public override void Write(decimal value, NpgsqlWriteBuffer buf, NpgsqlParameter parameter)
        {
            if (value == 0M)
            {
                buf.WriteInt64(0);
                return;
            }

            var negative = value < 0;

            if (negative)
            {
                value = -value;
            }

            int numGroups, weight, fractionDigits;

            GetNumericHeader(value, out numGroups, out weight, out fractionDigits);

            buf.WriteInt16(numGroups);
            buf.WriteInt16(weight);
            buf.WriteInt16(negative ? 0x4000 : 0x0000);
            buf.WriteInt16(fractionDigits);
            for (int i = 0, pos = weight + 7; i < numGroups; i++, pos--)
            {
                buf.WriteInt16((ushort)(value / Decimals[pos]));
                value %= Decimals[pos];
            }
        }
예제 #2
0
        /// <inheritdoc />
        public override void Write(Guid value, NpgsqlWriteBuffer buf, NpgsqlParameter?parameter)
        {
            var raw = new GuidRaw(value);

            buf.WriteInt32(raw.Data1);
            buf.WriteInt16(raw.Data2);
            buf.WriteInt16(raw.Data3);
            buf.WriteInt64(raw.Data4, BitConverter.IsLittleEndian);
        }
예제 #3
0
        public override void Write(Guid value, NpgsqlWriteBuffer buf, NpgsqlParameter parameter)
        {
            // TODO: Allocation... investigate alternatives?
            var bytes = value.ToByteArray();

            buf.WriteInt32(BitConverter.ToInt32(bytes, 0));
            buf.WriteInt16(BitConverter.ToInt16(bytes, 4));
            buf.WriteInt16(BitConverter.ToInt16(bytes, 6));
            buf.WriteBytes(bytes, 8, 8);
        }
예제 #4
0
        /// <inheritdoc />
        public override void Write(decimal value, NpgsqlWriteBuffer buf, NpgsqlParameter?parameter)
        {
            var          weight     = 0;
            var          groupCount = 0;
            Span <short> groups     = stackalloc short[MaxGroupCount];

            var raw = new DecimalRaw(value);

            if (raw.Low != 0 || raw.Mid != 0 || raw.High != 0)
            {
                var scale = raw.Scale;
                weight = -scale / MaxGroupScale - 1;

                uint remainder;
                var  scaleChunk = scale % MaxGroupScale;
                if (scaleChunk > 0)
                {
                    var divisor    = DecimalRaw.Powers10[scaleChunk];
                    var multiplier = DecimalRaw.Powers10[MaxGroupScale - scaleChunk];
                    remainder = DecimalRaw.Divide(ref raw, divisor) * multiplier;

                    if (remainder != 0)
                    {
                        weight--;
                        goto WriteGroups;
                    }
                }

                while ((remainder = DecimalRaw.Divide(ref raw, MaxGroupSize)) == 0)
                {
                    weight++;
                }

WriteGroups:
                groups[groupCount++] = (short)remainder;

                while (raw.Low != 0 || raw.Mid != 0 || raw.High != 0)
                {
                    groups[groupCount++] = (short)DecimalRaw.Divide(ref raw, MaxGroupSize);
                }
            }

            buf.WriteInt16(groupCount);
            buf.WriteInt16(groupCount + weight);
            buf.WriteInt16(raw.Negative ? SignNegative : SignPositive);
            buf.WriteInt16(raw.Scale);

            while (groupCount > 0)
            {
                buf.WriteInt16(groups[--groupCount]);
            }
        }
예제 #5
0
        public void Write(BigInteger value, NpgsqlWriteBuffer buf, NpgsqlParameter parameter)
        {
            var sig    = value.Sign;
            var groups = new List <short>(MaxGroupCount);
            var weight = 0;

            var raw = sig * value;

            if (!raw.IsZero)
            {
                weight = -1;

                BigInteger remainder;
                do
                {
                    remainder = raw % MaxGroupSize;
                    raw       = (raw - remainder) / MaxGroupSize;

                    if (!remainder.IsZero)
                    {
                        break;
                    }

                    weight++;
                } while (true);

                groups.Add((short)remainder);

                while (!raw.IsZero)
                {
                    remainder = raw % MaxGroupSize;
                    raw       = (raw - remainder) / MaxGroupSize;
                    groups.Add((short)remainder);
                }
            }

            buf.WriteInt16(groups.Count);
            buf.WriteInt16(groups.Count + weight);
            buf.WriteInt16(sig > 0 ? SignPositive : SignNegative);
            buf.WriteInt16(0);

            for (var i = groups.Count - 1; i >= 0; i--)
            {
                buf.WriteInt16(groups[i]);
            }
        }
예제 #6
0
    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++;
    }
예제 #7
0
        internal PgServerMock WriteRowDescription(params FieldDescription[] fields)
        {
            CheckDisposed();

            _writeBuffer.WriteByte((byte)BackendMessageCode.RowDescription);
            _writeBuffer.WriteInt32(4 + 2 + fields.Sum(f => Encoding.GetByteCount(f.Name) + 1 + 18));
            _writeBuffer.WriteInt16(fields.Length);

            foreach (var field in fields)
            {
                _writeBuffer.WriteNullTerminatedString(field.Name);
                _writeBuffer.WriteUInt32(field.TableOID);
                _writeBuffer.WriteInt16(field.ColumnAttributeNumber);
                _writeBuffer.WriteUInt32(field.TypeOID);
                _writeBuffer.WriteInt16(field.TypeSize);
                _writeBuffer.WriteInt32(field.TypeModifier);
                _writeBuffer.WriteInt16((short)field.FormatCode);
            }

            return(this);
        }
