private static unsafe Guid ReadBinaryGuid(byte *data) { var a = BinaryBuffer.ReadIntNetworkUnsafe(data); var b = BinaryBuffer.ReadShortNetworkUnsafe(&data[4]); var c = BinaryBuffer.ReadShortNetworkUnsafe(&data[6]); return(new Guid(a, b, c, data[8], data[9], data[10], data[11], data[12], data[13], data[14], data[15])); }
public override unsafe IReadOnlyList <string> DecodeBinaryArray( byte *data, int length, int count, PostgresClientState state) { var results = new string[count]; var resultIndex = 0; for (var i = 0; i < length;) { var size = BinaryBuffer.ReadIntNetworkUnsafe(&data[i]); if (size + i > length) { throw new ArgumentOutOfRangeException(); } i += 4; var s = size == 0 ? "" : state.ServerEncoding.GetString(&data[i], size); results[resultIndex] = s; ++resultIndex; if (resultIndex == count) { break; } i += size; } if (resultIndex != count) { // TODO throw new Exception( "Unexpected early termination of string array."); } return(results); }
public override int DecodeBinary(DataRow row, PostgresClientState state) { PostgresTypeConverter.DemandDataLength(row, 4); return(BinaryBuffer.ReadIntNetworkUnsafe(row.Data, 0)); }
public override unsafe IReadOnlyList <T> DecodeBinary( DataRow row, PostgresClientState state) { // TODO if (row.Length < 4 * 0) { // TODO throw new Exception(); } // https://stackoverflow.com/questions/4016412/postgresqls-libpq-encoding-for-binary-transport-of-array-data fixed(byte *dataPtrBase = row.Data) { var dimentions = BinaryBuffer .ReadIntNetworkUnsafe(dataPtrBase); var noNullBitmap = BinaryBuffer .ReadIntNetworkUnsafe(&dataPtrBase[4 * 1]); var oid = BinaryBuffer .ReadIntNetworkUnsafe(&dataPtrBase[4 * 2]); if (dimentions < 1) { throw new ArgumentOutOfRangeException( nameof(dimentions), dimentions, "Invalid dimention count."); } if (oid < 1) { throw new ArgumentOutOfRangeException( nameof(oid), oid, "Invalid oid."); } var hasDimentions = dimentions > 1; if (hasDimentions) { throw new ArgumentOutOfRangeException( nameof(dimentions), dimentions, "Multi-dimentional arrays are not supported."); } var dimentionalArray = hasDimentions ? new List <IReadOnlyList <T> >(dimentions) : null; var dataPtr = &dataPtrBase[4 * 3]; for (var dimention = 0; dimention < dimentions; ++dimention) { var elementCount = BinaryBuffer .ReadIntNetworkUnsafe(dataPtr); dataPtr = &dataPtr[4]; // TODO: var firstIndex = BinaryBuffer .ReadIntNetworkUnsafe(dataPtr); dataPtr = &dataPtr[4]; IReadOnlyList <T> array; if (elementCount == 0) { array = EmptyArray <T> .Value; } else { var length = row.Data.Length - (dataPtr - dataPtrBase); array = _wrappedCodec.DecodeBinaryArray( dataPtr, (int)length, elementCount, state); } if (!hasDimentions) { return(array); } dimentionalArray.Add(array); } throw new ArgumentOutOfRangeException( nameof(dimentions), dimentions, "Multi-dimentional arrays are not supported."); } }