private bool TryProcessSessionState(TdsParserStateObject stateObj, int length, SessionData sdata)
{
if (length < 5)
{
throw SQL.ParsingError();
}
UInt32 seqNum;
if (!stateObj.TryReadUInt32(out seqNum))
{
return false;
}
if (seqNum == UInt32.MaxValue)
{
_connHandler.DoNotPoolThisConnection();
}
byte status;
if (!stateObj.TryReadByte(out status))
{
return false;
}
if (status > 1)
{
throw SQL.ParsingError();
}
bool recoverable = status != 0;
length -= 5;
while (length > 0)
{
byte stateId;
if (!stateObj.TryReadByte(out stateId))
{
return false;
}
int stateLen;
byte stateLenByte;
if (!stateObj.TryReadByte(out stateLenByte))
{
return false;
}
if (stateLenByte < 0xFF)
{
stateLen = stateLenByte;
}
else
{
if (!stateObj.TryReadInt32(out stateLen))
{
return false;
}
}
byte[] buffer = null;
lock (sdata._delta)
{
if (sdata._delta[stateId] == null)
{
buffer = new byte[stateLen];
sdata._delta[stateId] = new SessionStateRecord { _version = seqNum, _dataLength = stateLen, _data = buffer, _recoverable = recoverable };
sdata._deltaDirty = true;
if (!recoverable)
{
checked { sdata._unrecoverableStatesCount++; }
}
}
else
{
if (sdata._delta[stateId]._version <= seqNum)
{
SessionStateRecord sv = sdata._delta[stateId];
sv._version = seqNum;
sv._dataLength = stateLen;
if (sv._recoverable != recoverable)
{
if (recoverable)
{
Debug.Assert(sdata._unrecoverableStatesCount > 0, "Unrecoverable states count >0");
sdata._unrecoverableStatesCount--;
}
else
{
checked { sdata._unrecoverableStatesCount++; }
}
sv._recoverable = recoverable;
}
buffer = sv._data;
if (buffer.Length < stateLen)
{
buffer = new byte[stateLen];
sv._data = buffer;
}
}
}
}
if (buffer != null)
{
if (!stateObj.TryReadByteArray(buffer, 0, stateLen))
{
return false;
}
}
else
{
if (!stateObj.TrySkipBytes(stateLen))
return false;
}
if (stateLenByte < 0xFF)
{
length -= 2 + stateLen;
}
else
{
length -= 6 + stateLen;
}
}
sdata.AssertUnrecoverableStateCountIsCorrect();
return true;
}