Ejemplo n.º 1
0
        public void PrepareWrite(object value, NpgsqlBuffer buf, LengthCache lengthCache, NpgsqlParameter parameter = null)
        {
            _buf     = buf;
            _charPos = -1;
            _byteLen = lengthCache.GetLast();

            _str = value as string;
            if (_str != null)
            {
                _charLen = parameter == null || parameter.Size == 0 || parameter.Size >= _str.Length ? _str.Length : parameter.Size;
                return;
            }

            _chars = value as char[];
            if (_chars != null)
            {
                _charLen = parameter == null || parameter.Size == 0 || parameter.Size >= _chars.Length ? _chars.Length : parameter.Size;
                return;
            }

            throw PGUtil.ThrowIfReached();
        }
Ejemplo n.º 2
0
        public override bool Write(ref DirectBuffer directBuf)
        {
            var bitArray = _value as BitArray;

            if (bitArray != null)
            {
                return(WriteBitArray(bitArray));
            }

            if (_value is bool)
            {
                return(WriteBool((bool)_value));
            }

            var str = _value as string;

            if (str != null)
            {
                return(WriteString(str));
            }

            throw PGUtil.ThrowIfReached($"Bad type {_value.GetType()} some made its way into BitStringHandler.Write()");
        }
Ejemplo n.º 3
0
        public bool Write(ref byte[] directBuf)
        {
            var bitArray = _value as BitArray;

            if (bitArray != null)
            {
                return(WriteBitArray(bitArray));
            }

            if (_value is bool)
            {
                return(WriteBool((bool)_value));
            }

            var str = _value as string;

            if (str != null)
            {
                return(WriteString(str));
            }

            throw PGUtil.ThrowIfReached(String.Format("Bad type {0} some made its way into BitStringHandler.Write()", _value.GetType()));
        }
Ejemplo n.º 4
0
        public NpgsqlDate AddMonths(int months)
        {
            switch (_type)
            {
            case InternalType.Infinity:
                return(Infinity);

            case InternalType.NegativeInfinity:
                return(NegativeInfinity);

            case InternalType.Finite:
                break;

            default:
                throw PGUtil.ThrowIfReached();
            }

            int newYear  = Year;
            int newMonth = Month + months;

            while (newMonth > 12)
            {
                newMonth -= 12;
                newYear  += 1;
            }
            ;
            while (newMonth < 1)
            {
                newMonth += 12;
                newYear  -= 1;
            }
            ;
            int maxDay = (IsLeap(newYear) ? LeapYearMaxes : CommonYearMaxes)[newMonth - 1];
            int newDay = Day > maxDay ? maxDay : Day;

            return(new NpgsqlDate(newYear, newMonth, newDay));
        }
Ejemplo n.º 5
0
        /// <summary>
        /// Converts the value of the current <see cref="NpgsqlDateTime"/> object to local time.
        /// </summary>
        /// <remarks>
        /// See the MSDN documentation for DateTime.ToLocalTime().
        /// <b>Note:</b> this method <b>only</b> takes into account the time zone's base offset, and does
        /// <b>not</b> respect daylight savings. See https://github.com/npgsql/npgsql/pull/684 for more
        /// details.
        /// </remarks>
        public NpgsqlDateTime ToLocalTime()
        {
            switch (_type)
            {
            case InternalType.FiniteUnspecified:
            // Treat as UTC
            case InternalType.FiniteUtc:
                if (_date.DaysSinceEra >= 1 && _date.DaysSinceEra <= MaxDateTimeDay - 1)
                {
                    // Day between 0001-01-02 and 9999-12-30, so we can use DateTime and it will always succeed
                    return(new NpgsqlDateTime(TimeZoneInfo.ConvertTimeFromUtc(new DateTime(this.DateTime.Ticks, DateTimeKind.Utc), TimeZoneInfo.Local)));
                }
                // Else there are no DST rules available in the system for outside the DateTime range, so just use the base offset
                return(new NpgsqlDateTime(Add(TimeZoneInfo.Local.BaseUtcOffset).Ticks, DateTimeKind.Local));

            case InternalType.FiniteLocal:
            case InternalType.Infinity:
            case InternalType.NegativeInfinity:
                return(this);

            default:
                throw PGUtil.ThrowIfReached();
            }
        }
Ejemplo n.º 6
0
        internal override bool Write(NpgsqlBuffer buf, ref DirectBuffer directBuf)
        {
            Contract.Requires(Statement != null && Statement.All(c => c < 128));

            switch (_state)
            {
            case State.WroteNothing:
                _statementNameBytes = PGUtil.UTF8Encoding.GetBytes(Statement);
                _queryLen           = PGUtil.UTF8Encoding.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();
            }
        }
