Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -1352,7 +1352,7 @@ internal void SetToDateTime2(DateTime dateTime, byte scale)
}
#endif

internal void SetToDecimal(byte precision, byte scale, bool positive, int[] bits)
internal void SetToDecimal(byte precision, byte scale, bool positive, ReadOnlySpan<int> bits)
{
Debug.Assert(IsEmpty, "setting value a second time?");
_value._numericInfo._precision = precision;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2250,7 +2250,13 @@ private byte ValueScaleCore(object value)
{
if (value is decimal decimalValue)
{
return (byte)((decimal.GetBits(decimalValue)[3] & 0x00ff0000) >> 0x10);
#if NET
Span<int> decimalBits = stackalloc int[4];
decimal.GetBits(decimalValue, decimalBits);
#else
int[] decimalBits = decimal.GetBits(decimalValue);
#endif
return (byte)((decimalBits[3] & 0x00ff0000) >> 0x10);
}
return 0;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6782,7 +6782,7 @@ internal bool DeserializeUnencryptedValue(SqlBuffer value, byte[] unencryptedByt

// Now read the 4 next integers which contain the actual value.
length = checked((int)length - 1);
int[] bits = new int[4];
Span<int> bits = stackalloc int[4];
int decLength = length >> 2;
ReadOnlySpan<byte> span = unencryptedBytes.AsSpan();
for (int i = 0; i < decLength; i++)
Expand Down Expand Up @@ -7702,8 +7702,15 @@ internal Task WriteSqlVariantValue(object value, int length, int offset, TdsPars

case TdsEnums.SQLNUMERICN:
{
#if NET
Span<int> decimalBits = stackalloc int[4];
decimal.GetBits((decimal)value, decimalBits);
#else
int[] decimalBits = decimal.GetBits((decimal)value);
#endif

stateObj.WriteByte(mt.Precision); //propbytes: precision
stateObj.WriteByte((byte)((decimal.GetBits((decimal)value)[3] & 0x00ff0000) >> 0x10)); // propbytes: scale
stateObj.WriteByte((byte)((decimalBits[3] & 0x00ff0000) >> 0x10)); // propbytes: scale
WriteDecimal((decimal)value, stateObj);
break;
}
Expand Down Expand Up @@ -7864,9 +7871,15 @@ internal Task WriteSqlVariantDataRowValue(object value, TdsParserStateObject sta

case TdsEnums.SQLNUMERICN:
{
#if NET
Span<int> decimalBits = stackalloc int[4];
decimal.GetBits((decimal)value, decimalBits);
#else
int[] decimalBits = decimal.GetBits((decimal)value);
#endif
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
stateObj.WriteByte((byte)((decimalBits[3] & 0x00ff0000) >> 0x10)); // propbytes: scale
WriteDecimal((decimal)value, stateObj);
break;
}
Expand Down Expand Up @@ -7923,7 +7936,12 @@ private byte[] SerializeSqlMoney(SqlMoney value, int length, TdsParserStateObjec
private void WriteSqlMoney(SqlMoney value, int length, TdsParserStateObject stateObj)
{
// UNDONE: can I use SqlMoney.ToInt64()?
#if NET
Span<int> bits = stackalloc int[4];
decimal.GetBits(value.Value, bits);
#else
int[] bits = decimal.GetBits(value.Value);
#endif

// this decimal should be scaled by 10000 (regardless of what the incoming decimal was scaled by)
bool isNeg = (0 != (bits[3] & unchecked((int)0x80000000)));
Expand Down Expand Up @@ -7956,7 +7974,12 @@ private void WriteSqlMoney(SqlMoney value, int length, TdsParserStateObject stat
private byte[] SerializeCurrency(Decimal value, int length, TdsParserStateObject stateObj)
{
SqlMoney m = new SqlMoney(value);
int[] bits = Decimal.GetBits(m.Value);
#if NET
Span<int> bits = stackalloc int[4];
decimal.GetBits(m.Value, bits);
#else
int[] bits = decimal.GetBits(m.Value);
#endif

// this decimal should be scaled by 10000 (regardless of what the incoming decimal was scaled by)
bool isNeg = (0 != (bits[3] & unchecked((int)0x80000000)));
Expand Down Expand Up @@ -8001,7 +8024,12 @@ private byte[] SerializeCurrency(Decimal value, int length, TdsParserStateObject
private void WriteCurrency(decimal value, int length, TdsParserStateObject stateObj)
{
SqlMoney m = new SqlMoney(value);
#if NET
Span<int> bits = stackalloc int[4];
decimal.GetBits(m.Value, bits);
#else
int[] bits = decimal.GetBits(m.Value);
#endif

// this decimal should be scaled by 10000 (regardless of what the incoming decimal was scaled by)
bool isNeg = (0 != (bits[3] & unchecked((int)0x80000000)));
Expand Down Expand Up @@ -8138,8 +8166,8 @@ private TdsOperationStatus TryReadSqlDecimal(SqlBuffer value, int length, byte p

length = checked((int)length - 1);

int[] bits;
result = TryReadDecimalBits(length, stateObj, out bits);
Span<int> bits = stackalloc int[4];
result = TryReadDecimalBits(length, stateObj, bits);
if (result != TdsOperationStatus.Done)
{
return result;
Expand All @@ -8151,31 +8179,16 @@ private TdsOperationStatus TryReadSqlDecimal(SqlBuffer value, int length, byte p

// @devnote: length should be size of decimal without the sign
// @devnote: sign should have already been read off the wire
private TdsOperationStatus TryReadDecimalBits(int length, TdsParserStateObject stateObj, out int[] bits)
private TdsOperationStatus TryReadDecimalBits(int length, TdsParserStateObject stateObj, Span<int> bits)
{
bits = stateObj._decimalBits; // used alloc'd array if we have one already
int i;

if (bits == null)
{
bits = new int[4];
stateObj._decimalBits = bits;
}
else
{
for (i = 0; i < bits.Length; i++)
{
bits[i] = 0;
}
}

Debug.Assert(bits.Length == 4);
Debug.Assert((length > 0) &&
(length <= TdsEnums.MAX_NUMERIC_LEN - 1) &&
(length % 4 == 0), "decimal should have 4, 8, 12, or 16 bytes of data");

int decLength = length >> 2;

for (i = 0; i < decLength; i++)
for (int i = 0; i < decLength; i++)
{
// up to 16 bytes of data following the sign byte
TdsOperationStatus result = stateObj.TryReadInt32(out bits[i]);
Expand All @@ -8201,7 +8214,13 @@ internal static SqlDecimal AdjustSqlDecimalScale(SqlDecimal d, int newScale)

internal static decimal AdjustDecimalScale(decimal value, int newScale)
{
int oldScale = (decimal.GetBits(value)[3] & 0x00ff0000) >> 0x10;
#if NET
Span<int> decimalBits = stackalloc int[4];
decimal.GetBits(value, decimalBits);
#else
int[] decimalBits = decimal.GetBits(value);
#endif
int oldScale = (decimalBits[3] & 0x00ff0000) >> 0x10;

if (newScale != oldScale)
{
Expand Down Expand Up @@ -8283,7 +8302,12 @@ internal void WriteSqlDecimal(SqlDecimal d, TdsParserStateObject stateObj)

private byte[] SerializeDecimal(decimal value, TdsParserStateObject stateObj)
{
int[] decimalBits = Decimal.GetBits(value);
#if NET
Span<int> decimalBits = stackalloc int[4];
decimal.GetBits(value, decimalBits);
#else
int[] decimalBits = decimal.GetBits(value);
#endif
if (stateObj._bDecimalBytes == null)
{
stateObj._bDecimalBytes = new byte[17];
Expand Down Expand Up @@ -8338,8 +8362,12 @@ struct {

private void WriteDecimal(decimal value, TdsParserStateObject stateObj)
{
stateObj._decimalBits = decimal.GetBits(value);
Debug.Assert(stateObj._decimalBits != null, "decimalBits should be filled in at TdsExecuteRPC time");
#if NET
Span<int> decimalBits = stackalloc int[4];
decimal.GetBits(value, decimalBits);
#else
int[] decimalBits = decimal.GetBits(value);
#endif

/*
Returns a binary representation of a Decimal. The return value is an integer
Expand All @@ -8361,7 +8389,7 @@ struct {
*/

// write the sign (note that COM and SQL are opposite)
if (0x80000000 == (stateObj._decimalBits[3] & 0x80000000))
if ((decimalBits[3] & 0x80000000) == 0x80000000)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would use stateObj._decimalBits here and below instead of decimalBits.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This would be valid in netfx, but not in netcore - we'll have written the decimal bits to decimalBits, but read values from stateObj._decimalBits.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, I was assuming we would revert to always setting _decimalBits per my comment above.

{
stateObj.WriteByte(0);
}
Expand All @@ -8370,9 +8398,9 @@ struct {
stateObj.WriteByte(1);
}

WriteInt(stateObj._decimalBits[0], stateObj);
WriteInt(stateObj._decimalBits[1], stateObj);
WriteInt(stateObj._decimalBits[2], stateObj);
WriteInt(decimalBits[0], stateObj);
WriteInt(decimalBits[1], stateObj);
WriteInt(decimalBits[2], stateObj);
WriteInt(0, stateObj);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -223,7 +223,6 @@ private enum SnapshotStatus
// TDS stream processing variables
internal ulong _longlen; // plp data length indicator
internal ulong _longlenleft; // Length of data left to read (64 bit lengths)
internal int[] _decimalBits; // scratch buffer for decimal/numeric data
internal byte[] _bTmp = new byte[TdsEnums.SQL2005_HEADER_LEN]; // Scratch buffer for misc use
internal int _bTmpRead; // Counter for number of temporary bytes read
internal Decoder _plpdecoder; // Decoder object to process plp character data
Expand Down
Loading