예제 #1
0
        internal override void WriteFully(WriteBuffer buf)
        {
            buf.WriteInt32(_length);
            buf.WriteInt32(ProtocolVersion3);

            foreach (var kv in _parameters)
            {
                buf.WriteBytesNullTerminated(kv.Key);
                buf.WriteBytesNullTerminated(kv.Value);
            }

            buf.WriteByte(0);
        }
예제 #2
0
        internal override void WriteFully(WriteBuffer buf)
        {
            buf.WriteInt32(_length);
            buf.WriteInt32(ProtocolVersion3);

            foreach (var kv in _parameters)
            {
                buf.WriteBytesNullTerminated(kv.Key);
                buf.WriteBytesNullTerminated(kv.Value);
            }

            buf.WriteByte(0);
        }
예제 #3
0
        internal override void WriteFully(WriteBuffer buf)
        {
            Contract.Requires(Name != null && Name.All(c => c < 128));

            buf.WriteByte(Code);
            buf.WriteInt32(Length - 1);
            buf.WriteByte((byte)StatementOrPortal);
            buf.WriteBytesNullTerminated(Encoding.ASCII.GetBytes(Name));
        }
예제 #4
0
        internal override void WriteFully(WriteBuffer buf)
        {
            Contract.Requires(Name != null && Name.All(c => c < 128));

            buf.WriteByte(Code);
            buf.WriteInt32(Length - 1);
            buf.WriteByte((byte)StatementOrPortal);
            buf.WriteBytesNullTerminated(Encoding.ASCII.GetBytes(Name));
        }
예제 #5
0
        internal override void WriteFully(WriteBuffer buf)
        {
            Contract.Requires(Portal != null && Portal.All(c => c < 128));

            var portalNameBytes = Portal == "" ? PGUtil.EmptyBuffer : Encoding.ASCII.GetBytes(Portal);
            buf.WriteByte(Code);
            buf.WriteInt32(Length - 1);
            buf.WriteBytesNullTerminated(portalNameBytes);
            buf.WriteInt32(MaxRows);
        }
예제 #6
0
        internal override void WriteFully(WriteBuffer buf)
        {
            Contract.Requires(Portal != null && Portal.All(c => c < 128));

            var portalNameBytes = Portal == "" ? PGUtil.EmptyBuffer : Encoding.ASCII.GetBytes(Portal);

            buf.WriteByte(Code);
            buf.WriteInt32(Length - 1);
            buf.WriteBytesNullTerminated(portalNameBytes);
            buf.WriteInt32(MaxRows);
        }
예제 #7
0
 internal override void WriteFully(WriteBuffer buf)
 {
     buf.WriteByte(Code);
     buf.WriteInt32(Length - 1);
     if (_errorMessageLen == 0)
     {
         buf.WriteByte(0);
     }
     else
     {
         buf.WriteBytesNullTerminated(PGUtil.UTF8Encoding.GetBytes(_errorMessage));
     }
 }
예제 #8
0
 internal override void WriteFully(WriteBuffer buf)
 {
     buf.WriteByte(Code);
     buf.WriteInt32(Length - 1);
     if (_errorMessageLen == 0)
     {
         buf.WriteByte(0);
     }
     else
     {
         buf.WriteBytesNullTerminated(PGUtil.UTF8Encoding.GetBytes(_errorMessage));
     }
 }