Ejemplo n.º 7
0
        public bool Write <TElement>(ref DirectBuffer directBuf)
        {
            switch (_writeState)
            {
            case WriteState.WroteNothing:
                var len =
                    4 +                   // ndim
                    4 +                   // has_nulls
                    4 +                   // element_oid
                    _dimensions * 8;      // dim (4) + lBound (4)

                if (_buf.WriteSpaceLeft < len)
                {
                    Contract.Assume(_buf.Size >= len, "Buffer too small for header");
                    return(false);
                }
                _buf.WriteInt32(_dimensions);
                _buf.WriteInt32(_hasNulls ? 1 : 0);     // Actually not used by backend
                _buf.WriteInt32((int)ElementHandler.OID);
                var asArray = _writeValue as Array;
                if (asArray != null)
                {
                    for (var i = 0; i < _dimensions; i++)
                    {
                        _buf.WriteInt32(asArray.GetLength(i));
                        _buf.WriteInt32(LowerBound);      // We don't map .NET lower bounds to PG
                    }
                }
                else
                {
                    _buf.WriteInt32(_writeValue.Count);
                    _buf.WriteInt32(LowerBound);      // We don't map .NET lower bounds to PG
                    _enumerator = _writeValue.GetEnumerator();
                }

                var asGeneric = _writeValue as IList <TElement>;
                _enumerator = asGeneric != null?asGeneric.GetEnumerator() : _writeValue.GetEnumerator();

                if (!_enumerator.MoveNext())
                {
                    goto case WriteState.Cleanup;
                }

                _writeState = WriteState.WritingElements;
                goto case WriteState.WritingElements;

            case WriteState.WritingElements:
                var genericEnumerator = _enumerator as IEnumerator <TElement>;
                if (genericEnumerator != null)
                {
                    // TODO: Actually call the element writer generically...!
                    do
                    {
                        if (!WriteSingleElement(genericEnumerator.Current, ref directBuf))
                        {
                            return(false);
                        }
                    } while (genericEnumerator.MoveNext());
                }
                else
                {
                    do
                    {
                        if (!WriteSingleElement(_enumerator.Current, ref directBuf))
                        {
                            return(false);
                        }
                    } while (_enumerator.MoveNext());
                }
                goto case WriteState.Cleanup;

            case WriteState.Cleanup:
                _writeValue = null;
                _buf        = null;
                _parameter  = null;
                _writeState = WriteState.NeedPrepare;
                return(true);

            default:
                throw PGUtil.ThrowIfReached();
            }
        }
Ejemplo n.º 8
0
        public bool Read(out IDictionary <string, string> result)
        {
            result = null;
            switch (_state)
            {
            case State.Count:
                if (_buf.ReadBytesLeft < 4)
                {
                    return(false);
                }
                _numElements = _buf.ReadInt32();
                _value       = new Dictionary <string, string>(_numElements);
                if (_numElements == 0)
                {
                    CleanupState();
                    return(true);
                }
                goto case State.KeyLen;

            case State.KeyLen:
                _state = State.KeyLen;
                if (_buf.ReadBytesLeft < 4)
                {
                    return(false);
                }
                var keyLen = _buf.ReadInt32();
                Contract.Assume(keyLen != -1);
                _textHandler.PrepareRead(_buf, _fieldDescription, keyLen);
                goto case State.KeyData;

            case State.KeyData:
                _state = State.KeyData;
                if (!_textHandler.Read(out _key))
                {
                    return(false);
                }
                goto case State.ValueLen;

            case State.ValueLen:
                _state = State.ValueLen;
                if (_buf.ReadBytesLeft < 4)
                {
                    return(false);
                }
                var valueLen = _buf.ReadInt32();
                if (valueLen == -1)
                {
                    _value[_key] = null;
                    if (--_numElements == 0)
                    {
                        result = _value;
                        CleanupState();
                        return(true);
                    }
                    goto case State.KeyLen;
                }
                _textHandler.PrepareRead(_buf, _fieldDescription, valueLen);
                goto case State.ValueData;

            case State.ValueData:
                _state = State.ValueData;
                string value;
                if (!_textHandler.Read(out value))
                {
                    return(false);
                }
                _value[_key] = value;
                if (--_numElements == 0)
                {
                    result = _value;
                    CleanupState();
                    return(true);
                }
                goto case State.KeyLen;

            default:
                throw PGUtil.ThrowIfReached();
            }
        }
Ejemplo n.º 9
0
 public override int GetHashCode()
 {
     return(PGUtil.RotateShift(addr.GetHashCode(), mask % 32));
 }
