示例#1
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;
                    }
                }
            }
        }