internal bool TryReadSqlValue(SqlBuffer value, SqlMetaDataPriv md, int length, TdsParserStateObject stateObj)
{
bool isPlp = md.metaType.IsPlp;
byte tdsType = md.tdsType;
Debug.Assert(isPlp || !IsNull(md.metaType, (ulong)length), "null value should not get here!");
if (isPlp)
{
// We must read the column value completely, no matter what length is passed in
length = Int32.MaxValue;
}
switch (tdsType)
{
case TdsEnums.SQLDECIMALN:
case TdsEnums.SQLNUMERICN:
if (!TryReadSqlDecimal(value, length, md.precision, md.scale, stateObj))
{
return false;
}
break;
case TdsEnums.SQLUDT:
case TdsEnums.SQLBINARY:
case TdsEnums.SQLBIGBINARY:
case TdsEnums.SQLBIGVARBINARY:
case TdsEnums.SQLVARBINARY:
case TdsEnums.SQLIMAGE:
byte[] b = null;
// If varbinary(max), we only read the first chunk here, expecting the caller to read the rest
if (isPlp)
{
// If we are given -1 for length, then we read the entire value,
// otherwise only the requested amount, usually first chunk.
int ignored;
if (!stateObj.TryReadPlpBytes(ref b, 0, length, out ignored))
{
return false;
}
}
else
{
//Debug.Assert(length > 0 && length < (long)(Int32.MaxValue), "Bad length for column");
b = new byte[length];
if (!stateObj.TryReadByteArray(b, 0, length))
{
return false;
}
}
value.SqlBinary = SqlTypeWorkarounds.SqlBinaryCtor(b, true);
break;
case TdsEnums.SQLCHAR:
case TdsEnums.SQLBIGCHAR:
case TdsEnums.SQLVARCHAR:
case TdsEnums.SQLBIGVARCHAR:
case TdsEnums.SQLTEXT:
case TdsEnums.SQLNCHAR:
case TdsEnums.SQLNVARCHAR:
case TdsEnums.SQLNTEXT:
if (!TryReadSqlStringValue(value, tdsType, length, md.encoding, isPlp, stateObj))
{
return false;
}
break;
case TdsEnums.SQLXMLTYPE:
// We store SqlCachedBuffer here, so that we can return either SqlBinary, SqlString or SqlXmlReader.
SqlCachedBuffer sqlBuf;
if (!SqlCachedBuffer.TryCreate(md, this, stateObj, out sqlBuf))
{
return false;
}
value.SqlCachedBuffer = sqlBuf;
break;
case TdsEnums.SQLDATE:
case TdsEnums.SQLTIME:
case TdsEnums.SQLDATETIME2:
case TdsEnums.SQLDATETIMEOFFSET:
if (!TryReadSqlDateTime(value, tdsType, length, md.scale, stateObj))
{
return false;
}
break;
default:
Debug.Assert(!isPlp, "ReadSqlValue calling ReadSqlValueInternal with plp data");
if (!TryReadSqlValueInternal(value, tdsType, length, stateObj))
{
return false;
}
break;
}
Debug.Assert((stateObj._longlen == 0) && (stateObj._longlenleft == 0), "ReadSqlValue did not read plp field completely, longlen =" + stateObj._longlen.ToString((IFormatProvider)null) + ",longlenleft=" + stateObj._longlenleft.ToString((IFormatProvider)null));
return true;
}