Ejemplo n.º 10
0
        private Object FastpathV3(Int32 fnid, Boolean resulttype, FastpathArg[] args)
        {
            // give  thread safety
            lock (stream)
            {
                // send the function call

                {
                    Int32 l_msgLen = 0;
                    l_msgLen += 16;
                    for (Int32 i = 0; i < args.Length; i++)
                    {
                        l_msgLen += args[i].SendSize();
                    }

                    stream.WriteByte((Byte)'F');
                    PGUtil.WriteInt32(stream, l_msgLen);
                    PGUtil.WriteInt32(stream, fnid);
                    PGUtil.WriteInt16(stream, 1);
                    PGUtil.WriteInt16(stream, 1);
                    PGUtil.WriteInt16(stream, (short)args.Length);

                    for (Int32 i = 0; i < args.Length; i++)
                    {
                        args[i].Send(stream);
                    }

                    PGUtil.WriteInt16(stream, 1);

                    // This is needed, otherwise data can be lost
                    stream.Flush();
                }


                // Now handle the result

                // Now loop, reading the results
                Object    result = null; // our result
                Exception error  = null;
                Int32     c;
                Boolean   l_endQuery   = false;
                Byte[]    input_buffer = new Byte[512];

                while (!l_endQuery)
                {
                    c = (Char)stream.ReadByte();

                    switch (c)
                    {
                    case 'A':   // Asynchronous Notify
                        Int32  msglen = PGUtil.ReadInt32(stream, input_buffer);
                        Int32  pid    = PGUtil.ReadInt32(stream, input_buffer);
                        String msg    = PGUtil.ReadString(stream, conn.Connector.Encoding);
                        PGUtil.ReadString(stream, conn.Connector.Encoding);
                        String param = PGUtil.ReadString(stream, conn.Connector.Encoding);

                        conn.Connector.CheckErrorsAndNotifications();
                        break;

                    //------------------------------
                    // Error message returned
                    case 'E':
                        NpgsqlError e = new NpgsqlError(conn.BackendProtocolVersion);
                        e.ReadFromStream(stream, conn.Connector.Encoding);
                        throw new NpgsqlException(e.ToString());

                    //------------------------------
                    // Notice from backend
                    case 'N':
                        Int32 l_nlen = PGUtil.ReadInt32(stream, input_buffer);

                        NpgsqlError e1 = new NpgsqlError(conn.BackendProtocolVersion);
                        e1.ReadFromStream(stream, conn.Connector.Encoding);
                        conn.Connector.Mediator.Errors.Add(e1);

                        break;

                    case 'V':
                        Int32 l_msgLen   = PGUtil.ReadInt32(stream, input_buffer);
                        Int32 l_valueLen = PGUtil.ReadInt32(stream, input_buffer);

                        if (l_valueLen == -1)
                        {
                            //null value
                        }
                        else if (l_valueLen == 0)
                        {
                            result = new Byte[0];
                        }
                        else
                        {
                            // Return an Integer if
                            if (resulttype)
                            {
                                result = PGUtil.ReadInt32(stream, input_buffer);
                            }
                            else
                            {
                                Byte[] buf = new Byte[l_valueLen];

                                Int32 bytes_from_stream = 0;
                                Int32 total_bytes_read  = 0;
                                Int32 size = l_valueLen;
                                do
                                {
                                    bytes_from_stream = stream.Read(buf, total_bytes_read, size);
                                    total_bytes_read += bytes_from_stream;
                                    size -= bytes_from_stream;
                                }while(size > 0);

                                result = buf;
                            }
                        }
                        break;

                    case 'Z':
                        //TODO: use size better
                        if (PGUtil.ReadInt32(stream, input_buffer) != 5)
                        {
                            throw new NpgsqlException("Received Z");
                        }
                        //TODO: handle transaction status
                        Char l_tStatus = (Char)stream.ReadByte();
                        l_endQuery = true;
                        break;

                    default:
                        throw new NpgsqlException("postgresql.fp.protocol received " + c.ToString());
                    }
                }

                if (error != null)
                {
                    throw error;
                }

                return(result);
            }
        }
Ejemplo n.º 11
0
 public override int GetHashCode()
 {
     return(X.GetHashCode() ^ PGUtil.RotateShift(Y.GetHashCode(), sizeof(int) / 2));
 }
Ejemplo n.º 12
0
        public virtual void Write(object value, NpgsqlBuffer buf)
        {
            NpgsqlDateTime ts;

            if (value is NpgsqlDateTime)
            {
                ts = (NpgsqlDateTime)value;
                if (!ts.IsFinite)
                {
                    if (ts.IsInfinity)
                    {
                        buf.WriteInt64(Int64.MaxValue);
                        return;
                    }

                    if (ts.IsNegativeInfinity)
                    {
                        buf.WriteInt64(Int64.MinValue);
                        return;
                    }

                    throw PGUtil.ThrowIfReached();
                }
            }
            else if (value is DateTime)
            {
                var dt = (DateTime)value;
                if (_convertInfinityDateTime)
                {
                    if (dt == DateTime.MaxValue)
                    {
                        buf.WriteInt64(Int64.MaxValue);
                        return;
                    }
                    else if (dt == DateTime.MinValue)
                    {
                        buf.WriteInt64(Int64.MinValue);
                        return;
                    }
                }
                ts = new NpgsqlDateTime(dt);
            }
            else if (value is DateTimeOffset)
            {
                ts = new NpgsqlDateTime(((DateTimeOffset)value).DateTime);
            }
            else if (value is string)
            {
                // TODO: Decide what to do with this
                throw new InvalidOperationException("String DateTimes are not allowed, use DateTime instead.");
            }
            else
            {
                throw new InvalidCastException();
            }

            var uSecsTime = ts.Time.Ticks / 10;

            if (ts >= new NpgsqlDateTime(2000, 1, 1, 0, 0, 0))
            {
                var uSecsDate = (ts.Date.DaysSinceEra - 730119) * 86400000000L;
                buf.WriteInt64(uSecsDate + uSecsTime);
            }
            else
            {
                var uSecsDate = (730119 - ts.Date.DaysSinceEra) * 86400000000L;
                buf.WriteInt64(-(uSecsDate - uSecsTime));
            }
        }