예제 #9
0
        internal bool Write(WriteBuffer buf, ref DirectBuffer directBuf)
        {
            Contract.Requires(Statement != null && Statement.All(c => c < 128));
            Contract.Requires(Portal != null && Portal.All(c => c < 128));

            switch (_state)
            {
            case State.Header:
                var formatCodesSum = InputParameters.Select(p => p.FormatCode).Sum(c => (int)c);
                _formatCodeListLength = formatCodesSum == 0 ? 0 : formatCodesSum == InputParameters.Count ? 1 : InputParameters.Count;
                var headerLength =
                    1 +                            // Message code
                    4 +                            // Message length
                    Portal.Length + 1 +
                    Statement.Length + 1 +
                    2;                             // Number of parameter format codes that follow

                if (buf.WriteSpaceLeft < headerLength)
                {
                    Contract.Assume(buf.Size >= headerLength, "Buffer too small for Bind header");
                    return(false);
                }

                foreach (var c in InputParameters.Select(p => p.LengthCache).Where(c => c != null))
                {
                    c.Rewind();
                }
                var messageLength = headerLength +
                                    2 * _formatCodeListLength +                                   // List of format codes
                                    2 +                                                           // Number of parameters
                                    4 * InputParameters.Count +                                   // Parameter lengths
                                    InputParameters.Select(p => p.ValidateAndGetLength()).Sum() + // Parameter values
                                    2 +                                                           // Number of result format codes
                                    2 * (UnknownResultTypeList?.Length ?? 1);                     // Result format codes

                buf.WriteByte(Code);
                buf.WriteInt32(messageLength - 1);
                buf.WriteBytesNullTerminated(Encoding.ASCII.GetBytes(Portal));
                buf.WriteBytesNullTerminated(Encoding.ASCII.GetBytes(Statement));
                buf.WriteInt16(_formatCodeListLength);
                _paramIndex = 0;

                _state = State.ParameterFormatCodes;
                goto case State.ParameterFormatCodes;

            case State.ParameterFormatCodes:
                // 0 length implicitly means all-text, 1 means all-binary, >1 means mix-and-match
                if (_formatCodeListLength == 1)
                {
                    if (buf.WriteSpaceLeft < 2)
                    {
                        return(false);
                    }
                    buf.WriteInt16((short)FormatCode.Binary);
                }
                else if (_formatCodeListLength > 1)
                {
                    for (; _paramIndex < InputParameters.Count; _paramIndex++)
                    {
                        if (buf.WriteSpaceLeft < 2)
                        {
                            return(false);
                        }
                        buf.WriteInt16((short)InputParameters[_paramIndex].FormatCode);
                    }
                }

                if (buf.WriteSpaceLeft < 2)
                {
                    return(false);
                }

                buf.WriteInt16(InputParameters.Count);
                _paramIndex = 0;

                _state = State.ParameterValues;
                goto case State.ParameterValues;

            case State.ParameterValues:
                if (!WriteParameters(buf, ref directBuf))
                {
                    return(false);
                }
                _state = State.ResultFormatCodes;
                goto case State.ResultFormatCodes;

            case State.ResultFormatCodes:
                if (UnknownResultTypeList != null)
                {
                    if (buf.WriteSpaceLeft < 2 + UnknownResultTypeList.Length * 2)
                    {
                        return(false);
                    }
                    buf.WriteInt16(UnknownResultTypeList.Length);
                    foreach (var t in UnknownResultTypeList)
                    {
                        buf.WriteInt16(t ? 0 : 1);
                    }
                }
                else
                {
                    if (buf.WriteSpaceLeft < 4)
                    {
                        return(false);
                    }
                    buf.WriteInt16(1);
                    buf.WriteInt16(AllResultTypesAreUnknown ? 0 : 1);
                }

                _state = State.Done;
                return(true);

            default:
                throw PGUtil.ThrowIfReached();
            }
        }
