public override async ValueTask <NpgsqlPath> Read(NpgsqlReadBuffer buf, int len, bool async, FieldDescription fieldDescription = null) { await buf.Ensure(5, async); bool open; var openByte = buf.ReadByte(); switch (openByte) { case 1: open = false; break; case 0: open = true; break; default: throw new Exception("Error decoding binary geometric path: bad open byte"); } var numPoints = buf.ReadInt32(); var result = new NpgsqlPath(numPoints, open); for (var i = 0; i < numPoints; i++) { await buf.Ensure(16, async); result.Add(new NpgsqlPoint(buf.ReadDouble(), buf.ReadDouble())); } return(result); }
public override async ValueTask <object> Read(NpgsqlReadBuffer buf, int len, bool async, FieldDescription fieldDescription = null) { if (_members == null) { ResolveFields(); } Debug.Assert(_members != null); await buf.Ensure(4, async); var fieldCount = buf.ReadInt32(); if (fieldCount != _members.Count) // PostgreSQL sanity check { throw new Exception($"pg_attributes contains {_members.Count} rows for type {PgDisplayName}, but {fieldCount} fields were received!"); } var result = (IDictionary <string, object>) new ExpandoObject(); foreach (var member in _members) { await buf.Ensure(8, async); buf.ReadInt32(); // read typeOID, not used var fieldLen = buf.ReadInt32(); if (fieldLen == -1) { // Null field, simply skip it and leave at default continue; } // TODO: We need name translation result[member.PgName] = await member.Handler.ReadAsObject(buf, fieldLen, async); } return(result); }
/// <inheritdoc /> public override async ValueTask <Dictionary <string, string?> > Read(NpgsqlReadBuffer buf, int len, bool async, FieldDescription?fieldDescription = null) { await buf.Ensure(4, async); var numElements = buf.ReadInt32(); var hstore = new Dictionary <string, string?>(numElements); for (var i = 0; i < numElements; i++) { await buf.Ensure(4, async); var keyLen = buf.ReadInt32(); Debug.Assert(keyLen != -1); var key = await _textHandler.Read(buf, keyLen, async); await buf.Ensure(4, async); var valueLen = buf.ReadInt32(); hstore[key] = valueLen == -1 ? null : await _textHandler.Read(buf, valueLen, async); } return(hstore); }
protected internal override async ValueTask <TAny> Read <TAny>(NpgsqlReadBuffer buf, int len, bool async, FieldDescription fieldDescription = null) { if (_resolvedType != typeof(TAny)) { Map(typeof(TAny)); } await buf.Ensure(4, async); var fieldCount = buf.ReadInt32(); if (fieldCount != _members.Count) // PostgreSQL sanity check { throw new Exception($"pg_attributes contains {_members.Count} rows for type {PgDisplayName}, but {fieldCount} fields were received!"); } // If TAny is a struct, we have to box it here to properly set its fields below object result = Activator.CreateInstance <TAny>(); foreach (var member in _members) { await buf.Ensure(8, async); buf.ReadInt32(); // read typeOID, not used var fieldLen = buf.ReadInt32(); if (fieldLen == -1) { continue; // Null field, simply skip it and leave at default } member.Setter(result, await member.Handler.ReadAsObject(buf, fieldLen, async)); } return((TAny)result); }
/// <inheritdoc /> public override async ValueTask <BitArray> Read(NpgsqlReadBuffer buf, int len, bool async, FieldDescription?fieldDescription = null) { await buf.Ensure(4, async); var numBits = buf.ReadInt32(); var result = new BitArray(numBits); var bytesLeft = len - 4; // Remove leading number of bits if (bytesLeft == 0) { return(result); } var bitNo = 0; while (true) { var iterationEndPos = bytesLeft > buf.ReadBytesLeft ? bytesLeft - buf.ReadBytesLeft : 1; for (; bytesLeft > iterationEndPos; bytesLeft--) { // ReSharper disable ShiftExpressionRealShiftCountIsZero var chunk = buf.ReadByte(); result[bitNo++] = (chunk & (1 << 7)) != 0; result[bitNo++] = (chunk & (1 << 6)) != 0; result[bitNo++] = (chunk & (1 << 5)) != 0; result[bitNo++] = (chunk & (1 << 4)) != 0; result[bitNo++] = (chunk & (1 << 3)) != 0; result[bitNo++] = (chunk & (1 << 2)) != 0; result[bitNo++] = (chunk & (1 << 1)) != 0; result[bitNo++] = (chunk & (1 << 0)) != 0; } if (bytesLeft == 1) { break; } Debug.Assert(buf.ReadBytesLeft == 0); await buf.Ensure(Math.Min(bytesLeft, buf.Size), async); } if (bitNo < result.Length) { var remainder = result.Length - bitNo; await buf.Ensure(1, async); var lastChunk = buf.ReadByte(); for (var i = 7; i >= 8 - remainder; i--) { result[bitNo++] = (lastChunk & (1 << i)) != 0; } } return(result); }
public ValueTask <bool> MoveNextAsync() { if (_tupleEnumerable.State != RowState.Reading) { throw new ObjectDisposedException(null); } using (NoSynchronizationContextScope.Enter()) return(MoveNextCore()); async ValueTask <bool> MoveNextCore() { // Consume the previous column if (_pos != -1) { await _value.Consume(_cancellationToken); } if (_pos + 1 == _numColumns) { return(false); } _pos++; // Read the next column await _readBuffer.Ensure(1, async : true); var kind = (TupleDataKind)_readBuffer.ReadByte(); int len; switch (kind) { case TupleDataKind.Null: case TupleDataKind.UnchangedToastedValue: len = 0; break; case TupleDataKind.TextValue: case TupleDataKind.BinaryValue: if (_readBuffer.ReadBytesLeft < 4) { using var tokenRegistration = _readBuffer.Connector.StartNestedCancellableOperation(_cancellationToken); await _readBuffer.Ensure(4, async : true); } len = _readBuffer.ReadInt32(); break; default: throw new ArgumentOutOfRangeException(); } _value.Reset(kind, len, _rowDescription[_pos]); return(true); } }
public override async Task <NpgsqlPolygon> Read(NpgsqlReadBuffer buf, int len, bool async, FieldDescription fieldDescription = null) { await buf.Ensure(4, async); var numPoints = buf.ReadInt32(); var result = new NpgsqlPolygon(numPoints); for (var i = 0; i < numPoints; i++) { await buf.Ensure(16, async); result.Add(new NpgsqlPoint(buf.ReadDouble(), buf.ReadDouble())); } return(result); }
private protected async ValueTask <NpgsqlRange <TAny> > DoRead <TAny>(NpgsqlReadBuffer buf, int len, bool async, FieldDescription?fieldDescription) { await buf.Ensure(1, async); var flags = (RangeFlags)buf.ReadByte(); if ((flags & RangeFlags.Empty) != 0) { return(NpgsqlRange <TAny> .Empty); } var lowerBound = default(TAny); var upperBound = default(TAny); if ((flags & RangeFlags.LowerBoundInfinite) == 0) { lowerBound = await _subtypeHandler.ReadWithLength <TAny>(buf, async); } if ((flags & RangeFlags.UpperBoundInfinite) == 0) { upperBound = await _subtypeHandler.ReadWithLength <TAny>(buf, async); } return(new NpgsqlRange <TAny>(lowerBound, upperBound, flags)); }
public override async ValueTask Read(TComposite composite, NpgsqlReadBuffer buffer, bool async, CancellationToken cancellationToken = default) { if (_set == null) { ThrowHelper.ThrowInvalidOperationException_NoPropertySetter(typeof(TComposite), MemberInfo); } await buffer.Ensure(sizeof(uint) + sizeof(int), async, cancellationToken); var oid = buffer.ReadUInt32(); Debug.Assert(oid == PostgresType.OID); var length = buffer.ReadInt32(); if (length == -1) { return; } var value = NullableHandler <TMember> .Exists ? await NullableHandler <TMember> .ReadAsync(_handler, buffer, length, async, cancellationToken : cancellationToken) : await _handler.Read <TMember>(buffer, length, async, cancellationToken : cancellationToken); _set(composite, value); }
/// <inheritdoc /> public override async ValueTask <Dictionary <string, string?> > Read(NpgsqlReadBuffer buf, int len, bool async, FieldDescription?fieldDescription = null, CancellationToken cancellationToken = default) { await buf.Ensure(4, async, cancellationToken); var numElements = buf.ReadInt32(); return(await ReadInto(new Dictionary <string, string?>(numElements), numElements, buf, async, cancellationToken)); }
public override async ValueTask <NpgsqlRange <TElement>[]> Read( NpgsqlReadBuffer buf, int len, bool async, FieldDescription?fieldDescription = null) { await buf.Ensure(4, async); var numRanges = buf.ReadInt32(); var multirange = new NpgsqlRange <TElement> [numRanges]; for (var i = 0; i < numRanges; i++) { await buf.Ensure(4, async); var rangeLen = buf.ReadInt32(); multirange[i] = await _rangeHandler.Read(buf, rangeLen, async, fieldDescription); } return(multirange); }
async ValueTask <List <NpgsqlRange <TElement> > > INpgsqlTypeHandler <List <NpgsqlRange <TElement> > > .Read( NpgsqlReadBuffer buf, int len, bool async, FieldDescription?fieldDescription) { await buf.Ensure(4, async); var numRanges = buf.ReadInt32(); var multirange = new List <NpgsqlRange <TElement> >(numRanges); for (var i = 0; i < numRanges; i++) { await buf.Ensure(4, async); var rangeLen = buf.ReadInt32(); multirange.Add(await _rangeHandler.Read(buf, rangeLen, async, fieldDescription)); } return(multirange); }
public async ValueTask <T> Read <T>(NpgsqlReadBuffer buffer, bool async, CancellationToken cancellationToken = default) { await buffer.Ensure(sizeof(uint) + sizeof(int), async, cancellationToken); var oid = buffer.ReadUInt32(); var length = buffer.ReadInt32(); if (length == -1) { return(default !);
async ValueTask <ImmutableDictionary <string, string?> > INpgsqlTypeHandler <ImmutableDictionary <string, string?> > .Read( NpgsqlReadBuffer buf, int len, bool async, FieldDescription?fieldDescription, CancellationToken cancellationToken) { await buf.Ensure(4, async, cancellationToken); var numElements = buf.ReadInt32(); return((await ReadInto(ImmutableDictionary <string, string?> .Empty.ToBuilder(), numElements, buf, async, cancellationToken)) .ToImmutable()); }
public override async Task <PostgisGeometry> Read(NpgsqlReadBuffer buf, int len, bool async, FieldDescription fieldDescription = null) { await buf.Ensure(5, async); var bo = (ByteOrder)buf.ReadByte(); var id = buf.ReadUInt32(bo); var srid = 0u; if ((id & (uint)EwkbModifiers.HasSRID) != 0) { await buf.Ensure(4, async); srid = buf.ReadUInt32(bo); } var geom = await DoRead(buf, (WkbIdentifier)(id & 7), bo, async); geom.SRID = srid; return(geom); }
async Task ReadHeader(bool async) { _leftToReadInDataMsg = Expect <CopyDataMessage>(await _connector.ReadMessage(async), _connector).Length; var headerLen = NpgsqlRawCopyStream.BinarySignature.Length + 4 + 4; await _buf.Ensure(headerLen, async); if (NpgsqlRawCopyStream.BinarySignature.Any(t => _buf.ReadByte() != t)) { throw new NpgsqlException("Invalid COPY binary signature at beginning!"); } var flags = _buf.ReadInt32(); if (flags != 0) { throw new NotSupportedException("Unsupported flags in COPY operation (OID inclusion?)"); } _buf.ReadInt32(); // Header extensions, currently unused _leftToReadInDataMsg -= headerLen; }
internal async ValueTask <TAny> ReadWithLength <TAny>(NpgsqlReadBuffer buf, bool async, FieldDescription fieldDescription = null) { await buf.Ensure(4, async); var len = buf.ReadInt32(); if (len == -1) { return(default(TAny)); } return(await Read <TAny>(buf, len, async, fieldDescription)); }
public override async ValueTask <PostgisGeometry> Read(NpgsqlReadBuffer buf, int len, bool async, FieldDescription?fieldDescription = null, CancellationToken cancellationToken = default) { await buf.Ensure(5, async, cancellationToken); var le = buf.ReadByte() != 0; var id = buf.ReadUInt32(le); var srid = 0u; if ((id & (uint)EwkbModifiers.HasSRID) != 0) { await buf.Ensure(4, async, cancellationToken); srid = buf.ReadUInt32(le); } var geom = await DoRead(buf, (WkbIdentifier)(id & 7), le, async, cancellationToken); geom.SRID = srid; return(geom); }
async ValueTask <T> ReadInto <T>(T dictionary, int numElements, NpgsqlReadBuffer buf, bool async, CancellationToken cancellationToken = default) where T : IDictionary <string, string?> { for (var i = 0; i < numElements; i++) { await buf.Ensure(4, async, cancellationToken); var keyLen = buf.ReadInt32(); Debug.Assert(keyLen != -1); var key = await _textHandler.Read(buf, keyLen, async, cancellationToken : cancellationToken); await buf.Ensure(4, async, cancellationToken); var valueLen = buf.ReadInt32(); dictionary[key] = valueLen == -1 ? null : await _textHandler.Read(buf, valueLen, async, cancellationToken : cancellationToken); } return(dictionary); }
public override async ValueTask <BitArray> Read(NpgsqlReadBuffer buf, int len, bool async, FieldDescription fieldDescription = null) { await buf.Ensure(4, async); var numBits = buf.ReadInt32(); var result = new BitArray(numBits); var bytesLeft = len - 4; // Remove leading number of bits var bitNo = 0; do { var iterationEndPos = bytesLeft - Math.Min(bytesLeft, buf.ReadBytesLeft) + 1; for (; bytesLeft > iterationEndPos; bytesLeft--) { var chunk = buf.ReadByte(); result[bitNo++] = (chunk & (1 << 7)) != 0; result[bitNo++] = (chunk & (1 << 6)) != 0; result[bitNo++] = (chunk & (1 << 5)) != 0; result[bitNo++] = (chunk & (1 << 4)) != 0; result[bitNo++] = (chunk & (1 << 3)) != 0; result[bitNo++] = (chunk & (1 << 2)) != 0; result[bitNo++] = (chunk & (1 << 1)) != 0; result[bitNo++] = (chunk & (1 << 0)) != 0; } } while (bytesLeft > 1); if (bitNo < result.Length) { var remainder = result.Length - bitNo; await buf.Ensure(1, async); var lastChunk = buf.ReadByte(); for (var i = 7; i >= 8 - remainder; i--) { result[bitNo++] = (lastChunk & (1 << i)) != 0; } } return(result); }
public override async ValueTask <object[]> Read(NpgsqlReadBuffer buf, int len, bool async, FieldDescription?fieldDescription = null) { await buf.Ensure(4, async); var fieldCount = buf.ReadInt32(); var result = new object[fieldCount]; for (var i = 0; i < fieldCount; i++) { await buf.Ensure(8, async); var typeOID = buf.ReadUInt32(); var fieldLen = buf.ReadInt32(); if (fieldLen == -1) // Null field, simply skip it and leave at default { continue; } result[i] = await _typeMapper.GetByOID(typeOID).ReadAsObject(buf, fieldLen, async); } return(result); }
/// <inheritdoc /> public override async ValueTask <NpgsqlPath> Read(NpgsqlReadBuffer buf, int len, bool async, FieldDescription?fieldDescription = null) { await buf.Ensure(5, async); var open = buf.ReadByte() switch { 1 => false, 0 => true, _ => throw new Exception("Error decoding binary geometric path: bad open byte") }; var numPoints = buf.ReadInt32(); var result = new NpgsqlPath(numPoints, open); for (var i = 0; i < numPoints; i++) { await buf.Ensure(16, async); result.Add(new NpgsqlPoint(buf.ReadDouble(), buf.ReadDouble())); } return(result); }
/// <inheritdoc /> public override async ValueTask <string> Read(NpgsqlReadBuffer buf, int len, bool async, FieldDescription?fieldDescription = null) { await buf.Ensure(1, async); var version = buf.ReadByte(); if (version != JsonPathVersion) { throw new NotSupportedException($"Don't know how to decode JSONPATH with wire format {version}, your connection is now broken"); } return(await _textHandler.Read(buf, len - 1, async, fieldDescription)); }
public override async ValueTask <string> Read(NpgsqlReadBuffer buf, int len, bool async, FieldDescription?fieldDescription = null) { await buf.Ensure(1, async); var version = buf.ReadByte(); if (version != LTxtQueryProtocolVersion) { throw new NotSupportedException($"Don't know how to decode ltxtquery with wire format {version}, your connection is now broken"); } return(await base.Read(buf, len - 1, async, fieldDescription)); }
async ValueTask <bool> INpgsqlTypeHandler <bool> .Read(NpgsqlReadBuffer buf, int len, bool async, FieldDescription?fieldDescription) { await buf.Ensure(5, async); var bitLen = buf.ReadInt32(); if (bitLen != 1) { throw new InvalidCastException("Can't convert a BIT(N) type to bool, only BIT(1)"); } var b = buf.ReadByte(); return((b & 128) != 0); }
/// <inheritdoc /> public override async ValueTask <NpgsqlTsVector> Read(NpgsqlReadBuffer buf, int len, bool async, FieldDescription?fieldDescription = null) { await buf.Ensure(4, async); var numLexemes = buf.ReadInt32(); len -= 4; var lexemes = new List <NpgsqlTsVector.Lexeme>(); for (var lexemePos = 0; lexemePos < numLexemes; lexemePos++) { await buf.Ensure(Math.Min(len, MaxSingleLexemeBytes), async); var posBefore = buf.ReadPosition; List <NpgsqlTsVector.Lexeme.WordEntryPos>?positions = null; var lexemeString = buf.ReadNullTerminatedString(); int numPositions = buf.ReadInt16(); for (var i = 0; i < numPositions; i++) { var wordEntryPos = buf.ReadInt16(); if (positions == null) { positions = new List <NpgsqlTsVector.Lexeme.WordEntryPos>(); } positions.Add(new NpgsqlTsVector.Lexeme.WordEntryPos(wordEntryPos)); } lexemes.Add(new NpgsqlTsVector.Lexeme(lexemeString, positions, true)); len -= buf.ReadPosition - posBefore; } return(new NpgsqlTsVector(lexemes, true)); }
/// <summary> /// Reads a generic list containing elements of type <typeparamref name="TRequestedElement"/> from the given buffer <paramref name="buf"/>. /// </summary> protected async ValueTask <List <TRequestedElement> > ReadList <TRequestedElement>(NpgsqlReadBuffer buf, bool async, CancellationToken cancellationToken = default) { await buf.Ensure(12, async, cancellationToken); var dimensions = buf.ReadInt32(); var containsNulls = buf.ReadInt32() == 1; buf.ReadUInt32(); // Element OID. Ignored. if (dimensions == 0) { return(ElementTypeInfo <TRequestedElement> .EmptyList); } if (dimensions > 1) { throw new NotSupportedException($"Can't read multidimensional array as List<{typeof(TRequestedElement).Name}>"); } if (ElementTypeInfo <TRequestedElement> .IsNonNullable && containsNulls) { throw new InvalidOperationException(ReadNonNullableCollectionWithNullsExceptionMessage); } await buf.Ensure(8, async, cancellationToken); var length = buf.ReadInt32(); buf.ReadInt32(); // We don't care about the lower bounds var list = new List <TRequestedElement>(length); for (var i = 0; i < length; i++) { list.Add(await ElementHandler.ReadWithLength <TRequestedElement>(buf, async, cancellationToken: cancellationToken)); } return(list); }
async ValueTask <BitVector32> INpgsqlTypeHandler <BitVector32> .Read(NpgsqlReadBuffer buf, int len, bool async, FieldDescription?fieldDescription) { if (len > 4 + 4) { throw new InvalidCastException("Can't read PostgreSQL bitstring with more than 32 bits into BitVector32"); } await buf.Ensure(4 + 4, async); var numBits = buf.ReadInt32(); return(numBits == 0 ? new BitVector32(0) : new BitVector32(buf.ReadInt32())); }
protected internal async ValueTask <TAny> Read <TAny>(NpgsqlReadBuffer buf, int len, bool async, FieldDescription?fieldDescription = null) { switch (this) { case INpgsqlSimpleTypeHandler <TAny> simpleTypeHandler: await buf.Ensure(len, async); return(simpleTypeHandler.Read(buf, len, fieldDescription)); case INpgsqlTypeHandler <TAny> typeHandler: return(await typeHandler.Read(buf, len, async, fieldDescription)); default: return(await ReadCustom <TAny>(buf, len, async, fieldDescription)); } }
async ValueTask <bool> INpgsqlTypeHandler <bool> .Read(NpgsqlReadBuffer buf, int len, bool async, FieldDescription fieldDescription) { await buf.Ensure(5, async); var bitLen = buf.ReadInt32(); if (bitLen != 1) { // This isn't a single bit - error. // Consume the rest of the value first so the connection is left in a good state. buf.Skip(len - 4); throw new NpgsqlSafeReadException(new InvalidCastException("Can't convert a BIT(N) type to bool, only BIT(1)")); } var b = buf.ReadByte(); return((b & 128) != 0); }