Пример #1
0
        /// <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);
            }
        }
Пример #2
0
        private protected int ValidateAndGetLength <TAny>(NpgsqlRange <TAny> value, ref NpgsqlLengthCache?lengthCache, NpgsqlParameter?parameter)
        {
            var totalLen       = 1;
            var lengthCachePos = lengthCache?.Position ?? 0;

            if (!value.IsEmpty)
            {
                if (!value.LowerBoundInfinite)
                {
                    totalLen += 4;
                    if (value.LowerBound is not null)
                    {
                        totalLen += _subtypeHandler.ValidateAndGetLength(value.LowerBound, ref lengthCache, null);
                    }
                }

                if (!value.UpperBoundInfinite)
                {
                    totalLen += 4;
                    if (value.UpperBound is not null)
                    {
                        totalLen += _subtypeHandler.ValidateAndGetLength(value.UpperBound, ref lengthCache, null);
                    }
                }
            }

            // If we're traversing an already-populated length cache, rewind to first element slot so that
            // the elements' handlers can access their length cache values
            if (lengthCache != null && lengthCache.IsPopulated)
            {
                lengthCache.Position = lengthCachePos;
            }

            return(totalLen);
        }
Пример #3
0
        public override int ValidateAndGetLength(T value, ref NpgsqlLengthCache?lengthCache, NpgsqlParameter?parameter)
        {
            Initialize();

            if (lengthCache == null)
            {
                lengthCache = new NpgsqlLengthCache(1);
            }

            if (lengthCache.IsPopulated)
            {
                return(lengthCache.Get());
            }

            // Leave empty slot for the entire composite type, and go ahead an populate the element slots
            var position = lengthCache.Position;

            lengthCache.Set(0);

            // number of fields + (type oid + field length) * member count
            var length = sizeof(int) + sizeof(int) * 2 * _memberHandlers.Length;

            foreach (var member in _memberHandlers)
            {
                length += member.ValidateAndGetLength(value, ref lengthCache);
            }

            return(lengthCache.Lengths[position] = length);
        }
Пример #4
0
        /// <inheritdoc />
        public int ValidateAndGetLength(IDictionary <string, string?> value, ref NpgsqlLengthCache?lengthCache, NpgsqlParameter?parameter)
        {
            if (lengthCache == null)
            {
                lengthCache = new NpgsqlLengthCache(1);
            }
            if (lengthCache.IsPopulated)
            {
                return(lengthCache.Get());
            }

            // Leave empty slot for the entire hstore length, and go ahead an populate the individual string slots
            var pos = lengthCache.Position;

            lengthCache.Set(0);

            var totalLen = 4;  // Number of key-value pairs

            foreach (var kv in value)
            {
                totalLen += 8;   // Key length + value length
                if (kv.Key == null)
                {
                    throw new FormatException("HSTORE doesn't support null keys");
                }
                totalLen += _textHandler.ValidateAndGetLength(kv.Key, ref lengthCache, null);
                if (kv.Value != null)
                {
                    totalLen += _textHandler.ValidateAndGetLength(kv.Value !, ref lengthCache, null);
                }
            }

            return(lengthCache.Lengths[pos] = totalLen);
        }
 public Task Write(
     NpgsqlRange <DateOnly> value,
     NpgsqlWriteBuffer buf,
     NpgsqlLengthCache?lengthCache,
     NpgsqlParameter?parameter,
     bool async,
     CancellationToken cancellationToken = default)
 => WriteRange(value, buf, lengthCache, parameter, async, cancellationToken);
Пример #6
0
 /// <inheritdoc />
 public int ValidateAndGetLength(string value, ref NpgsqlLengthCache?lengthCache, NpgsqlParameter?parameter)
 {
     if (value.Any(c => c != '0' && c != '1'))
     {
         throw new FormatException("Cannot interpret as ASCII BitString: " + value);
     }
     return(4 + (value.Length + 7) / 8);
 }
Пример #7
0
 public Task Write(
     NpgsqlRange <TSubtype2>[] value,
     NpgsqlWriteBuffer buf,
     NpgsqlLengthCache?lengthCache,
     NpgsqlParameter?parameter,
     bool async,
     CancellationToken cancellationToken = default)
 => WriteMultirange(value, buf, lengthCache, parameter, async, cancellationToken);
