public override async Task Write(object value, NpgsqlWriteBuffer buf, NpgsqlLengthCache lengthCache, NpgsqlParameter parameter, bool async) { Debug.Assert(_resolvedType != null); Debug.Assert(_members != null); if (buf.WriteSpaceLeft < 4) { await buf.Flush(async); } buf.WriteInt32(_members.Count); foreach (var fieldDescriptor in _members) { var fieldHandler = fieldDescriptor.Handler; var fieldValue = fieldDescriptor.Getter(value); if (buf.WriteSpaceLeft < 4) { await buf.Flush(async); } buf.WriteUInt32(fieldDescriptor.OID); await fieldHandler.WriteObjectWithLength(fieldValue, buf, lengthCache, null, async); } }
/// <inheritdoc /> public override async Task Write(BitArray value, NpgsqlWriteBuffer buf, NpgsqlLengthCache?lengthCache, NpgsqlParameter?parameter, bool async, CancellationToken cancellationToken = default) { // Initial bitlength byte if (buf.WriteSpaceLeft < 4) { await buf.Flush(async, cancellationToken); } buf.WriteInt32(value.Length); var byteLen = (value.Length + 7) / 8; var pos = 0; while (true) { var endPos = pos + Math.Min(byteLen - pos, buf.WriteSpaceLeft); for (; pos < endPos; pos++) { var bitPos = pos * 8; var b = 0; for (var i = 0; i < Math.Min(8, value.Length - bitPos); i++) { b += (value[bitPos + i] ? 1 : 0) << (8 - i - 1); } buf.WriteByte((byte)b); } if (pos == byteLen) { return; } await buf.Flush(async, cancellationToken); } }
public override async Task Write(NpgsqlTsQuery query, NpgsqlWriteBuffer buf, NpgsqlLengthCache lengthCache, NpgsqlParameter parameter, bool async) { var numTokens = GetTokenCount(query); if (buf.WriteSpaceLeft < 4) { await buf.Flush(async); } buf.WriteInt32(numTokens); if (numTokens == 0) { return; } _stack.Push(query); while (_stack.Count > 0) { if (buf.WriteSpaceLeft < 2) { await buf.Flush(async); } if (_stack.Peek().Kind == NpgsqlTsQuery.NodeKind.Lexeme && buf.WriteSpaceLeft < MaxSingleTokenBytes) { await buf.Flush(async); } var node = _stack.Pop(); buf.WriteByte(node.Kind == NpgsqlTsQuery.NodeKind.Lexeme ? (byte)1 : (byte)2); if (node.Kind != NpgsqlTsQuery.NodeKind.Lexeme) { buf.WriteByte((byte)node.Kind); if (node.Kind == NpgsqlTsQuery.NodeKind.Not) { _stack.Push(((NpgsqlTsQueryNot)node).Child); } else { _stack.Push(((NpgsqlTsQueryBinOp)node).Right); _stack.Push(((NpgsqlTsQueryBinOp)node).Left); } } else { var lexemeNode = (NpgsqlTsQueryLexeme)node; buf.WriteByte((byte)lexemeNode.Weights); buf.WriteByte(lexemeNode.IsPrefixSearch ? (byte)1 : (byte)0); buf.WriteString(lexemeNode.Text); buf.WriteByte(0); } } _stack.Clear(); }
/// <inheritdoc /> public async Task Write(string value, NpgsqlWriteBuffer buf, NpgsqlLengthCache?lengthCache, NpgsqlParameter?parameter, bool async, CancellationToken cancellationToken = default) { // Initial bitlength byte if (buf.WriteSpaceLeft < 4) { await buf.Flush(async, cancellationToken); } buf.WriteInt32(value.Length); var pos = 0; var byteLen = (value.Length + 7) / 8; var bytePos = 0; while (true) { var endBytePos = bytePos + Math.Min(byteLen - bytePos - 1, buf.WriteSpaceLeft); for (; bytePos < endBytePos; bytePos++) { var b = 0; b += (value[pos++] - '0') << 7; b += (value[pos++] - '0') << 6; b += (value[pos++] - '0') << 5; b += (value[pos++] - '0') << 4; b += (value[pos++] - '0') << 3; b += (value[pos++] - '0') << 2; b += (value[pos++] - '0') << 1; b += (value[pos++] - '0'); buf.WriteByte((byte)b); } if (bytePos >= byteLen - 1) { break; } await buf.Flush(async, cancellationToken); } if (pos < value.Length) { if (buf.WriteSpaceLeft < 1) { await buf.Flush(async, cancellationToken); } var remainder = value.Length - pos; var lastChunk = 0; for (var i = 7; i >= 8 - remainder; i--) { lastChunk += (value[pos++] - '0') << i; } buf.WriteByte((byte)lastChunk); } }
/// <inheritdoc /> public async Task Write(ArraySegment <byte> value, NpgsqlWriteBuffer buf, NpgsqlLengthCache lengthCache, [CanBeNull] NpgsqlParameter parameter, bool async) { if (value.Array is null) { return; } if (!(parameter == null || parameter.Size <= 0 || parameter.Size >= value.Count)) { value = new ArraySegment <byte>(value.Array, value.Offset, Math.Min(parameter.Size, value.Count)); } // The entire segment fits in our buffer, copy it as usual. if (value.Count <= buf.WriteSpaceLeft) { buf.WriteBytes(value.Array, value.Offset, value.Count); return; } // The segment is larger than our buffer. Flush whatever is currently in the buffer and // write the array directly to the socket. await buf.Flush(async); buf.DirectWrite(value.Array, value.Offset, value.Count); }
public async Task Write(GeometryCollection value, NpgsqlWriteBuffer buf, NpgsqlLengthCache lengthCache, NpgsqlParameter parameter, bool async) { var type = EwkbGeometryType.GeometryCollection; var size = SizeOfHeader; var srid = GetSrid(value.CRS); if (srid != 0) { size += sizeof(int); type |= EwkbGeometryType.HasSrid; } if (buf.WriteSpaceLeft < size) { await buf.Flush(async); } var geometries = value.Geometries; buf.WriteByte(0); // Most significant byte first buf.WriteInt32((int)type); buf.WriteInt32(geometries.Count); if (srid != 0) { buf.WriteInt32(srid); } for (var i = 0; i < geometries.Count; ++i) { await Write((GeoJSONObject)geometries[i], buf, lengthCache, parameter, async); } }
public async Task Write(MultiLineString value, NpgsqlWriteBuffer buf, NpgsqlLengthCache lengthCache, NpgsqlParameter parameter, bool async) { var type = EwkbGeometryType.MultiLineString; var size = SizeOfHeader; var srid = GetSrid(value.CRS); if (srid != 0) { size += sizeof(int); type |= EwkbGeometryType.HasSrid; } if (buf.WriteSpaceLeft < size) { await buf.Flush(async); } var coordinates = value.Coordinates; buf.WriteByte(0); // Most significant byte first buf.WriteInt32((int)type); buf.WriteInt32(coordinates.Count); if (srid != 0) { buf.WriteInt32(srid); } for (var i = 0; i < coordinates.Count; ++i) { await Write(coordinates[i], buf, lengthCache, parameter, async); } }
protected internal override Task WriteObjectWithLength(object value, NpgsqlWriteBuffer buf, NpgsqlLengthCache lengthCache, NpgsqlParameter parameter, bool async) { if (value == null || value is DBNull) { return(base.WriteObjectWithLength(value, buf, lengthCache, parameter, async)); } var convertedValue = value is string asString ? asString : (string)parameter.ConvertedValue; if (buf.WriteSpaceLeft < 4) { return(WriteWithLengthLong()); } buf.WriteInt32(ValidateObjectAndGetLength(value, ref lengthCache, parameter)); return(base.Write(convertedValue, buf, lengthCache, parameter, async)); async Task WriteWithLengthLong() { await buf.Flush(async); buf.WriteInt32(ValidateObjectAndGetLength(value, ref lengthCache, parameter)); await base.Write(convertedValue, buf, lengthCache, parameter, async); } }
public async Task Write(Point value, NpgsqlWriteBuffer buf, NpgsqlLengthCache lengthCache, NpgsqlParameter parameter, bool async) { var type = EwkbGeometryType.Point; var size = SizeOfHeader; var srid = GetSrid(value.CRS); if (srid != 0) { size += sizeof(int); type |= EwkbGeometryType.HasSrid; } if (buf.WriteSpaceLeft < size) { await buf.Flush(async); } buf.WriteByte(0); // Most significant byte first buf.WriteInt32((int)type); if (srid != 0) { buf.WriteInt32(srid); } await WritePosition(value.Coordinates, buf, async); }
/// <summary> /// In the vast majority of cases writing a parameter to the buffer won't need to perform I/O. /// </summary> public override Task WriteWithLengthInternal <TAny>([AllowNull] TAny value, NpgsqlWriteBuffer buf, NpgsqlLengthCache?lengthCache, NpgsqlParameter?parameter, bool async, CancellationToken cancellationToken = default) { if (buf.WriteSpaceLeft < 4) { return(WriteWithLengthLong()); } if (value == null || typeof(TAny) == typeof(DBNull)) { buf.WriteInt32(-1); return(Task.CompletedTask); } return(WriteWithLength(value, buf, lengthCache, parameter, async, cancellationToken)); async Task WriteWithLengthLong() { if (buf.WriteSpaceLeft < 4) { await buf.Flush(async, cancellationToken); } if (value == null || typeof(TAny) == typeof(DBNull)) { buf.WriteInt32(-1); return; } await WriteWithLength(value, buf, lengthCache, parameter, async, cancellationToken); } }
public override async Task Write(ArraySegment <char> value, NpgsqlWriteBuffer buf, NpgsqlLengthCache lengthCache, NpgsqlParameter parameter, bool async) { if (buf.WriteSpaceLeft < 1) { await buf.Flush(async); } buf.WriteByte(JsonbProtocolVersion); await base.Write(value, buf, lengthCache, parameter, async); }
/// <inheritdoc /> public override async Task Write(NpgsqlPolygon value, NpgsqlWriteBuffer buf, NpgsqlLengthCache?lengthCache, NpgsqlParameter?parameter, bool async, CancellationToken cancellationToken = default) { if (buf.WriteSpaceLeft < 4) { await buf.Flush(async, cancellationToken); } buf.WriteInt32(value.Count); foreach (var p in value) { if (buf.WriteSpaceLeft < 16) { await buf.Flush(async, cancellationToken); } buf.WriteDouble(p.X); buf.WriteDouble(p.Y); } }
/// <inheritdoc /> public async Task Write(bool value, NpgsqlWriteBuffer buf, NpgsqlLengthCache?lengthCache, NpgsqlParameter?parameter, bool async, CancellationToken cancellationToken = default) { if (buf.WriteSpaceLeft < 5) { await buf.Flush(async, cancellationToken); } buf.WriteInt32(1); buf.WriteByte(value ? (byte)0x80 : (byte)0); }
public override async Task Write(NpgsqlPolygon value, NpgsqlWriteBuffer buf, NpgsqlLengthCache lengthCache, NpgsqlParameter parameter, bool async) { if (buf.WriteSpaceLeft < 4) { await buf.Flush(async); } buf.WriteInt32(value.Count); foreach (var p in value) { if (buf.WriteSpaceLeft < 16) { await buf.Flush(async); } buf.WriteDouble(p.X); buf.WriteDouble(p.Y); } }
async Task StartRow(bool async, CancellationToken cancellationToken = default) { CheckReady(); if (_column != -1 && _column != NumColumns) { ThrowHelper.ThrowInvalidOperationException_BinaryImportParametersMismatch(NumColumns, _column); } if (_buf.WriteSpaceLeft < 2) { await _buf.Flush(async, cancellationToken); } _buf.WriteInt16(NumColumns); _column = 0; _rowsImported++; }
public async Task Write(bool value, NpgsqlWriteBuffer buf, NpgsqlLengthCache lengthCache, NpgsqlParameter parameter, bool async) { if (buf.WriteSpaceLeft < 5) { await buf.Flush(async); } buf.WriteInt32(1); buf.WriteByte(value ? (byte)0x80 : (byte)0); }
/// <inheritdoc /> public override async Task Write(NpgsqlPath value, NpgsqlWriteBuffer buf, NpgsqlLengthCache?lengthCache, NpgsqlParameter?parameter, bool async) { if (buf.WriteSpaceLeft < 5) { await buf.Flush(async); } buf.WriteByte((byte)(value.Open ? 0 : 1)); buf.WriteInt32(value.Count); foreach (var p in value) { if (buf.WriteSpaceLeft < 16) { await buf.Flush(async); } buf.WriteDouble(p.X); buf.WriteDouble(p.Y); } }
internal override async Task Write(NpgsqlWriteBuffer buf, bool async) { Debug.Assert(Statement != null && Statement.All(c => c < 128)); var queryByteLen = _encoding.GetByteCount(Query); if (buf.WriteSpaceLeft < 1 + 4 + Statement.Length + 1) { await buf.Flush(async); } var messageLength = 1 + // Message code 4 + // Length Statement.Length + 1 + // Null terminator queryByteLen + 1 + // Null terminator 2 + // Number of parameters ParameterTypeOIDs.Count * 4; buf.WriteByte(Code); buf.WriteInt32(messageLength - 1); buf.WriteNullTerminatedString(Statement); await buf.WriteString(Query, queryByteLen, async); if (buf.WriteSpaceLeft < 1 + 2) { await buf.Flush(async); } buf.WriteByte(0); // Null terminator for the query buf.WriteInt16((short)ParameterTypeOIDs.Count); foreach (var t in ParameterTypeOIDs) { if (buf.WriteSpaceLeft < 4) { await buf.Flush(async); } buf.WriteInt32((int)t); } }
public override async Task Write(ArraySegment <char> value, NpgsqlWriteBuffer buf, NpgsqlLengthCache?lengthCache, NpgsqlParameter?parameter, bool async, CancellationToken cancellationToken = default) { if (buf.WriteSpaceLeft < 1) { await buf.Flush(async, cancellationToken); } buf.WriteByte(LTxtQueryProtocolVersion); await base.Write(value, buf, lengthCache, parameter, async, cancellationToken); }
public async Task Write(Polygon value, NpgsqlWriteBuffer buf, NpgsqlLengthCache lengthCache, NpgsqlParameter parameter, bool async) { var type = EwkbGeometryType.Polygon; var size = SizeOfHeader; var srid = GetSrid(value.CRS); if (srid != 0) { size += sizeof(int); type |= EwkbGeometryType.HasSrid; } if (buf.WriteSpaceLeft < size) { await buf.Flush(async); } var lines = value.Coordinates; buf.WriteByte(0); // Most significant byte first buf.WriteInt32((int)type); buf.WriteInt32(lines.Count); if (srid != 0) { buf.WriteInt32(srid); } for (var i = 0; i < lines.Count; ++i) { if (buf.WriteSpaceLeft < 4) { await buf.Flush(async); } var coordinates = lines[i].Coordinates; buf.WriteInt32(coordinates.Count); for (var j = 0; j < coordinates.Count; ++j) { await WritePosition(coordinates[j], buf, async); } } }
internal override async Task Write(NpgsqlWriteBuffer buf, bool async) { if (buf.WriteSpaceLeft < 1 + 5) { await buf.Flush(async); } buf.WriteByte(Code); buf.WriteInt32(4 + PayloadLength); if (PayloadLength <= buf.WriteSpaceLeft) { // The entire array fits in our buffer, copy it into the buffer as usual. buf.WriteBytes(Payload, PayloadOffset, Payload.Length); return; } await buf.Flush(async); buf.DirectWrite(Payload, PayloadOffset, PayloadLength); }
/// <inheritdoc /> public override async Task Write(string value, NpgsqlWriteBuffer buf, NpgsqlLengthCache?lengthCache, NpgsqlParameter?parameter, bool async, CancellationToken cancellationToken = default) { if (buf.WriteSpaceLeft < 1) { await buf.Flush(async, cancellationToken); } buf.WriteByte(JsonPathVersion); await _textHandler.Write(value, buf, lengthCache, parameter, async, cancellationToken); }
internal override async Task Write(NpgsqlWriteBuffer buf, bool async) { if (buf.WriteSpaceLeft < 1 + 4) { await buf.Flush(async); } var queryByteLen = _encoding.GetByteCount(_query); buf.WriteByte(Code); buf.WriteInt32(4 + // Message length (including self excluding code) queryByteLen + // Query byte length 1); // Null terminator await buf.WriteString(_query, queryByteLen, async); if (buf.WriteSpaceLeft < 1) { await buf.Flush(async); } buf.WriteByte(0); }
/// <inheritdoc /> public override async Task Write(string value, NpgsqlWriteBuffer buf, NpgsqlLengthCache?lengthCache, NpgsqlParameter?parameter, bool async) { if (_isJsonb) { if (buf.WriteSpaceLeft < 1) { await buf.Flush(async); } buf.WriteByte(JsonbProtocolVersion); } await _textHandler.Write(value, buf, lengthCache, parameter, async); }
/// <inheritdoc /> protected override async Task WriteWithLength <TAny>(TAny value, NpgsqlWriteBuffer buf, NpgsqlLengthCache?lengthCache, NpgsqlParameter?parameter, bool async, CancellationToken cancellationToken = default) { buf.WriteInt32(ValidateAndGetLength(value, ref lengthCache, parameter)); if (_isJsonb) { if (buf.WriteSpaceLeft < 1) { await buf.Flush(async, cancellationToken); } buf.WriteByte(JsonbProtocolVersion); } if (typeof(TAny) == typeof(string)) { await _textHandler.Write((string)(object)value !, buf, lengthCache, parameter, async, cancellationToken); } else if (typeof(TAny) == typeof(char[])) { await _textHandler.Write((char[])(object)value !, buf, lengthCache, parameter, async, cancellationToken); } else if (typeof(TAny) == typeof(ArraySegment <char>)) { await _textHandler.Write((ArraySegment <char>)(object) value !, buf, lengthCache, parameter, async, cancellationToken); } else if (typeof(TAny) == typeof(char)) { await _textHandler.Write((char)(object)value !, buf, lengthCache, parameter, async, cancellationToken); } else if (typeof(TAny) == typeof(byte[])) { await _textHandler.Write((byte[])(object)value !, buf, lengthCache, parameter, async, cancellationToken); } else if (typeof(TAny) == typeof(JsonDocument)) { var data = parameter?.ConvertedValue != null ? (byte[])parameter.ConvertedValue : SerializeJsonDocument((JsonDocument)(object)value !); await buf.WriteBytesRaw(data, async, cancellationToken); } else { // User POCO, read serialized representation from the validation phase var s = parameter?.ConvertedValue != null ? (string)parameter.ConvertedValue : JsonSerializer.Serialize(value !, value !.GetType(), _serializerOptions); await _textHandler.Write(s, buf, lengthCache, parameter, async, cancellationToken); } }
static async Task WritePosition(IPosition coordinate, NpgsqlWriteBuffer buf, bool async) { var altitude = coordinate.Altitude; if (buf.WriteSpaceLeft < SizeOfPoint(altitude.HasValue)) { await buf.Flush(async); } buf.WriteDouble(coordinate.Longitude); buf.WriteDouble(coordinate.Latitude); if (altitude.HasValue) { buf.WriteDouble(altitude.Value); } }
/// <inheritdoc /> public override async Task Write(NpgsqlTsVector vector, NpgsqlWriteBuffer buf, NpgsqlLengthCache?lengthCache, NpgsqlParameter?parameter, bool async) { if (buf.WriteSpaceLeft < 4) { await buf.Flush(async); } buf.WriteInt32(vector.Count); foreach (var lexeme in vector) { if (buf.WriteSpaceLeft < MaxSingleLexemeBytes) { await buf.Flush(async); } buf.WriteString(lexeme.Text); buf.WriteByte(0); buf.WriteInt16(lexeme.Count); for (var i = 0; i < lexeme.Count; i++) { buf.WriteInt16(lexeme[i].Value); } } }
async Task Write(byte[] value, NpgsqlWriteBuffer buf, int offset, int count, bool async, CancellationToken cancellationToken = default) { // The entire segment fits in our buffer, copy it as usual. if (count <= buf.WriteSpaceLeft) { buf.WriteBytes(value, offset, count); return; } // The segment is larger than our buffer. Flush whatever is currently in the buffer and // write the array directly to the socket. await buf.Flush(async, cancellationToken); await buf.DirectWrite(new ReadOnlyMemory <byte>(value, offset, count), async, cancellationToken); }
async Task Write(byte[] value, NpgsqlWriteBuffer buf, int offset, int count, bool async) { // The entire segment fits in our buffer, copy it as usual. if (count <= buf.WriteSpaceLeft) { buf.WriteBytes(value, offset, count); return; } // The segment is larger than our buffer. Flush whatever is currently in the buffer and // write the array directly to the socket. await buf.Flush(async); await buf.DirectWrite(value, offset, count, async); }
public override async Task Write(T value, NpgsqlWriteBuffer buffer, NpgsqlLengthCache?lengthCache, NpgsqlParameter?parameter, bool async, CancellationToken cancellationToken = default) { Initialize(); if (buffer.WriteSpaceLeft < sizeof(int)) { await buffer.Flush(async, cancellationToken); } buffer.WriteInt32(_memberHandlers.Length); foreach (var member in _memberHandlers) { await member.Write(value, buffer, lengthCache, async, cancellationToken); } }