예제 #1
0
        public bool Read(out NpgsqlTsQuery result)
        {
            result = null;

            if (_tokenPos == -1)
            {
                if (_buf.ReadBytesLeft < 4)
                {
                    return(false);
                }
                _numTokens  = _buf.ReadInt32();
                _bytesLeft -= 4;
                _tokenPos   = 0;
            }

            if (_numTokens == 0)
            {
                result = new NpgsqlTsQueryEmpty();
                _buf   = null;
                _nodes = null;
                return(true);
            }

            for (; _tokenPos < _numTokens; _tokenPos++)
            {
                if (_buf.ReadBytesLeft < Math.Min(_bytesLeft, MaxSingleTokenBytes))
                {
                    return(false);
                }

                int readPos = _buf.ReadPosition;

                bool isOper = _buf.ReadByte() == 2;
                if (isOper)
                {
                    NpgsqlTsQuery.NodeKind operKind = (NpgsqlTsQuery.NodeKind)_buf.ReadByte();
                    if (operKind == NpgsqlTsQuery.NodeKind.Not)
                    {
                        var node = new NpgsqlTsQueryNot(null);
                        InsertInTree(node);
                        _nodes.Push(new Tuple <NpgsqlTsQuery, int>(node, 0));
                    }
                    else
                    {
                        NpgsqlTsQuery node = null;

                        if (operKind == NpgsqlTsQuery.NodeKind.And)
                        {
                            node = new NpgsqlTsQueryAnd(null, null);
                        }
                        else if (operKind == NpgsqlTsQuery.NodeKind.Or)
                        {
                            node = new NpgsqlTsQueryOr(null, null);
                        }
                        else
                        {
                            PGUtil.ThrowIfReached();
                        }

                        InsertInTree(node);

                        _nodes.Push(new Tuple <NpgsqlTsQuery, int>(node, 2));
                        _nodes.Push(new Tuple <NpgsqlTsQuery, int>(node, 1));
                    }
                }
                else
                {
                    NpgsqlTsQueryLexeme.Weight weight = (NpgsqlTsQueryLexeme.Weight)_buf.ReadByte();
                    bool   prefix = _buf.ReadByte() != 0;
                    string str    = _buf.ReadNullTerminatedString();
                    InsertInTree(new NpgsqlTsQueryLexeme(str, weight, prefix));
                }

                _bytesLeft -= _buf.ReadPosition - readPos;
            }

            if (_nodes.Count != 0)
            {
                PGUtil.ThrowIfReached();
            }

            result = _value;
            _buf   = null;
            _nodes = null;
            _value = null;
            return(true);
        }
예제 #2
0
 public Task Write(NpgsqlTsQueryAnd value, NpgsqlWriteBuffer buf, NpgsqlLengthCache lengthCache, NpgsqlParameter parameter, bool async)
 => Write((NpgsqlTsQuery)value, buf, lengthCache, parameter, async);
예제 #3
0
        public override async ValueTask <NpgsqlTsQuery> Read(ReadBuffer buf, int len, bool async, FieldDescription fieldDescription = null)
        {
            await buf.Ensure(4, async);

            var numTokens = buf.ReadInt32();

            if (numTokens == 0)
            {
                return(new NpgsqlTsQueryEmpty());
            }

            _nodes = new Stack <Tuple <NpgsqlTsQuery, int> >();
            len   -= 4;

            for (var tokenPos = 0; tokenPos < numTokens; tokenPos++)
            {
                await buf.Ensure(Math.Min(len, MaxSingleTokenBytes), async);

                var readPos = buf.ReadPosition;

                var isOper = buf.ReadByte() == 2;
                if (isOper)
                {
                    var operKind = (NpgsqlTsQuery.NodeKind)buf.ReadByte();
                    if (operKind == NpgsqlTsQuery.NodeKind.Not)
                    {
                        var node = new NpgsqlTsQueryNot(null);
                        InsertInTree(node);
                        _nodes.Push(new Tuple <NpgsqlTsQuery, int>(node, 0));
                    }
                    else
                    {
                        NpgsqlTsQuery node = null;

                        switch (operKind)
                        {
                        case NpgsqlTsQuery.NodeKind.And:
                            node = new NpgsqlTsQueryAnd(null, null);
                            break;

                        case NpgsqlTsQuery.NodeKind.Or:
                            node = new NpgsqlTsQueryOr(null, null);
                            break;

                        default:
                            throw new InvalidOperationException($"Internal Npgsql bug: unexpected value {operKind} of enum {nameof(NpgsqlTsQuery.NodeKind)}. Please file a bug.");
                        }

                        InsertInTree(node);

                        _nodes.Push(new Tuple <NpgsqlTsQuery, int>(node, 2));
                        _nodes.Push(new Tuple <NpgsqlTsQuery, int>(node, 1));
                    }
                }
                else
                {
                    var weight = (NpgsqlTsQueryLexeme.Weight)buf.ReadByte();
                    var prefix = buf.ReadByte() != 0;
                    var str    = buf.ReadNullTerminatedString();
                    InsertInTree(new NpgsqlTsQueryLexeme(str, weight, prefix));
                }

                len -= buf.ReadPosition - readPos;
            }

            if (_nodes.Count != 0)
            {
                throw new InvalidOperationException("Internal Npgsql bug, please report.");
            }

            return(_value);
        }
예제 #4
0
 public int ValidateAndGetLength(NpgsqlTsQueryAnd value, ref NpgsqlLengthCache lengthCache, NpgsqlParameter parameter)
 => ValidateAndGetLength((NpgsqlTsQuery)value, ref lengthCache, parameter);