internal int ReadPlpAnsiChars(ref char[] buff, int offst, int len, SqlMetaDataPriv metadata, TdsParserStateObject stateObj)
{
int charsRead = 0;
int charsLeft = 0;
int bytesRead = 0;
int totalcharsRead = 0;
if (stateObj._longlen == 0)
{
Debug.Assert(stateObj._longlenleft == 0);
return 0; // No data
}
Debug.Assert(((ulong)stateObj._longlen != TdsEnums.SQL_PLP_NULL),
"Out of sync plp read request");
Debug.Assert((buff == null && offst == 0) || (buff.Length >= offst + len), "Invalid length sent to ReadPlpAnsiChars()!");
charsLeft = len;
if (stateObj._longlenleft == 0)
{
stateObj.ReadPlpLength(false);
if (stateObj._longlenleft == 0)
{// Data read complete
stateObj._plpdecoder = null;
return 0;
}
}
if (stateObj._plpdecoder == null)
{
Encoding enc = metadata.encoding;
if (enc == null)
{
if (null == _defaultEncoding)
{
ThrowUnsupportedCollationEncountered(stateObj);
}
enc = _defaultEncoding;
}
stateObj._plpdecoder = enc.GetDecoder();
}
while (charsLeft > 0)
{
bytesRead = (int)Math.Min(stateObj._longlenleft, (ulong)charsLeft);
if ((stateObj._bTmp == null) || (stateObj._bTmp.Length < bytesRead))
{
// Grow the array
stateObj._bTmp = new byte[bytesRead];
}
bytesRead = stateObj.ReadPlpBytesChunk(stateObj._bTmp, 0, bytesRead);
charsRead = stateObj._plpdecoder.GetChars(stateObj._bTmp, 0, bytesRead, buff, offst);
charsLeft -= charsRead;
offst += charsRead;
totalcharsRead += charsRead;
if (stateObj._longlenleft == 0) // Read the next chunk or cleanup state if hit the end
stateObj.ReadPlpLength(false);
if (stateObj._longlenleft == 0)
{ // Data read complete
stateObj._plpdecoder = null;
break;
}
}
return (totalcharsRead);
}