private int ReadBytes(byte[] buffer, int offset, int count)
{
bool gotData = true;
int intCount = 0;
int cb = 0;
if (_reader.IsClosed || _endOfColumn)
{
return 0;
}
try
{
while (count > 0)
{
// if no bytes were read, get the next row
if (_advanceReader && (0 == _bytesCol))
{
gotData = false;
if (_readFirstRow && !_processAllRows)
{
// for XML column, stop processing after the first row
// no op here - reader is closed after the end of this loop
}
else if (AdvanceToNextRow(_reader))
{
_readFirstRow = true;
if (_reader.IsDBNull(_columnOrdinal))
{
// Handle row with DBNULL as empty data
// for XML column, processing is stopped on the next loop since _readFirstRow is true
continue;
}
// the value is not null, read it
gotData = true;
}
// else AdvanceToNextRow has returned false - no more rows or result sets remained, stop processing
}
if (gotData)
{
cb = (int)_reader.GetBytesInternal(_columnOrdinal, _bytesCol, buffer, offset, count);
if (cb < count)
{
_bytesCol = 0;
gotData = false;
if (!_advanceReader)
{
_endOfColumn = true;
}
}
else
{
Debug.Assert(cb == count);
_bytesCol += cb;
}
// we are guaranteed that cb is < Int32.Max since we always pass in count which is of type Int32 to
// our getbytes interface
count -= (int)cb;
offset += (int)cb;
intCount += (int)cb;
}
else
{
break; // no more data available, we are done
}
}
if (!gotData && _advanceReader)
{
_reader.Close(); // Need to close the reader if we are done reading
}
}
catch (Exception e)
{
if (_advanceReader && ADP.IsCatchableExceptionType(e))
{
_reader.Close();
}
throw;
}
return intCount;
}