Skip to content

Commit

Permalink
Merge pull request dotnet/corefx#31044 from Wraith2/sqldatespan2
Browse files Browse the repository at this point in the history
Add datetime read span path for netcore

Commit migrated from dotnet/corefx@10ccbc1
  • Loading branch information
AfsanehR-zz committed Oct 4, 2018
2 parents 7a1ad01 + f99eb73 commit 3b8fae6
Show file tree
Hide file tree
Showing 5 changed files with 64 additions and 106 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -310,7 +310,6 @@
</ItemGroup>
<!-- Windows dependencies for Integrated Authentication for MANAGED_SNI build -->
<ItemGroup Condition=" '$(TargetsWindows)' == 'true' And '$(IsPartialFacadeAssembly)' != 'true' ">
<Reference Include="System.Memory" />
<Compile Include="$(CommonPath)\Interop\Windows\SChannel\Interop.SecPkgContext_ApplicationProtocol.cs">
<Link>Common\Interop\Windows\SChannel\Interop.SecPkgContext_ApplicationProtocol.cs</Link>
</Compile>
Expand Down Expand Up @@ -404,6 +403,7 @@
</ItemGroup>
<!-- Common (Windows and Unix) dependencies for MANAGED_SNI build -->
<ItemGroup Condition="'$(IsPartialFacadeAssembly)' != 'true' AND '$(OSGroup)' != 'AnyOS'">
<Reference Include="System.Memory" />
<Compile Include="$(CommonPath)\System\Net\ContextFlagsPal.cs">
<Link>Common\System\Net\ContextFlagsPal.cs</Link>
</Compile>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1027,90 +1027,47 @@ internal void SetToString(string value)
_isNull = false;
}

internal void SetToDate(byte[] bytes)
internal void SetToDate(ReadOnlySpan<byte> bytes)
{
Debug.Assert(IsEmpty, "setting value a second time?");

_type = StorageType.Date;
_value._int32 = GetDateFromByteArray(bytes, 0);
_value._int32 = GetDateFromByteArray(bytes);
_isNull = false;
}

internal void SetToDate(DateTime date)
internal void SetToTime(ReadOnlySpan<byte> bytes, byte scale)
{
Debug.Assert(IsEmpty, "setting value a second time?");

_type = StorageType.Date;
_value._int32 = date.Subtract(DateTime.MinValue).Days;
_isNull = false;
}

internal void SetToTime(byte[] bytes, int length, byte scale)
{
Debug.Assert(IsEmpty, "setting value a second time?");

_type = StorageType.Time;
FillInTimeInfo(ref _value._timeInfo, bytes, length, scale);
FillInTimeInfo(ref _value._timeInfo, bytes, scale);
_isNull = false;
}

internal void SetToTime(TimeSpan timeSpan, byte scale)
internal void SetToDateTime2(ReadOnlySpan<byte> bytes, byte scale)
{
Debug.Assert(IsEmpty, "setting value a second time?");

_type = StorageType.Time;
_value._timeInfo.ticks = timeSpan.Ticks;
_value._timeInfo.scale = scale;
_isNull = false;
}

internal void SetToDateTime2(byte[] bytes, int length, byte scale)
{
Debug.Assert(IsEmpty, "setting value a second time?");

int length = bytes.Length;
_type = StorageType.DateTime2;
FillInTimeInfo(ref _value._dateTime2Info.timeInfo, bytes, length - 3, scale); // remaining 3 bytes is for date
_value._dateTime2Info.date = GetDateFromByteArray(bytes, length - 3); // 3 bytes for date
FillInTimeInfo(ref _value._dateTime2Info.timeInfo, bytes.Slice(0, length - 3), scale); // remaining 3 bytes is for date
_value._dateTime2Info.date = GetDateFromByteArray(bytes.Slice(length - 3)); // 3 bytes for date
_isNull = false;
}

internal void SetToDateTime2(DateTime dateTime, byte scale)
internal void SetToDateTimeOffset(ReadOnlySpan<byte> bytes, byte scale)
{
Debug.Assert(IsEmpty, "setting value a second time?");

_type = StorageType.DateTime2;
_value._dateTime2Info.timeInfo.ticks = dateTime.TimeOfDay.Ticks;
_value._dateTime2Info.timeInfo.scale = scale;
_value._dateTime2Info.date = dateTime.Subtract(DateTime.MinValue).Days;
_isNull = false;
}