Пример #8
0
 /// <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);
 }
Пример #9
0
 public Task Write(
     uint256 value,
     NpgsqlWriteBuffer buf,
     NpgsqlLengthCache?lengthCache,
     NpgsqlParameter?parameter,
     bool async)
 {
     return(this.Write(value.ToBytes(false), buf, lengthCache, parameter, async));
 }
Пример #10
0
        public override async Task Write(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);
        }
Пример #11
0
        /// <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);
            }
        }
Пример #12
0
        /// <summary>
        /// Called to validate and get the length of a value of an arbitrary type.
        /// Checks that the current handler supports that type and throws an exception otherwise.
        /// </summary>
        protected internal override int ValidateAndGetLength <TAny>(TAny value, ref NpgsqlLengthCache?lengthCache, NpgsqlParameter?parameter)
        {
            var typedHandler = this as INpgsqlTypeHandler <TAny>;

            if (typedHandler is null)
            {
                ThrowHelper.ThrowInvalidCastException_NotSupportedType(this, parameter, typeof(TAny));
            }

            return(typedHandler.ValidateAndGetLength(value, ref lengthCache, parameter));
        }
Пример #13
0
    /// <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);
    }
Пример #14
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);
        }
Пример #15
0
        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);
            }
        }
Пример #16
0
        /// <inheritdoc />
        public async Task Write(BitVector32 value, NpgsqlWriteBuffer buf, NpgsqlLengthCache?lengthCache, NpgsqlParameter?parameter, bool async, CancellationToken cancellationToken = default)
        {
            if (buf.WriteSpaceLeft < 8)
            {
                await buf.Flush(async, cancellationToken);
            }

            if (value.Data == 0)
            {
                buf.WriteInt32(0);
            }
            else
            {
                buf.WriteInt32(32);
                buf.WriteInt32(value.Data);
            }
        }
Пример #17
0
        public override int ValidateAndGetLength(NpgsqlRange <TElement>[] value, ref NpgsqlLengthCache?lengthCache, NpgsqlParameter?parameter)
        {
            lengthCache ??= new NpgsqlLengthCache(1);
            if (lengthCache.IsPopulated)
            {
                return(lengthCache.Get());
            }

            var sum = 4 + 4 * value.Length;

            for (var i = 0; i < value.Length; i++)
            {
                sum += _rangeHandler.ValidateAndGetLength(value[i], ref lengthCache, parameter: null);
            }

            return(lengthCache !.Set(sum));
        }
    public override async Task Write(TComposite composite, NpgsqlWriteBuffer buffer, NpgsqlLengthCache?lengthCache, bool async, CancellationToken cancellationToken = default)
    {
        if (_get == null)
        {
            ThrowHelper.ThrowInvalidOperationException_NoPropertyGetter(typeof(TComposite), MemberInfo);
        }

        if (buffer.WriteSpaceLeft < sizeof(int))
        {
            await buffer.Flush(async, cancellationToken);
        }

        buffer.WriteUInt32(PostgresType.OID);
        await(NullableHandler <TMember> .Exists
            ? NullableHandler <TMember> .WriteAsync(_handler, _get(ref composite), buffer, lengthCache, null, async, cancellationToken)
            : _handler.WriteWithLength(_get(ref composite), buffer, lengthCache, null, async, cancellationToken));
    }
Пример #19
0
        public override int ValidateAndGetLength(TComposite composite, ref NpgsqlLengthCache?lengthCache)
        {
            if (_get == null)
            {
                ThrowHelper.ThrowInvalidOperationException_NoPropertyGetter(typeof(TComposite), MemberInfo);
            }

            var value = _get(composite);

            if (value == null)
            {
                return(0);
            }

            return(NullableHandler <TMember> .Exists
                ? NullableHandler <TMember> .ValidateAndGetLength(_handler, value, ref lengthCache, null)
                : _handler.ValidateAndGetLength(value, ref lengthCache, null));
        }
Пример #20
0
        /// <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);
            }
        }
