public long GetChars(DataRowMessage row, int charOffset, char[] output, int outputOffset, int charsCount, FieldDescription field) { if (row.PosInColumn == 0) { _charPos = 0; } if (output == null) { // Note: Getting the length of a text column means decoding the entire field, // very inefficient and also consumes the column in sequential mode. But this seems to // be SqlClient's behavior as well. int bytesSkipped, charsSkipped; row.Buffer.SkipChars(int.MaxValue, row.ColumnLen - row.PosInColumn, out bytesSkipped, out charsSkipped); Contract.Assume(bytesSkipped == row.ColumnLen - row.PosInColumn); row.PosInColumn += bytesSkipped; _charPos += charsSkipped; return(_charPos); } if (charOffset < _charPos) { row.SeekInColumn(0); _charPos = 0; } if (charOffset > _charPos) { var charsToSkip = charOffset - _charPos; int bytesSkipped, charsSkipped; row.Buffer.SkipChars(charsToSkip, row.ColumnLen - row.PosInColumn, out bytesSkipped, out charsSkipped); row.PosInColumn += bytesSkipped; _charPos += charsSkipped; if (charsSkipped < charsToSkip) { // TODO: What is the actual required behavior here? throw new IndexOutOfRangeException(); } } int bytesRead, charsRead; row.Buffer.ReadChars(output, outputOffset, charsCount, row.ColumnLen - row.PosInColumn, out bytesRead, out charsRead); row.PosInColumn += bytesRead; _charPos += charsRead; return(charsRead); }
public long GetBytes(DataRowMessage row, int offset, [CanBeNull] byte[] output, int outputOffset, int len, FieldDescription field) { if (output == null) { return(row.ColumnLen); } row.SeekInColumn(offset); // Attempt to read beyond the end of the column if (offset + len > row.ColumnLen) { len = row.ColumnLen - offset; } row.Buffer.ReadAllBytes(output, outputOffset, len, false); row.PosInColumn += len; return(len); }