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.");
            }
        }