Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add and use TryReadChars method #1544

Merged
merged 5 commits into from
Feb 10, 2023
Merged
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 @@ -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)
David-Engel marked this conversation as resolved.
Show resolved Hide resolved
{
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