예제 #10
0
        internal bool Write(WriteBuffer buf, ref DirectBuffer directBuf)
        {
            Contract.Requires(Statement != null && Statement.All(c => c < 128));
            Contract.Requires(Portal != null && Portal.All(c => c < 128));

            switch (_state)
            {
                case State.Header:
                    var formatCodesSum = InputParameters.Select(p => p.FormatCode).Sum(c => (int)c);
                    _formatCodeListLength = formatCodesSum == 0 ? 0 : formatCodesSum == InputParameters.Count ? 1 : InputParameters.Count;
                    var headerLength =
                        1 +                        // Message code
                        4 +                        // Message length
                        Portal.Length + 1 +
                        Statement.Length + 1 +
                        2;                         // Number of parameter format codes that follow

                    if (buf.WriteSpaceLeft < headerLength)
                    {
                        Contract.Assume(buf.Size >= headerLength, "Buffer too small for Bind header");
                        return false;
                    }

                    foreach (var c in InputParameters.Select(p => p.LengthCache).Where(c => c != null))
                        c.Rewind();
                    var messageLength = headerLength +
                        2 * _formatCodeListLength + // List of format codes
                        2 +                         // Number of parameters
                        4 * InputParameters.Count +                                     // Parameter lengths
                        InputParameters.Select(p => p.ValidateAndGetLength()).Sum() +   // Parameter values
                        2 +                                                             // Number of result format codes
                        2 * (UnknownResultTypeList?.Length ?? 1);                       // Result format codes

                    buf.WriteByte(Code);
                    buf.WriteInt32(messageLength-1);
                    buf.WriteBytesNullTerminated(Encoding.ASCII.GetBytes(Portal));
                    buf.WriteBytesNullTerminated(Encoding.ASCII.GetBytes(Statement));
                    buf.WriteInt16(_formatCodeListLength);
                    _paramIndex = 0;

                    _state = State.ParameterFormatCodes;
                    goto case State.ParameterFormatCodes;

                case State.ParameterFormatCodes:
                    // 0 length implicitly means all-text, 1 means all-binary, >1 means mix-and-match
                    if (_formatCodeListLength == 1)
                    {
                        if (buf.WriteSpaceLeft < 2)
                            return false;
                        buf.WriteInt16((short)FormatCode.Binary);
                    }
                    else if (_formatCodeListLength > 1)
                        for (; _paramIndex < InputParameters.Count; _paramIndex++)
                        {
                            if (buf.WriteSpaceLeft < 2)
                                return false;
                            buf.WriteInt16((short)InputParameters[_paramIndex].FormatCode);
                        }
                    _state = State.ParameterCount;
                    goto case State.ParameterCount;

                case State.ParameterCount:
                    if (buf.WriteSpaceLeft < 2)
                        return false;

                    buf.WriteInt16(InputParameters.Count);
                    _paramIndex = 0;

                    _state = State.ParameterValues;
                    goto case State.ParameterValues;

                case State.ParameterValues:
                    if (!WriteParameters(buf, ref directBuf))
                        return false;
                    _state = State.ResultFormatCodes;
                    goto case State.ResultFormatCodes;

                case State.ResultFormatCodes:
                    if (UnknownResultTypeList != null)
                    {
                        if (buf.WriteSpaceLeft < 2 + UnknownResultTypeList.Length * 2)
                            return false;
                        buf.WriteInt16(UnknownResultTypeList.Length);
                        foreach (var t in UnknownResultTypeList)
                            buf.WriteInt16(t ? 0 : 1);
                    }
                    else
                    {
                        if (buf.WriteSpaceLeft < 4)
                            return false;
                        buf.WriteInt16(1);
                        buf.WriteInt16(AllResultTypesAreUnknown ? 0 : 1);
                    }

                    _state = State.Done;
                    return true;

                default:
                    throw PGUtil.ThrowIfReached();
            }
        }
