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(); }
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()"); }
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())); }
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)); }
/// <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(); } }
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(); } }
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(); } }
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(); } }
public override int GetHashCode() { return(PGUtil.RotateShift(addr.GetHashCode(), mask % 32)); }
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); } }
public override int GetHashCode() { return(X.GetHashCode() ^ PGUtil.RotateShift(Y.GetHashCode(), sizeof(int) / 2)); }
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)); } }
/// <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; } } } }
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); }
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(); } }
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)); }
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)); } }
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); }
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(); } }
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)))); }
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); } }
/// <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); }
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);
// ReSharper restore CompareOfFloatsByEqualityOperator public override int GetHashCode() => X.GetHashCode() ^ PGUtil.RotateShift(Y.GetHashCode(), sizeof(int) / 2);
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); }
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)); }
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); }
public override int GetHashCode() { return(PGUtil.RotateShift(Address.GetHashCode(), Netmask % 32)); }
public override int GetHashCode() { return (Center.X.GetHashCode() ^ PGUtil.RotateShift(Center.Y.GetHashCode(), sizeof(int) / 4) ^ PGUtil.RotateShift(Radius.GetHashCode(), sizeof(int) / 2)); }