예제 #8
0
        /// <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);
                }
            }
        }
예제 #9
0
파일: ParseMessage.cs 프로젝트: zhnc/npgsql
        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);
            }
        }
예제 #10
0
 public void Write(string value, NpgsqlWriteBuffer buf, NpgsqlParameter parameter)
 {
     Debug.Assert(parameter != null);
     buf.WriteInt16((short)parameter.ConvertedValue);
 }
예제 #11
0
        internal override async Task Write(NpgsqlWriteBuffer buf, bool async)
        {
            Debug.Assert(Statement != null && Statement.All(c => c < 128));
            Debug.Assert(Portal != null && Portal.All(c => c < 128));

            var headerLength =
                1 +                        // Message code
                4 +                        // Message length
                1 +                        // Portal is always empty (only a null terminator)
                Statement.Length + 1 +
                2;                         // Number of parameter format codes that follow

            if (buf.WriteSpaceLeft < headerLength)
            {
                Debug.Assert(buf.Size >= headerLength, "Buffer too small for Bind header");
                await buf.Flush(async);
            }

            var formatCodesSum = 0;
            var paramsLength   = 0;

            foreach (var p in InputParameters)
            {
                formatCodesSum += (int)p.FormatCode;
                p.LengthCache?.Rewind();
                paramsLength += p.ValidateAndGetLength();
            }

            var formatCodeListLength = formatCodesSum == 0 ? 0 : formatCodesSum == InputParameters.Count ? 1 : InputParameters.Count;

            var messageLength = headerLength +
                                2 * formatCodeListLength +                // List of format codes
                                2 +                                       // Number of parameters
                                4 * InputParameters.Count +               // Parameter lengths
                                paramsLength +                            // Parameter values
                                2 +                                       // Number of result format codes
                                2 * (UnknownResultTypeList?.Length ?? 1); // Result format codes

            buf.WriteByte(Code);
            buf.WriteInt32(messageLength - 1);
            Debug.Assert(Portal == string.Empty);
            buf.WriteByte(0);  // Portal is always empty

            buf.WriteNullTerminatedString(Statement);
            buf.WriteInt16(formatCodeListLength);

            // 0 length implicitly means all-text, 1 means all-binary, >1 means mix-and-match
            if (formatCodeListLength == 1)
            {
                if (buf.WriteSpaceLeft < 2)
                {
                    await buf.Flush(async);
                }
                buf.WriteInt16((short)FormatCode.Binary);
            }
            else if (formatCodeListLength > 1)
            {
                foreach (var p in InputParameters)
                {
                    if (buf.WriteSpaceLeft < 2)
                    {
                        await buf.Flush(async);
                    }
                    buf.WriteInt16((short)p.FormatCode);
                }
            }

            if (buf.WriteSpaceLeft < 2)
            {
                await buf.Flush(async);
            }

            buf.WriteInt16(InputParameters.Count);

            foreach (var param in InputParameters)
            {
                param.LengthCache?.Rewind();
                await param.WriteWithLength(buf, async);
            }

            if (UnknownResultTypeList != null)
            {
                if (buf.WriteSpaceLeft < 2 + UnknownResultTypeList.Length * 2)
                {
                    await buf.Flush(async);
                }
                buf.WriteInt16(UnknownResultTypeList.Length);
                foreach (var t in UnknownResultTypeList)
                {
                    buf.WriteInt16(t ? 0 : 1);
                }
            }
            else
            {
                if (buf.WriteSpaceLeft < 4)
                {
                    await buf.Flush(async);
                }
                buf.WriteInt16(1);
                buf.WriteInt16(AllResultTypesAreUnknown ? 0 : 1);
            }
        }
예제 #12
0
 /// <inheritdoc />
 public void Write(float value, NpgsqlWriteBuffer buf, NpgsqlParameter?parameter) => buf.WriteInt16((short)value);
예제 #13
0
 /// <inheritdoc />
 public void Write(sbyte value, NpgsqlWriteBuffer buf, NpgsqlParameter?parameter) => buf.WriteInt16(value);
예제 #14
0
 /// <inheritdoc />
 public override void Write(short value, NpgsqlWriteBuffer buf, NpgsqlParameter?parameter) => buf.WriteInt16(value);
예제 #15
0
파일: Int16Handler.cs 프로젝트: zhnc/npgsql
 public void Write(double value, NpgsqlWriteBuffer buf, NpgsqlParameter parameter)
 => buf.WriteInt16(checked ((short)value));
예제 #16
0
파일: Int16Handler.cs 프로젝트: zhnc/npgsql
 public void Write(decimal value, NpgsqlWriteBuffer buf, NpgsqlParameter parameter)
 => buf.WriteInt16((short)value);
예제 #17
0
        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
                    {
                        if (node.Kind == NpgsqlTsQuery.NodeKind.Phrase)
                        {
                            buf.WriteInt16(((NpgsqlTsQueryFollowedBy)node).Distance);
                        }

                        _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();
        }