Ejemplo n.º 13
0
        /// <summary>
        /// Recursively populates an array from PB binary data representation.
        /// </summary>
        private void PopulateArrayFromBinaryArray(NpgsqlBackendTypeInfo TypeInfo, byte[] backendData, Int32 fieldValueSize, Int32 TypeModifier, ref int dataOffset, int[] dimLengths, int[] dimLBounds, int dimOffset, Array dst, int[] dstOffsets)
        {
            int dimensionLBound = dimLBounds[dimOffset];
            int end             = dimensionLBound + dimLengths[dimOffset];

            if (dimOffset < dimLengths.Length - 1)
            {
                // Drill down recursively until we hit a single dimension array.
                for (int i = dimensionLBound; i < end; i++)
                {
                    dstOffsets[dimOffset] = i;

                    PopulateArrayFromBinaryArray(TypeInfo, backendData, fieldValueSize, TypeModifier, ref dataOffset, dimLengths, dimLBounds, dimOffset + 1, dst, dstOffsets);
                }
            }
            else
            {
                // Populate a single dimension array.
                for (int i = dimensionLBound; i < end; i++)
                {
                    // Sanity check.
                    if (backendData.Length < dataOffset + 4)
                    {
                        throw new NpgsqlException("Out of backend data while reading binary array");
                    }

                    int elementLength;

                    // Each element consists of an int length identifier, followed by that many bytes of raw data.
                    // Length -1 indicates a NULL value, and is naturally followed by no data.
                    elementLength = PGUtil.ReadInt32(backendData, dataOffset);
                    dataOffset   += 4;

                    if (elementLength == -1)
                    {
                        // This currently throws an exception on value types.
                        dst.SetValue(DBNull.Value, dstOffsets);
                    }
                    else
                    {
                        // Sanity check.
                        if (backendData.Length < dataOffset + elementLength)
                        {
                            throw new NpgsqlException("Out of backend data while reading binary array");
                        }

                        byte[] elementBinary;

                        // Get element data from backend data.
                        elementBinary = PGUtil.ReadBytes(backendData, dataOffset, elementLength);

                        object elementNative;

                        elementNative = _elementConverter.ConvertBackendBinaryToNative(elementBinary, fieldValueSize, TypeModifier);

                        dstOffsets[dimOffset] = i;
                        dst.SetValue(elementNative, dstOffsets);

                        dataOffset += elementLength;
                    }
                }
            }
        }
Ejemplo n.º 14
0
        public override bool Read([CanBeNull] out object[] result)
        {
            result = null;

            if (_fieldIndex == -1)
            {
                if (_readBuf.ReadBytesLeft < 4)
                {
                    return(false);
                }
                _fieldCount = _readBuf.ReadInt32();
                _value      = new object[_fieldCount];
                _fieldIndex = 0;
            }

            for (; _fieldIndex < _fieldCount; _fieldIndex++)
            {
                // Not yet started reading the field.
                // Read the type OID, then the length.
                if (_fieldLen == -1)
                {
                    if (_readBuf.ReadBytesLeft < 8)
                    {
                        return(false);
                    }
                    var typeOID = _readBuf.ReadInt32();
                    _fieldLen = _readBuf.ReadInt32();
                    if (_fieldLen == -1)
                    {
                        // Null field, simply skip it and leave at default
                        continue;
                    }
                    _fieldHandler = _registry[typeOID];
                }

                // Get the field's type handler and read the value
                object fieldValue;
                if (_fieldHandler is ISimpleTypeHandler)
                {
                    var asSimpleReader = (ISimpleTypeHandler)_fieldHandler;
                    if (_readBuf.ReadBytesLeft < _fieldLen)
                    {
                        return(false);
                    }
                    fieldValue = asSimpleReader.ReadAsObject(_readBuf, _fieldLen);
                }
                else if (_fieldHandler is IChunkingTypeHandler)
                {
                    var asChunkingReader = (IChunkingTypeHandler)_fieldHandler;
                    asChunkingReader.PrepareRead(_readBuf, _fieldLen);
                    if (!asChunkingReader.ReadAsObject(out fieldValue))
                    {
                        return(false);
                    }
                }
                else
                {
                    throw PGUtil.ThrowIfReached();
                }

                _value[_fieldIndex] = fieldValue;
                _fieldLen           = -1;
            }

            result        = _value;
            _fieldHandler = null;
            return(true);
        }