internal void SetToDateTimeOffset(byte[] bytes, int length, byte scale)
{
Debug.Assert(IsEmpty, "setting value a second time?");

int length = bytes.Length;
_type = StorageType.DateTimeOffset;
FillInTimeInfo(ref _value._dateTimeOffsetInfo.dateTime2Info.timeInfo, bytes, length - 5, scale); // remaining 5 bytes are for date and offset
_value._dateTimeOffsetInfo.dateTime2Info.date = GetDateFromByteArray(bytes, length - 5); // 3 bytes for date
FillInTimeInfo(ref _value._dateTimeOffsetInfo.dateTime2Info.timeInfo, bytes.Slice(0, length - 5), scale); // remaining 5 bytes are for date and offset
_value._dateTimeOffsetInfo.dateTime2Info.date = GetDateFromByteArray(bytes.Slice(length - 5)); // 3 bytes for date
_value._dateTimeOffsetInfo.offset = (short)(bytes[length - 2] + (bytes[length - 1] << 8)); // 2 bytes for offset (Int16)
_isNull = false;
}

internal void SetToDateTimeOffset(DateTimeOffset dateTimeOffset, byte scale)
{
Debug.Assert(IsEmpty, "setting value a second time?");

_type = StorageType.DateTimeOffset;
DateTime utcDateTime = dateTimeOffset.UtcDateTime; // timeInfo stores the utc datetime of a datatimeoffset
_value._dateTimeOffsetInfo.dateTime2Info.timeInfo.ticks = utcDateTime.TimeOfDay.Ticks;
_value._dateTimeOffsetInfo.dateTime2Info.timeInfo.scale = scale;
_value._dateTimeOffsetInfo.dateTime2Info.date = utcDateTime.Subtract(DateTime.MinValue).Days;
_value._dateTimeOffsetInfo.offset = (short)dateTimeOffset.Offset.TotalMinutes;
_isNull = false;
}

