private void ReadFromStream_Ver_2(Stream input_stream, Encoding encoding, NpgsqlBackendTypeMapping type_mapping)
        {
            NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "ReadFromStream_Ver_2");

            Byte[] input_buffer = new Byte[10]; // Max read will be 4 + 2 + 4

            // Read the number of fields.
            input_stream.Read(input_buffer, 0, 2);
            Int16 num_fields = IPAddress.NetworkToHostOrder(BitConverter.ToInt16(input_buffer, 0));


            // Temporary FieldData object to get data from stream and put in array.
            NpgsqlRowDescriptionFieldData fd;

            fields_data  = new NpgsqlRowDescriptionFieldData[num_fields];
            fields_index = new string[num_fields];

            field_name_index_table = new Hashtable(num_fields);


            // Now, iterate through each field getting its data.
            for (Int16 i = 0; i < num_fields; i++)
            {
                fd = new NpgsqlRowDescriptionFieldData();

                // Set field name.
                fd.name = PGUtil.ReadString(input_stream, encoding);

                // Read type_oid(Int32), type_size(Int16), type_modifier(Int32)
                input_stream.Read(input_buffer, 0, 4 + 2 + 4);

                fd.type_oid      = IPAddress.NetworkToHostOrder(BitConverter.ToInt32(input_buffer, 0));
                fd.type_info     = type_mapping[fd.type_oid];
                fd.type_size     = IPAddress.NetworkToHostOrder(BitConverter.ToInt16(input_buffer, 4));
                fd.type_modifier = IPAddress.NetworkToHostOrder(BitConverter.ToInt32(input_buffer, 6));

                // Add field data to array.
                fields_data[i] = fd;

                fields_index[i] = fd.name;

                if (!field_name_index_table.ContainsKey(fd.name))
                {
                    field_name_index_table.Add(fd.name, i);
                }
            }
        }
        private void ReadFromStream_Ver_3(Stream input_stream, Encoding encoding, NpgsqlBackendTypeMapping type_mapping)
        {
            NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "ReadFromStream_Ver_3");

            Byte[] input_buffer = new Byte[4]; // Max read will be 4 + 2 + 4 + 2 + 4 + 2

            // Read the length of message.
            // [TODO] Any use for now?
            PGUtil.ReadInt32(input_stream, input_buffer);
            Int16 num_fields = PGUtil.ReadInt16(input_stream, input_buffer);

            // Temporary FieldData object to get data from stream and put in array.
            NpgsqlRowDescriptionFieldData fd;

            fields_data            = new NpgsqlRowDescriptionFieldData[num_fields];
            fields_index           = new string[num_fields];
            field_name_index_table = new Hashtable(num_fields);

            for (Int16 i = 0; i < num_fields; i++)
            {
                fd = new NpgsqlRowDescriptionFieldData();

                fd.name      = PGUtil.ReadString(input_stream, encoding);
                fd.table_oid = PGUtil.ReadInt32(input_stream, input_buffer);
                fd.column_attribute_number = PGUtil.ReadInt16(input_stream, input_buffer);
                fd.type_oid      = PGUtil.ReadInt32(input_stream, input_buffer);
                fd.type_info     = type_mapping[fd.type_oid];
                fd.type_size     = PGUtil.ReadInt16(input_stream, input_buffer);
                fd.type_modifier = PGUtil.ReadInt32(input_stream, input_buffer);
                fd.format_code   = (FormatCode)PGUtil.ReadInt16(input_stream, input_buffer);

                fields_data[i]  = fd;
                fields_index[i] = fd.name;

                if (!field_name_index_table.ContainsKey(fd.name))
                {
                    field_name_index_table.Add(fd.name, i);
                }
            }
        }
        private void ReadFromStream_Ver_2(Stream inputStream, Encoding encoding)
        {
            NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "ReadFromStream_Ver_2");

            Byte[] null_map_array = new Byte[(row_desc.NumFields + 7) / 8];

            Array.Clear(null_map_array, 0, null_map_array.Length);


            // Decoders used to get decoded chars when using unicode like encodings which may have chars crossing the byte buffer bounds.

            Decoder decoder = encoding.GetDecoder();

            // Read the null fields bitmap.
            PGUtil.CheckedStreamRead(inputStream, null_map_array, 0, null_map_array.Length);

            // Get the data.
            for (Int16 field_count = 0; field_count < row_desc.NumFields; field_count++)
            {
                // Check if this field is null
                if (IsBackendNull(null_map_array, field_count))
                {
                    data.Add(DBNull.Value);
                    continue;
                }

                // Read the first data of the first row.

                PGUtil.CheckedStreamRead(inputStream, _inputBuffer, 0, 4);

                NpgsqlRowDescriptionFieldData field_descr = row_desc[field_count];
                Int32 field_value_size = IPAddress.NetworkToHostOrder(BitConverter.ToInt32(_inputBuffer, 0));
                field_value_size -= 4;

                string result = ReadStringFromStream(inputStream, field_value_size, decoder);
                // Add them to the AsciiRow data.
                data.Add(NpgsqlTypesHelper.ConvertBackendStringToSystemType(field_descr.type_info, result, field_descr.type_size, field_descr.type_modifier));
            }
        }
        private void ReadFromStream_Ver_3(Stream inputStream, Encoding encoding)
        {
            NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "ReadFromStream_Ver_3");

            PGUtil.ReadInt32(inputStream, _inputBuffer);
            Int16 numCols = PGUtil.ReadInt16(inputStream, _inputBuffer);

            Decoder decoder = encoding.GetDecoder();

            for (Int16 field_count = 0; field_count < numCols; field_count++)
            {
                Int32 field_value_size = PGUtil.ReadInt32(inputStream, _inputBuffer);

                // Check if this field is null
                if (field_value_size == -1) // Null value
                {
                    data.Add(DBNull.Value);
                    continue;
                }

                NpgsqlRowDescriptionFieldData field_descr = row_desc[field_count];

                if (row_desc[field_count].format_code == FormatCode.Text)
                {
                    string result = ReadStringFromStream(inputStream, field_value_size, decoder);
                    // Add them to the AsciiRow data.
                    data.Add(NpgsqlTypesHelper.ConvertBackendStringToSystemType(field_descr.type_info, result, field_descr.type_size, field_descr.type_modifier));
                }
                else
                {
                    Byte[] binary_data = ReadBytesFromStream(inputStream, field_value_size);

                    data.Add(NpgsqlTypesHelper.ConvertBackendBytesToSystemType(field_descr.type_info, binary_data, encoding, field_value_size, field_descr.type_modifier));
                }
            }
        }
        private void ReadFromStream_Ver_2(Stream input_stream, Encoding encoding, NpgsqlBackendTypeMapping type_mapping)
        {
            NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "ReadFromStream_Ver_2");

            Byte[] input_buffer = new Byte[10]; // Max read will be 4 + 2 + 4

            // Read the number of fields.
            input_stream.Read(input_buffer, 0, 2);
            Int16 num_fields = IPAddress.NetworkToHostOrder(BitConverter.ToInt16(input_buffer, 0));


            // Temporary FieldData object to get data from stream and put in array.
            NpgsqlRowDescriptionFieldData fd;

            // Now, iterate through each field getting its data.
            for (Int16 i = 0; i < num_fields; i++)
            {
                fd = new NpgsqlRowDescriptionFieldData();

                // Set field name.
                fd.name = PGUtil.ReadString(input_stream, encoding);

                // Read type_oid(Int32), type_size(Int16), type_modifier(Int32)
                input_stream.Read(input_buffer, 0, 4 + 2 + 4);

                fd.type_oid = IPAddress.NetworkToHostOrder(BitConverter.ToInt32(input_buffer, 0));
                fd.type_info = type_mapping[fd.type_oid];
                fd.type_size = IPAddress.NetworkToHostOrder(BitConverter.ToInt16(input_buffer, 4));
                fd.type_modifier = IPAddress.NetworkToHostOrder(BitConverter.ToInt32(input_buffer, 6));

                // Add field data to array.
                fields_data.Add(fd);

                fields_index.Add(fd.name);
            }
        }
        private void ReadFromStream_Ver_3(Stream input_stream, Encoding encoding, NpgsqlBackendTypeMapping type_mapping)
        {
            NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "ReadFromStream_Ver_3");

            Byte[] input_buffer = new Byte[4]; // Max read will be 4 + 2 + 4 + 2 + 4 + 2

            // Read the length of message.
            // [TODO] Any use for now?
            PGUtil.ReadInt32(input_stream, input_buffer);
            Int16 num_fields = PGUtil.ReadInt16(input_stream, input_buffer);

            // Temporary FieldData object to get data from stream and put in array.
            NpgsqlRowDescriptionFieldData fd;

            for (Int16 i = 0; i < num_fields; i++)
            {
                fd = new NpgsqlRowDescriptionFieldData();

                fd.name = PGUtil.ReadString(input_stream, encoding);
                fd.table_oid = PGUtil.ReadInt32(input_stream, input_buffer);
                fd.column_attribute_number = PGUtil.ReadInt16(input_stream, input_buffer);
                fd.type_oid = PGUtil.ReadInt32(input_stream, input_buffer);
                fd.type_info = type_mapping[fd.type_oid];
                fd.type_size = PGUtil.ReadInt16(input_stream, input_buffer);
                fd.type_modifier = PGUtil.ReadInt32(input_stream, input_buffer);
                fd.format_code = (FormatCode)PGUtil.ReadInt16(input_stream, input_buffer);

                fields_data.Add(fd);
                fields_index.Add(fd.name);
            }
        }