Ejemplo n.º 15
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();
            }
        }
Ejemplo n.º 16
0
        public override int GetHashCode()
        {
            int ret = 266370105;  //seed with something other than zero to make paths of all zeros hash differently.

            return(PGUtil.RotateShift(macAddr.GetHashCode(), ret));
        }
Ejemplo n.º 17
0
        public override void Write(object value, WriteBuffer buf, NpgsqlParameter parameter)
        {
            if (parameter != null && parameter.ConvertedValue != null)
            {
                value = parameter.ConvertedValue;
            }

            NpgsqlDateTime ts;

            if (value is NpgsqlDateTime)
            {
                ts = (NpgsqlDateTime)value;
                if (!ts.IsFinite)
                {
                    if (ts.IsInfinity)
                    {
                        buf.WriteInt64(Int64.MaxValue);
                        return;
                    }

                    if (ts.IsNegativeInfinity)
                    {
                        buf.WriteInt64(Int64.MinValue);
                        return;
                    }

                    throw PGUtil.ThrowIfReached();
                }
            }
            else if (value is DateTime)
            {
                var dt = (DateTime)value;
                if (_convertInfinityDateTime)
                {
                    if (dt == DateTime.MaxValue)
                    {
                        buf.WriteInt64(Int64.MaxValue);
                        return;
                    }
                    else if (dt == DateTime.MinValue)
                    {
                        buf.WriteInt64(Int64.MinValue);
                        return;
                    }
                }
                ts = new NpgsqlDateTime(dt);
            }
            else if (value is DateTimeOffset)
            {
                ts = new NpgsqlDateTime(((DateTimeOffset)value).DateTime);
            }
            else
            {
                throw PGUtil.ThrowIfReached();
            }

            var uSecsTime = ts.Time.Ticks / 10;

            if (ts >= new NpgsqlDateTime(2000, 1, 1, 0, 0, 0))
            {
                var uSecsDate = (ts.Date.DaysSinceEra - 730119) * 86400000000L;
                buf.WriteInt64(uSecsDate + uSecsTime);
            }
            else
            {
                var uSecsDate = (730119 - ts.Date.DaysSinceEra) * 86400000000L;
                buf.WriteInt64(-(uSecsDate - uSecsTime));
            }
        }
Ejemplo n.º 18
0
        public override bool Write(ref DirectBuffer directBuf)
        {
            Contract.Assert(_members != null);
            if (_fieldIndex == -1)
            {
                if (_writeBuf.WriteSpaceLeft < 4)
                {
                    return(false);
                }
                _writeBuf.WriteInt32(_members.Count);
                _fieldIndex = 0;
            }

            for (; _fieldIndex < _members.Count; _fieldIndex++)
            {
                var fieldDescriptor = _members[_fieldIndex];
                var fieldHandler    = fieldDescriptor.Handler;
                var fieldValue      = fieldDescriptor.GetValue(_value);

                if (fieldValue == null)
                {
                    if (_writeBuf.WriteSpaceLeft < 8)
                    {
                        return(false);
                    }
                    _writeBuf.WriteUInt32(fieldHandler.BackendType.OID);
                    _writeBuf.WriteInt32(-1);
                    continue;
                }

                var asSimpleWriter = fieldHandler as ISimpleTypeHandler;
                if (asSimpleWriter != null)
                {
                    var elementLen = asSimpleWriter.ValidateAndGetLength(fieldValue, null);
                    if (_writeBuf.WriteSpaceLeft < 8 + elementLen)
                    {
                        return(false);
                    }
                    _writeBuf.WriteUInt32(fieldDescriptor.OID);
                    _writeBuf.WriteInt32(elementLen);
                    asSimpleWriter.Write(fieldValue, _writeBuf, null);
                    continue;
                }

                var asChunkedWriter = fieldHandler as IChunkingTypeHandler;
                if (asChunkedWriter != null)
                {
                    if (!_wroteFieldHeader)
                    {
                        if (_writeBuf.WriteSpaceLeft < 8)
                        {
                            return(false);
                        }
                        _writeBuf.WriteUInt32(fieldDescriptor.OID);
                        _writeBuf.WriteInt32(asChunkedWriter.ValidateAndGetLength(fieldValue, ref _lengthCache, null));
                        asChunkedWriter.PrepareWrite(fieldValue, _writeBuf, _lengthCache, null);
                        _wroteFieldHeader = true;
                    }
                    if (!asChunkedWriter.Write(ref directBuf))
                    {
                        return(false);
                    }
                    _wroteFieldHeader = false;
                    continue;
                }

                throw PGUtil.ThrowIfReached();
            }

            return(true);
        }
