Skip to content

Commit

Permalink
Add and use TryReadChars method (#1544)
Browse files Browse the repository at this point in the history
  • Loading branch information
Wraith2 authored Feb 10, 2023
1 parent 5ff68eb commit 6db45d4
Show file tree
Hide file tree
Showing 4 changed files with 62 additions and 20 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -12501,18 +12501,18 @@ private bool TryReadPlpUnicodeCharsChunk(char[] buff, int offst, int len, TdsPar
return true;
}

charsRead = len;
int charsToRead = len;

// stateObj._longlenleft is in bytes
if ((stateObj._longlenleft >> 1) < (ulong)len)
charsRead = (int)(stateObj._longlenleft >> 1);
if ((stateObj._longlenleft / 2) < (ulong)len)
{
charsToRead = (int)(stateObj._longlenleft >> 1);
}

for (int ii = 0; ii < charsRead; ii++)
if (!stateObj.TryReadChars(buff, offst, charsToRead, out charsRead))
{
if (!stateObj.TryReadChar(out buff[offst + ii]))
{
return false;
}
charsRead = 0;
return false;
}

stateObj._longlenleft -= ((ulong)charsRead << 1);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,9 @@
// See the LICENSE file in the project root for more information.

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Runtime.InteropServices;
using System.Security;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Data.Common;
Expand Down Expand Up @@ -487,6 +484,7 @@ internal bool TryReadChar(out char value)

AssertValidState();
value = (char)((buffer[1] << 8) + buffer[0]);

return true;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13528,7 +13528,6 @@ internal void WriteParameterVarLen(MetaType type, int size, bool isNull, TdsPars
// Returns the actual chars read
private bool TryReadPlpUnicodeCharsChunk(char[] buff, int offst, int len, TdsParserStateObject stateObj, out int charsRead)
{

Debug.Assert((buff == null && len == 0) || (buff.Length >= offst + len), "Invalid length sent to ReadPlpUnicodeChars()!");
Debug.Assert((stateObj._longlen != 0) && (stateObj._longlen != TdsEnums.SQL_PLP_NULL),
"Out of sync plp read request");
Expand All @@ -13539,18 +13538,18 @@ private bool TryReadPlpUnicodeCharsChunk(char[] buff, int offst, int len, TdsPar
return true;
}

charsRead = len;
int charsToRead = len;

// stateObj._longlenleft is in bytes
if ((stateObj._longlenleft >> 1) < (ulong)len)
charsRead = (int)(stateObj._longlenleft >> 1);
if ((stateObj._longlenleft / 2) < (ulong)len)
{
charsToRead = (int)(stateObj._longlenleft >> 1);
}

for (int ii = 0; ii < charsRead; ii++)
if (!stateObj.TryReadChars(buff, offst, charsToRead, out charsRead))
{
if (!stateObj.TryReadChar(out buff[offst + ii]))
{
return false;
}
charsRead = 0;
return false;
}

stateObj._longlenleft -= ((ulong)charsRead << 1);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -436,6 +436,51 @@ internal bool TryStartNewRow(bool isNullCompressed, int nullBitmapColumnsCount =
return true;
}

internal bool TryReadChars(char[] chars, int charsOffset, int charsCount, out int charsCopied)
{
charsCopied = 0;
while (charsCopied < charsCount)
{
// check if the current buffer contains some bytes we need to copy and copy them
// in a block
int bytesToRead = Math.Min(
(charsCount - charsCopied) * 2,
unchecked((_inBytesRead - _inBytesUsed) & (int)0xFFFFFFFE) // it the result is odd take off the 0 to make it even
);
if (bytesToRead > 0)
{
Buffer.BlockCopy(
_inBuff,
_inBytesUsed,
chars,
(charsOffset + charsCopied) * 2, // offset in bytes,
bytesToRead
);
charsCopied += (bytesToRead / 2);
_inBytesUsed += bytesToRead;
_inBytesPacket -= bytesToRead;
}

// if the number of chars requested is lower than the number copied then we need
// to request a new packet, use TryReadChar() to do this then loop back to see
// if we can copy another bulk of chars from the new buffer

if (charsCopied < charsCount)
{
bool result = TryReadChar(out chars[charsOffset + charsCopied]);
if (result)
{
charsCopied += 1;
}
else
{
return false;
}
}
}
return true;
}

internal bool IsRowTokenReady()
{
// Removing one byte since TryReadByteArray\TryReadByte will aggressively read the next packet if there is no data left - so we need to ensure there is a spare byte
Expand Down

0 comments on commit 6db45d4

Please sign in to comment.