From 2ad4391da28fe0d2cbffd00ad6053199232aed73 Mon Sep 17 00:00:00 2001 From: Wraith2 Date: Fri, 3 Feb 2023 23:27:09 +0000 Subject: [PATCH] move TryReadChars to shared and cleanup --- .../src/Microsoft/Data/SqlClient/TdsParser.cs | 3 -- .../Data/SqlClient/TdsParserStateObject.cs | 48 ------------------- .../src/Microsoft/Data/SqlClient/TdsParser.cs | 17 ++++--- .../Data/SqlClient/TdsParserStateObject.cs | 45 +++++++++++++++++ 4 files changed, 53 insertions(+), 60 deletions(-) diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParser.cs b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParser.cs index c2b1abaa51..49327a4cdd 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParser.cs +++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParser.cs @@ -10,8 +10,6 @@ using System.Diagnostics; using System.Globalization; using System.IO; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; using System.Security.Authentication; using System.Text; using System.Threading; @@ -12511,7 +12509,6 @@ private bool TryReadPlpUnicodeCharsChunk(char[] buff, int offst, int len, TdsPar charsToRead = (int)(stateObj._longlenleft >> 1); } - if (!stateObj.TryReadChars(buff, offst, charsToRead, out charsRead)) { charsRead = 0; diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParserStateObject.cs b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParserStateObject.cs index 814e8bc6df..bc7cd362a8 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParserStateObject.cs +++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParserStateObject.cs @@ -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; @@ -491,51 +488,6 @@ internal bool TryReadChar(out char value) 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 TryReadInt16(out short value) { Debug.Assert(_syncOverAsync || !_asyncReadWithoutSnapshot, "This method is not safe to call when doing sync over async"); diff --git a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/TdsParser.cs b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/TdsParser.cs index 70673ef343..a15da77757 100644 --- a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/TdsParser.cs +++ b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/TdsParser.cs @@ -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"); @@ -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); diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/TdsParserStateObject.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/TdsParserStateObject.cs index 86f51fba2a..62c02e4db7 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/TdsParserStateObject.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/TdsParserStateObject.cs @@ -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