Ejemplo n.º 19
0
        internal override bool Write(NpgsqlBuffer buf, ref byte[] directBuf)
        {
            Contract.Requires(Statement != null && Statement.All(c => c < 128));
            Contract.Requires(Portal != null && Portal.All(c => c < 128));

            switch (_state)
            {
            case State.WroteNothing:
                var formatCodesSum       = InputParameters.Select(p => p.FormatCode).Sum(c => (int)c);
                var formatCodeListLength = formatCodesSum == 0 ? 0 : formatCodesSum == InputParameters.Count ? 1 : InputParameters.Count;

                var headerLength =
                    4 +                            // Message length
                    Portal.Length + 1 +
                    Statement.Length + 1 +
                    2 +                            // Number of parameter format codes that follow
                    2 * formatCodeListLength +     // List of format codes
                    2;                             // Number of parameters

                if (buf.WriteSpaceLeft < headerLength)
                {
                    if (buf.Size < headerLength)
                    {
                        throw new Exception("Buffer too small for Bind header");
                    }
                    return(false);
                }

                var messageLength = headerLength +
                                    4 * InputParameters.Count +                                             // Parameter lengths
                                    InputParameters.Select(p => p.BoundSize).Sum() +                        // Parameter values
                                    2 +                                                                     // Number of result format codes
                                    2 * (UnknownResultTypeList == null ? 1 : UnknownResultTypeList.Length); // Result format codes

                buf.WriteByte(Code);
                buf.WriteInt32(messageLength);
                buf.WriteBytesNullTerminated(Encoding.ASCII.GetBytes(Portal));
                buf.WriteBytesNullTerminated(Encoding.ASCII.GetBytes(Statement));

                // 0 implicitly means all-text, 1 means all binary, >1 means mix-and-match
                buf.WriteInt16(formatCodeListLength);
                if (formatCodeListLength == 1)
                {
                    buf.WriteInt16((short)FormatCode.Binary);
                }
                else if (formatCodeListLength > 1)
                {
                    foreach (var code in InputParameters.Select(p => p.FormatCode))
                    {
                        buf.WriteInt16((short)code);
                    }
                }

                buf.WriteInt16(InputParameters.Count);
                _state = State.WroteHeader;
                goto case State.WroteHeader;

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

            case State.WroteParameters:
                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();
            }
        }
Ejemplo n.º 20
0
        public bool Write(ref DirectBuffer directBuf)
        {
            switch (_state)
            {
            case State.Count:
                if (_buf.WriteSpaceLeft < 4)
                {
                    return(false);
                }
                _buf.WriteInt32(_value.Count);
                if (_value.Count == 0)
                {
                    CleanupState();
                    return(true);
                }
                _enumerator = _value.GetEnumerator();
                _enumerator.MoveNext();
                goto case State.KeyLen;

            case State.KeyLen:
                _state = State.KeyLen;
                if (_buf.WriteSpaceLeft < 4)
                {
                    return(false);
                }
                var keyLen = _lengthCache.Get();
                _buf.WriteInt32(keyLen);
                _textHandler.PrepareWrite(_enumerator.Current.Key, _buf, _lengthCache, _parameter);
                goto case State.KeyData;

            case State.KeyData:
                _state = State.KeyData;
                if (!_textHandler.Write(ref directBuf))
                {
                    return(false);
                }
                goto case State.ValueLen;

            case State.ValueLen:
                _state = State.ValueLen;
                if (_buf.WriteSpaceLeft < 4)
                {
                    return(false);
                }
                if (_enumerator.Current.Value == null)
                {
                    _buf.WriteInt32(-1);
                    if (!_enumerator.MoveNext())
                    {
                        CleanupState();
                        return(true);
                    }
                    goto case State.KeyLen;
                }
                var valueLen = _lengthCache.Get();
                _buf.WriteInt32(valueLen);
                _textHandler.PrepareWrite(_enumerator.Current.Value, _buf, _lengthCache, _parameter);
                goto case State.ValueData;

            case State.ValueData:
                _state = State.ValueData;
                if (!_textHandler.Write(ref directBuf))
                {
                    return(false);
                }
                if (!_enumerator.MoveNext())
                {
                    CleanupState();
                    return(true);
                }
                goto case State.KeyLen;

            default:
                throw PGUtil.ThrowIfReached();
            }
        }
 /// <summary>
 /// Convert a System.Double to a postgres float8.
 /// </summary>
 internal static byte[] DoubleToFloat8Binary(NpgsqlNativeTypeInfo TypeInfo, Object NativeData, NativeToBackendTypeConverterOptions options)
 {
     return(PGUtil.HostNetworkByteOrderSwap(BitConverter.GetBytes(Convert.ToDouble(NativeData))));
 }
