internal Task WriteSqlVariantDataRowValue(object value, TdsParserStateObject stateObj, bool canAccumulate = true)
{
// handle null values
if ((null == value) || (DBNull.Value == value))
{
WriteInt(TdsEnums.FIXEDNULL, stateObj);
return null;
}
MetaType metatype = MetaType.GetMetaTypeFromValue(value);
int length = 0;
if (metatype.IsAnsiType)
{
length = GetEncodingCharLength((string)value, length, 0, _defaultEncoding);
}
switch (metatype.TDSType)
{
case TdsEnums.SQLFLT4:
WriteSqlVariantHeader(6, metatype.TDSType, metatype.PropBytes, stateObj);
WriteFloat((float)value, stateObj);
break;
case TdsEnums.SQLFLT8:
WriteSqlVariantHeader(10, metatype.TDSType, metatype.PropBytes, stateObj);
WriteDouble((double)value, stateObj);
break;
case TdsEnums.SQLINT8:
WriteSqlVariantHeader(10, metatype.TDSType, metatype.PropBytes, stateObj);
WriteLong((long)value, stateObj);
break;
case TdsEnums.SQLINT4:
WriteSqlVariantHeader(6, metatype.TDSType, metatype.PropBytes, stateObj);
WriteInt((int)value, stateObj);
break;
case TdsEnums.SQLINT2:
WriteSqlVariantHeader(4, metatype.TDSType, metatype.PropBytes, stateObj);
WriteShort((short)value, stateObj);
break;
case TdsEnums.SQLINT1:
WriteSqlVariantHeader(3, metatype.TDSType, metatype.PropBytes, stateObj);
stateObj.WriteByte((byte)value);
break;
case TdsEnums.SQLBIT:
WriteSqlVariantHeader(3, metatype.TDSType, metatype.PropBytes, stateObj);
if ((bool)value == true)
stateObj.WriteByte(1);
else
stateObj.WriteByte(0);
break;
case TdsEnums.SQLBIGVARBINARY:
{
byte[] b = (byte[])value;
length = b.Length;
WriteSqlVariantHeader(4 + length, metatype.TDSType, metatype.PropBytes, stateObj);
WriteShort(length, stateObj); // propbytes: varlen
return stateObj.WriteByteArray(b, length, 0, canAccumulate);
}
case TdsEnums.SQLBIGVARCHAR:
{
string s = (string)value;
length = s.Length;
WriteSqlVariantHeader(9 + length, metatype.TDSType, metatype.PropBytes, stateObj);
WriteUnsignedInt(_defaultCollation.info, stateObj); // propbytes: collation.Info
stateObj.WriteByte(_defaultCollation.sortId); // propbytes: collation.SortId
WriteShort(length, stateObj);
return WriteEncodingChar(s, _defaultEncoding, stateObj, canAccumulate);
}
case TdsEnums.SQLUNIQUEID:
{
System.Guid guid = (System.Guid)value;
byte[] b = guid.ToByteArray();
length = b.Length;
Debug.Assert(length == 16, "Invalid length for guid type in com+ object");
WriteSqlVariantHeader(18, metatype.TDSType, metatype.PropBytes, stateObj);
stateObj.WriteByteArray(b, length, 0);
break;
}
case TdsEnums.SQLNVARCHAR:
{
string s = (string)value;
length = s.Length * 2;
WriteSqlVariantHeader(9 + length, metatype.TDSType, metatype.PropBytes, stateObj);
WriteUnsignedInt(_defaultCollation.info, stateObj); // propbytes: collation.Info
stateObj.WriteByte(_defaultCollation.sortId); // propbytes: collation.SortId
WriteShort(length, stateObj); // propbyte: varlen
// string takes cchar, not cbyte so convert
length >>= 1;
return WriteString(s, length, 0, stateObj, canAccumulate);
}
case TdsEnums.SQLDATETIME:
{
TdsDateTime dt = MetaType.FromDateTime((DateTime)value, 8);
WriteSqlVariantHeader(10, metatype.TDSType, metatype.PropBytes, stateObj);
WriteInt(dt.days, stateObj);
WriteInt(dt.time, stateObj);
break;
}
case TdsEnums.SQLMONEY:
{
WriteSqlVariantHeader(10, metatype.TDSType, metatype.PropBytes, stateObj);
WriteCurrency((Decimal)value, 8, stateObj);
break;
}
case TdsEnums.SQLNUMERICN:
{
WriteSqlVariantHeader(21, metatype.TDSType, metatype.PropBytes, stateObj);
stateObj.WriteByte(metatype.Precision); //propbytes: precision
stateObj.WriteByte((byte)((Decimal.GetBits((Decimal)value)[3] & 0x00ff0000) >> 0x10)); // propbytes: scale
WriteDecimal((Decimal)value, stateObj);
break;
}
case TdsEnums.SQLTIME:
WriteSqlVariantHeader(8, metatype.TDSType, metatype.PropBytes, stateObj);
stateObj.WriteByte(metatype.Scale); //propbytes: scale
WriteTime((TimeSpan)value, metatype.Scale, 5, stateObj);
break;
case TdsEnums.SQLDATETIMEOFFSET:
WriteSqlVariantHeader(13, metatype.TDSType, metatype.PropBytes, stateObj);
stateObj.WriteByte(metatype.Scale); //propbytes: scale
WriteDateTimeOffset((DateTimeOffset)value, metatype.Scale, 10, stateObj);
break;
default:
Debug.Assert(false, "unknown tds type for sqlvariant!");
break;
} // switch
// return point for accumulated writes, note: non-accumulated writes returned from their case statements
return null;
}