Пример #21
0
        /// <inheritdoc />
        public async Task Write(ReadOnlyMemory <byte> value, NpgsqlWriteBuffer buf, NpgsqlLengthCache?lengthCache, NpgsqlParameter?parameter, bool async)
        {
            if (parameter != null && parameter.Size > 0 && parameter.Size < value.Length)
            {
                value = value.Slice(0, parameter.Size);
            }

            // The entire segment fits in our buffer, copy it into the buffer as usual.
            if (value.Length <= buf.WriteSpaceLeft)
            {
                buf.WriteBytes(value.Span);
                return;
            }

            // The segment is larger than our buffer. Perform a direct write, flushing whatever is currently in the buffer
            // and then writing the array directly to the socket.
            await buf.DirectWrite(value, async);
        }
Пример #22
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);
            }
        }
Пример #23
0
        public async Task Write(
            List <NpgsqlRange <TElement> > 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);

            for (var i = 0; i < value.Count; i++)
            {
                await _rangeHandler.WriteWithLength(value[i], buf, lengthCache, parameter : null, async, cancellationToken);
            }
        }
Пример #24
0
        /// <inheritdoc />
        protected internal override int ValidateAndGetLength <TAny>(TAny value, ref NpgsqlLengthCache?lengthCache, NpgsqlParameter?parameter)
        {
            if (typeof(TAny) == typeof(string) ||
                typeof(TAny) == typeof(char[]) ||
                typeof(TAny) == typeof(ArraySegment <char>) ||
                typeof(TAny) == typeof(char) ||
                typeof(TAny) == typeof(byte[]))
            {
                return(_textHandler.ValidateAndGetLength(value, ref lengthCache, parameter) + _headerLen);
            }

            if (typeof(TAny) == typeof(JsonDocument))
            {
                if (lengthCache == null)
                {
                    lengthCache = new NpgsqlLengthCache(1);
                }
                if (lengthCache.IsPopulated)
                {
                    return(lengthCache.Get());
                }

                var data = SerializeJsonDocument((JsonDocument)(object)value !);
                if (parameter != null)
                {
                    parameter.ConvertedValue = data;
                }
                return(lengthCache.Set(data.Length + _headerLen));
            }

            // User POCO, need to serialize. At least internally ArrayPool buffers are used...
            var s = JsonSerializer.Serialize(value, _serializerOptions);

            if (parameter != null)
            {
                parameter.ConvertedValue = s;
            }

            return(_textHandler.ValidateAndGetLength(s, ref lengthCache, parameter) + _headerLen);
        }
Пример #25
0
    /// <inheritdoc />
    public override async Task Write(NpgsqlTsVector vector, NpgsqlWriteBuffer buf, NpgsqlLengthCache?lengthCache, NpgsqlParameter?parameter, bool async, CancellationToken cancellationToken = default)
    {
        if (buf.WriteSpaceLeft < 4)
        {
            await buf.Flush(async, cancellationToken);
        }
        buf.WriteInt32(vector.Count);

        foreach (var lexeme in vector)
        {
            if (buf.WriteSpaceLeft < MaxSingleLexemeBytes)
            {
                await buf.Flush(async, cancellationToken);
            }

            buf.WriteString(lexeme.Text);
            buf.WriteByte(0);
            buf.WriteInt16(lexeme.Count);
            for (var i = 0; i < lexeme.Count; i++)
            {
                buf.WriteInt16(lexeme[i].Value);
            }
        }
    }
Пример #26
0
 /// <inheritdoc />
 public int ValidateAndGetLength(BitVector32 value, ref NpgsqlLengthCache?lengthCache, NpgsqlParameter?parameter)
 => value.Data == 0 ? 4 : 8;
Пример #27
0
 public override int ValidateAndGetLength(ArraySegment <char> value, ref NpgsqlLengthCache?lengthCache, NpgsqlParameter?parameter) =>
 base.ValidateAndGetLength(value, ref lengthCache, parameter) + 1;
Пример #28
0
 public override int ValidateAndGetLength(string value, ref NpgsqlLengthCache?lengthCache, NpgsqlParameter?parameter) =>
 base.ValidateAndGetLength(value, ref lengthCache, parameter) + 1;
Пример #29
0
 /// <inheritdoc />
 public int ValidateAndGetLength(bool value, ref NpgsqlLengthCache?lengthCache, NpgsqlParameter?parameter)
 => 5;
Пример #30
0
 /// <inheritdoc />
 public override int ValidateAndGetLength(BitArray value, ref NpgsqlLengthCache?lengthCache, NpgsqlParameter?parameter)
 => 4 + (value.Length + 7) / 8;