Ejemplo n.º 22
0
        private Object FastpathV2(Int32 fnid, Boolean resulttype, FastpathArg[] args)
        {
            // added Oct 7 1998 to give us thread safety
            lock (stream)
            {
                // send the function call

                // 70 is 'F' in ASCII. Note: don't use SendChar() here as it adds padding
                // that confuses the backend. The 0 terminates the command line.
                stream.WriteByte((Byte)70);
                stream.WriteByte((Byte)0);

                PGUtil.WriteInt32(stream, fnid);
                PGUtil.WriteInt32(stream, args.Length);


                for (Int32 i = 0; i < args.Length; i++)
                {
                    args[i].Send(stream);
                }

                // This is needed, otherwise data can be lost
                stream.Flush();


                // Now handle the result

                // Now loop, reading the results
                Object  result       = null; // our result
                String  errorMessage = "";
                Byte[]  input_buffer = new Byte[512];
                Int32   c;
                Boolean l_endQuery = false;
                while (!l_endQuery)
                {
                    c = (Char)stream.ReadByte();

                    switch (c)
                    {
                    case 'A':   // Asynchronous Notify
                        //TODO: do something with this
                        Int32  pid = PGUtil.ReadInt32(stream, input_buffer);
                        String msg = PGUtil.ReadString(stream, conn.Connector.Encoding);


                        conn.Connector.CheckErrorsAndNotifications();

                        break;

                    //------------------------------
                    // Error message returned
                    case 'E':
                        NpgsqlError e = new NpgsqlError(conn.BackendProtocolVersion);
                        e.ReadFromStream(stream, conn.Connector.Encoding);
                        errorMessage += e.Message;
                        break;

                    //------------------------------
                    // Notice from backend
                    case 'N':
                        NpgsqlError notice = new NpgsqlError(conn.BackendProtocolVersion);
                        notice.ReadFromStream(stream, conn.Connector.Encoding);
                        errorMessage += notice.Message;
                        break;

                    case 'V':
                        Char l_nextChar = (Char)stream.ReadByte();
                        if (l_nextChar == 'G')
                        {
                            Int32 sz = PGUtil.ReadInt32(stream, input_buffer);
                            // Return an Integer if
                            if (resulttype)
                            {
                                result = PGUtil.ReadInt32(stream, input_buffer);
                            }
                            else
                            {
                                Byte[] buf = new Byte[sz];

                                Int32 bytes_from_stream = 0;
                                Int32 total_bytes_read  = 0;
                                Int32 size = sz;
                                do
                                {
                                    bytes_from_stream = stream.Read(buf, total_bytes_read, size);
                                    total_bytes_read += bytes_from_stream;
                                    size -= bytes_from_stream;
                                }while(size > 0);

                                result = buf;
                            }
                            //There should be a trailing '0'
                            Int32 l_endChar = (Char)stream.ReadByte();
                        }
                        else
                        {
                            //it must have been a '0', thus no results
                        }
                        break;

                    case 'Z':
                        l_endQuery = true;
                        break;

                    default:
                        throw new NpgsqlException("postgresql.fp.protocol " + c.ToString());
                    }
                }

                if (errorMessage != null)
                {
                    throw new NpgsqlException("postgresql.fp.error" + errorMessage);
                }

                return(result);
            }
        }
Ejemplo n.º 23
0
        /// <summary>
        /// Creates an n-dimensional System.Array from PG binary representation.
        /// This function reads the array header and sets up an n-dimensional System.Array object to hold its data.
        /// PopulateArrayFromBinaryArray() is then called to carry out array population.
        /// </summary>
        public object ArrayBinaryToArray(NpgsqlBackendTypeInfo TypeInfo, byte[] BackendData, Int32 fieldValueSize, Int32 TypeModifier)
        {
            // Sanity check.
            if (BackendData.Length < 4)
            {
                throw new Exception("Insuffient backend data to describe dimension count in binary array header");
            }

            // Offset 0 holds an integer dscribing the number of dimensions in the array.
            int nDims = PGUtil.ReadInt32(BackendData, 0);

            // Sanity check.
            if (nDims < 0)
            {
                throw new NpgsqlException("Invalid array dimension count encountered in binary array header");
            }

            // {PG handles 0-dimension arrays, but .net does not.  Return a 0-size 1-dimensional array.
            if (nDims == 0)
            {
                return(Array.CreateInstance(_elementConverter.FrameworkType, 0));
            }

            int dimOffset;
            // Offset 12 begins an array of {int,int} objects, of length nDims.
            int dataOffset = 12;

            // Sanity check.
            if (BackendData.Length < dataOffset + nDims * 8)
            {
                throw new NpgsqlException("Insuffient backend data to describe all expected dimensions in binary array header");
            }

            int[] dimLengths;
            int[] dimLBounds;

            dimLengths = new int[nDims];
            dimLBounds = new int[nDims];

            // Populate array dimension lengths and lower bounds.
            for (dimOffset = 0; dimOffset < nDims; dimOffset++)
            {
                dimLengths[dimOffset] = PGUtil.ReadInt32(BackendData, dataOffset);
                dataOffset           += 4;

                // Lower bounds is 1-based in SQL, 0-based in .NET.
                dimLBounds[dimOffset] = PGUtil.ReadInt32(BackendData, dataOffset) - 1;
                dataOffset           += 4;
            }

            Array dst;

            int[] dstOffsets;

            dst = Array.CreateInstance(_elementConverter.FrameworkType, dimLengths, dimLBounds);

            dstOffsets = new int[nDims];

            // Right after the dimension descriptors begins array data.
            // Populate the new array.
            PopulateArrayFromBinaryArray(TypeInfo, BackendData, fieldValueSize, TypeModifier, ref dataOffset, dimLengths, dimLBounds, 0, dst, dstOffsets);

            return(dst);
        }
