internal bool TryProcessError(byte token, TdsParserStateObject stateObj, out SqlError error)
{
ushort shortLen;
byte byteLen;
int number;
byte state;
byte errorClass;
error = null;
if (!stateObj.TryReadInt32(out number))
{
return false;
}
if (!stateObj.TryReadByte(out state))
{
return false;
}
if (!stateObj.TryReadByte(out errorClass))
{
return false;
}
Debug.Assert(((errorClass >= TdsEnums.MIN_ERROR_CLASS) && token == TdsEnums.SQLERROR) ||
((errorClass < TdsEnums.MIN_ERROR_CLASS) && token == TdsEnums.SQLINFO), "class and token don't match!");
if (!stateObj.TryReadUInt16(out shortLen))
{
return false;
}
string message;
if (!stateObj.TryReadString(shortLen, out message))
{
return false;
}
if (!stateObj.TryReadByte(out byteLen))
{
return false;
}
string server;
// If the server field is not received use the locally cached value.
if (byteLen == 0)
{
server = _server;
}
else
{
if (!stateObj.TryReadString(byteLen, out server))
{
return false;
}
}
if (!stateObj.TryReadByte(out byteLen))
{
return false;
}
string procedure;
if (!stateObj.TryReadString(byteLen, out procedure))
{
return false;
}
int line;
if (_isYukon)
{
if (!stateObj.TryReadInt32(out line))
{
return false;
}
}
else
{
ushort shortLine;
if (!stateObj.TryReadUInt16(out shortLine))
{
return false;
}
line = shortLine;
// If we haven't yet completed processing login token stream yet, we may be talking to a Yukon server
// In that case we still have to read another 2 bytes
if (_state == TdsParserState.OpenNotLoggedIn)
{
// Login incomplete
byte b;
if (!stateObj.TryPeekByte(out b))
{
return false;
}
if (b == 0)
{
// This is an invalid token value
ushort value;
if (!stateObj.TryReadUInt16(out value))
{
return false;
}
line = (line << 16) + value;
}
}
}
error = new SqlError(number, state, errorClass, _server, message, procedure, line);
return true;
}