static async ValueTask <string> ReadLong(NpgsqlReadBuffer buf, int byteLen, bool async) { if (byteLen <= buf.Size) { // The string's byte representation can fit in our read buffer, read it. while (buf.ReadBytesLeft < byteLen) { await buf.ReadMore(async); } return(buf.ReadString(byteLen)); } // Bad case: the string's byte representation doesn't fit in our buffer. // This is rare - will only happen in CommandBehavior.Sequential mode (otherwise the // entire row is in memory). Tweaking the buffer length via the connection string can // help avoid this. // Allocate a temporary byte buffer to hold the entire string and read it in chunks. var tempBuf = new byte[byteLen]; var pos = 0; while (true) { var len = Math.Min(buf.ReadBytesLeft, byteLen - pos); buf.ReadBytes(tempBuf, pos, len); pos += len; if (pos < byteLen) { await buf.ReadMore(async); continue; } break; } return(buf.TextEncoding.GetString(tempBuf)); }
/// <inheritdoc /> public override async ValueTask <byte[]> Read(NpgsqlReadBuffer buf, int len, bool async, FieldDescription fieldDescription = null) { var bytes = new byte[len]; var pos = 0; while (true) { var toRead = Math.Min(len - pos, buf.ReadBytesLeft); buf.ReadBytes(bytes, pos, toRead); pos += toRead; if (pos == len) { break; } await buf.ReadMore(async); } return(bytes); }