Ejemplo n.º 24
0
 public override int GetHashCode()
 => Top.GetHashCode() ^ PGUtil.RotateShift(Right.GetHashCode(), sizeof(int) / 4) ^
 PGUtil.RotateShift(Bottom.GetHashCode(), sizeof(int) / 2) ^
 PGUtil.RotateShift(LowerLeft.GetHashCode(), sizeof(int) * 3 / 4);
Ejemplo n.º 25
0
        // ReSharper restore CompareOfFloatsByEqualityOperator

        public override int GetHashCode()
        => X.GetHashCode() ^ PGUtil.RotateShift(Y.GetHashCode(), sizeof(int) / 2);
Ejemplo n.º 26
0
        public override bool Read(out T result)
        {
            result = default(T);

            if (_fieldIndex == -1)
            {
                if (_readBuf.ReadBytesLeft < 4)
                {
                    return(false);
                }
                var fieldCount = _readBuf.ReadInt32();
                if (fieldCount != _members.Count)
                {
                    // PostgreSQL sanity check
                    throw new Exception($"pg_attributes contains {_members.Count} rows for type {PgDisplayName}, but {fieldCount} fields were received!");
                }
                _fieldIndex = 0;
            }

            for (; _fieldIndex < _members.Count; _fieldIndex++)
            {
                var fieldDescriptor = _members[_fieldIndex];
                // Not yet started reading the field.
                // Read the type OID (not really needed), then the length.
                if (_len == -1)
                {
                    if (_readBuf.ReadBytesLeft < 8)
                    {
                        return(false);
                    }
                    _readBuf.ReadInt32();  // read typeOID, not used
                    _len = _readBuf.ReadInt32();
                    if (_len == -1)
                    {
                        // Null field, simply skip it and leave at default
                        continue;
                    }
                }

                // Get the field's type handler and read the value
                var    handler    = fieldDescriptor.Handler;
                object fieldValue = null;

                if (handler is ISimpleTypeHandler)
                {
                    var asSimpleReader = (ISimpleTypeHandler)handler;
                    if (_readBuf.ReadBytesLeft < _len)
                    {
                        return(false);
                    }
                    fieldValue = asSimpleReader.ReadAsObject(_readBuf, _len);
                }
                else if (handler is IChunkingTypeHandler)
                {
                    var asChunkingReader = (IChunkingTypeHandler)handler;
                    if (!_preparedRead)
                    {
                        asChunkingReader.PrepareRead(_readBuf, _len);
                        _preparedRead = true;
                    }

                    if (!asChunkingReader.ReadAsObject(out fieldValue))
                    {
                        return(false);
                    }
                    _preparedRead = false;
                }
                else
                {
                    throw PGUtil.ThrowIfReached();
                }

                fieldDescriptor.SetValue(_value, fieldValue);
                _len = -1;
            }

            result = (T)_value;
            return(true);
        }
Ejemplo n.º 27
0
 public override int GetHashCode()
 {
     return
         (Start.X.GetHashCode() ^ PGUtil.RotateShift(Start.Y.GetHashCode(), sizeof(int) / 4) ^
          PGUtil.RotateShift(End.X.GetHashCode(), sizeof(int) / 2) ^ PGUtil.RotateShift(End.Y.GetHashCode(), sizeof(int) * 3 / 4));
 }
Ejemplo n.º 28
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);
        }
Ejemplo n.º 29
0
 public override int GetHashCode()
 {
     return(PGUtil.RotateShift(Address.GetHashCode(), Netmask % 32));
 }
Ejemplo n.º 30
0
 public override int GetHashCode()
 {
     return
         (Center.X.GetHashCode() ^ PGUtil.RotateShift(Center.Y.GetHashCode(), sizeof(int) / 4) ^
          PGUtil.RotateShift(Radius.GetHashCode(), sizeof(int) / 2));
 }