private static void FillInTimeInfo(ref TimeInfo timeInfo, byte[] timeBytes, int length, byte scale)
private static void FillInTimeInfo(ref TimeInfo timeInfo, ReadOnlySpan<byte> timeBytes, byte scale)
{
int length = timeBytes.Length;
Debug.Assert(3 <= length && length <= 5, "invalid data length for timeInfo: " + length);
Debug.Assert(0 <= scale && scale <= 7, "invalid scale: " + scale);

Expand All @@ -1127,9 +1084,10 @@ private static void FillInTimeInfo(ref TimeInfo timeInfo, byte[] timeBytes, int
timeInfo.scale = scale;
}

private static int GetDateFromByteArray(byte[] buf, int offset)
private static int GetDateFromByteArray(ReadOnlySpan<byte> buf)
{
return buf[offset] + (buf[offset + 1] << 8) + (buf[offset + 2] << 16);
byte thirdByte = buf[2]; // reordered to optimize JIT generated bounds checks to a single instance, review generated asm before changing
return buf[0] + (buf[1] << 8) + (thirdByte << 16);
}

private void ThrowIfNull()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1782,7 +1782,7 @@ internal bool TryGetBytesInternalSequential(int i, byte[] buffer, int index, int
{
// Read data (not exceeding the total amount of data available)
int bytesToRead = (int)Math.Min((long)length, _sharedState._columnDataBytesRemaining);
bool result = _stateObj.TryReadByteArray(buffer, index, bytesToRead, out bytesRead);
bool result = _stateObj.TryReadByteArray(buffer.AsSpan(index), bytesToRead, out bytesRead);
_columnDataBytesRead += bytesRead;
_sharedState._columnDataBytesRemaining -= bytesRead;
return result;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -684,7 +684,7 @@ private PreLoginHandshakeStatus ConsumePreLoginHandshake(bool encrypt, bool trus
byte[] payload = new byte[_physicalStateObj._inBytesPacket];

Debug.Assert(_physicalStateObj._syncOverAsync, "Should not attempt pends in a synchronous call");
result = _physicalStateObj.TryReadByteArray(payload, 0, payload.Length);
result = _physicalStateObj.TryReadByteArray(payload, payload.Length);
if (!result) { throw SQL.SynchronousCallMayNotPend(); }

if (payload[0] == 0xaa)
Expand Down Expand Up @@ -2384,7 +2384,7 @@ private bool TryProcessEnvChange(int tokenLength, TdsParserStateObject stateObj,
return false;
}
env.newBinValue = new byte[env.newLength];
if (!stateObj.TryReadByteArray(env.newBinValue, 0, env.newLength))
if (!stateObj.TryReadByteArray(env.newBinValue, env.newLength))
{ // read new value with 4 byte length
return false;
}
Expand Down Expand Up @@ -2476,7 +2476,7 @@ private bool TryReadTwoBinaryFields(SqlEnvChange env, TdsParserStateObject state
}
env.newLength = byteLength;
env.newBinValue = new byte[env.newLength];
if (!stateObj.TryReadByteArray(env.newBinValue, 0, env.newLength))
if (!stateObj.TryReadByteArray(env.newBinValue, env.newLength))
{
return false;
}
Expand All @@ -2486,7 +2486,7 @@ private bool TryReadTwoBinaryFields(SqlEnvChange env, TdsParserStateObject state
}
env.oldLength = byteLength;
env.oldBinValue = new byte[env.oldLength];
if (!stateObj.TryReadByteArray(env.oldBinValue, 0, env.oldLength))
if (!stateObj.TryReadByteArray(env.oldBinValue, env.oldLength))
{
return false;
}
Expand Down Expand Up @@ -2739,7 +2739,7 @@ private bool TryProcessFeatureExtAck(TdsParserStateObject stateObj)
byte[] data = new byte[dataLen];
if (dataLen > 0)
{
if (!stateObj.TryReadByteArray(data, 0, checked((int)dataLen)))
if (!stateObj.TryReadByteArray(data, checked((int)dataLen)))
{
return false;
}
Expand Down Expand Up @@ -2844,7 +2844,7 @@ private bool TryProcessSessionState(TdsParserStateObject stateObj, int length, S
}
if (buffer != null)
{
if (!stateObj.TryReadByteArray(buffer, 0, stateLen))
if (!stateObj.TryReadByteArray(buffer, stateLen))
{
return false;
}
Expand Down Expand Up @@ -2882,7 +2882,7 @@ private bool TryProcessLoginAck(TdsParserStateObject stateObj, out SqlLoginAck s
}

byte[] b = new byte[TdsEnums.VERSION_SIZE];
if (!stateObj.TryReadByteArray(b, 0, b.Length))
if (!stateObj.TryReadByteArray(b, b.Length))
{
return false;
}
Expand Down Expand Up @@ -4505,7 +4505,7 @@ internal bool TryReadSqlValue(SqlBuffer value, SqlMetaDataPriv md, int length, T
{
//Debug.Assert(length > 0 && length < (long)(Int32.MaxValue), "Bad length for column");
b = new byte[length];
if (!stateObj.TryReadByteArray(b, 0, length))
if (!stateObj.TryReadByteArray(b, length))
{
return false;
}
Expand Down Expand Up @@ -4565,33 +4565,33 @@ internal bool TryReadSqlValue(SqlBuffer value, SqlMetaDataPriv md, int length, T

private bool TryReadSqlDateTime(SqlBuffer value, byte tdsType, int length, byte scale, TdsParserStateObject stateObj)
{
byte[] datetimeBuffer = new byte[length];
Span<byte> datetimeBuffer = ((uint)length <= 16) ? stackalloc byte[16] : new byte[length];

if (!stateObj.TryReadByteArray(datetimeBuffer, 0, length))
if (!stateObj.TryReadByteArray(datetimeBuffer, length))
{
return false;
}

ReadOnlySpan<byte> dateTimeData = datetimeBuffer.Slice(0, length);
switch (tdsType)
{
case TdsEnums.SQLDATE:
Debug.Assert(length == 3, "invalid length for date type!");
value.SetToDate(datetimeBuffer);
value.SetToDate(dateTimeData);
break;

case TdsEnums.SQLTIME:
Debug.Assert(3 <= length && length <= 5, "invalid length for time type!");
value.SetToTime(datetimeBuffer, length, scale);
value.SetToTime(dateTimeData, scale);
break;

case TdsEnums.SQLDATETIME2:
Debug.Assert(6 <= length && length <= 8, "invalid length for datetime2 type!");
value.SetToDateTime2(datetimeBuffer, length, scale);
value.SetToDateTime2(dateTimeData, scale);
break;

case TdsEnums.SQLDATETIMEOFFSET:
Debug.Assert(8 <= length && length <= 10, "invalid length for datetimeoffset type!");
value.SetToDateTimeOffset(datetimeBuffer, length, scale);
value.SetToDateTimeOffset(dateTimeData, scale);
break;

default:
Expand Down Expand Up @@ -4785,7 +4785,7 @@ internal bool TryReadSqlValueInternal(SqlBuffer value, byte tdsType, int length,

byte[] b = new byte[length];

if (!stateObj.TryReadByteArray(b, 0, length))
if (!stateObj.TryReadByteArray(b, length))
{
return false;
}
Expand All @@ -4802,7 +4802,7 @@ internal bool TryReadSqlValueInternal(SqlBuffer value, byte tdsType, int length,
// Note: Better not come here with plp data!!
Debug.Assert(length <= TdsEnums.MAXSIZE);
byte[] b = new byte[length];
if (!stateObj.TryReadByteArray(b, 0, length))
if (!stateObj.TryReadByteArray(b, length))
{
return false;
}
Expand Down Expand Up @@ -6565,7 +6565,7 @@ private void ProcessSSPI(int receivedLength)

// read SSPI data received from server
Debug.Assert(_physicalStateObj._syncOverAsync, "Should not attempt pends in a synchronous call");
bool result = _physicalStateObj.TryReadByteArray(receivedBuff, 0, receivedLength);
bool result = _physicalStateObj.TryReadByteArray(receivedBuff, receivedLength);
if (!result) { throw SQL.SynchronousCallMayNotPend(); }

// allocate send buffer and initialize length
Expand Down
Loading

0 comments on commit 3b8fae6

Please sign in to comment.