예제 #11
0
        internal override bool Write(WriteBuffer buf)
        {
            Contract.Requires(Statement != null);

            switch (_state)
            {
            case State.WroteNothing:
                _statementNameBytes = Statement.Length == 0 ? PGUtil.EmptyBuffer : _encoding.GetBytes(Statement);
                _queryLen           = _encoding.GetByteCount(Query);
                if (buf.WriteSpaceLeft < 1 + 4 + _statementNameBytes.Length + 1)
                {
                    return(false);
                }

                var messageLength =
                    1 +                             // Message code
                    4 +                             // Length
                    _statementNameBytes.Length +
                    1 +                             // Null terminator
                    _queryLen +
                    1 +                             // Null terminator
                    2 +                             // Number of parameters
                    ParameterTypeOIDs.Count * 4;

                buf.WriteByte(Code);
                buf.WriteInt32(messageLength - 1);
                buf.WriteBytesNullTerminated(_statementNameBytes);
                goto case State.WroteHeader;

            case State.WroteHeader:
                _state = State.WroteHeader;

                if (_queryLen <= buf.WriteSpaceLeft)
                {
                    buf.WriteString(Query);
                    goto case State.WroteQuery;
                }

                if (_queryLen <= buf.Size)
                {
                    // String can fit entirely in an empty buffer. Flush and retry rather than
                    // going into the partial writing flow below (which requires ToCharArray())
                    return(false);
                }

                _queryChars = Query.ToCharArray();
                _charPos    = 0;
                goto case State.WritingQuery;

            case State.WritingQuery:
                _state = State.WritingQuery;
                int  charsUsed;
                bool completed;
                buf.WriteStringChunked(_queryChars, _charPos, _queryChars.Length - _charPos, true,
                                       out charsUsed, out completed);
                if (!completed)
                {
                    _charPos += charsUsed;
                    return(false);
                }
                goto case State.WroteQuery;

            case State.WroteQuery:
                _state = State.WroteQuery;
                if (buf.WriteSpaceLeft < 1 + 2)
                {
                    return(false);
                }
                buf.WriteByte(0);     // Null terminator for the query
                buf.WriteInt16((short)ParameterTypeOIDs.Count);
                goto case State.WritingParameterTypes;

            case State.WritingParameterTypes:
                _state = State.WritingParameterTypes;
                for (; _parameterTypePos < ParameterTypeOIDs.Count; _parameterTypePos++)
                {
                    if (buf.WriteSpaceLeft < 4)
                    {
                        return(false);
                    }
                    buf.WriteInt32((int)ParameterTypeOIDs[_parameterTypePos]);
                }

                _state = State.WroteAll;
                return(true);

            default:
                throw PGUtil.ThrowIfReached();
            }
        }
예제 #12
0
        internal override bool Write(WriteBuffer buf)
        {
            Contract.Requires(Statement != null);

            switch (_state)
            {
                case State.WroteNothing:
                    _statementNameBytes = Statement.Length == 0 ? PGUtil.EmptyBuffer : _encoding.GetBytes(Statement);
                    _queryLen = _encoding.GetByteCount(Query);
                    if (buf.WriteSpaceLeft < 1 + 4 + _statementNameBytes.Length + 1) {
                        return false;
                    }

                    var messageLength =
                        1 +                         // Message code
                        4 +                         // Length
                        _statementNameBytes.Length +
                        1 +                         // Null terminator
                        _queryLen +
                        1 +                         // Null terminator
                        2 +                         // Number of parameters
                        ParameterTypeOIDs.Count * 4;

                    buf.WriteByte(Code);
                    buf.WriteInt32(messageLength - 1);
                    buf.WriteBytesNullTerminated(_statementNameBytes);
                    goto case State.WroteHeader;

                case State.WroteHeader:
                    _state = State.WroteHeader;

                    if (_queryLen <= buf.WriteSpaceLeft) {
                        buf.WriteString(Query);
                        goto case State.WroteQuery;
                    }

                    if (_queryLen <= buf.Size) {
                        // String can fit entirely in an empty buffer. Flush and retry rather than
                        // going into the partial writing flow below (which requires ToCharArray())
                        return false;
                    }

                    _queryChars = Query.ToCharArray();
                    _charPos = 0;
                    goto case State.WritingQuery;

                case State.WritingQuery:
                    _state = State.WritingQuery;
                    int charsUsed;
                    bool completed;
                    buf.WriteStringChunked(_queryChars, _charPos, _queryChars.Length - _charPos, true,
                                           out charsUsed, out completed);
                    if (!completed)
                    {
                        _charPos += charsUsed;
                        return false;
                    }
                    goto case State.WroteQuery;

                case State.WroteQuery:
                    _state = State.WroteQuery;
                    if (buf.WriteSpaceLeft < 1 + 2) {
                        return false;
                    }
                    buf.WriteByte(0); // Null terminator for the query
                    buf.WriteInt16((short)ParameterTypeOIDs.Count);
                    goto case State.WritingParameterTypes;

                case State.WritingParameterTypes:
                    _state = State.WritingParameterTypes;
                    for (; _parameterTypePos < ParameterTypeOIDs.Count; _parameterTypePos++)
                    {
                        if (buf.WriteSpaceLeft < 4)
                        {
                            return false;
                        }
                        buf.WriteInt32((int)ParameterTypeOIDs[_parameterTypePos]);
                    }

                    _state = State.WroteAll;
                    return true;

                default:
                    throw PGUtil.ThrowIfReached();
            }
        }