(DISTFILES): Comment out a few missing files.
[mono-project.git] / mcs / class / Npgsql / Npgsql / NpgsqlAsciiRow.cs
blob16ca5d733b5fb06066030eaa16352565ad164bb3
1 // created on 13/6/2002 at 21:06
3 // Npgsql.NpgsqlAsciiRow.cs
4 //
5 // Author:
6 // Francisco Jr. (fxjrlists@yahoo.com.br)
7 //
8 // Copyright (C) 2002 The Npgsql Development Team
9 // npgsql-general@gborg.postgresql.org
10 // http://gborg.postgresql.org/project/npgsql/projdisplay.php
12 // This library is free software; you can redistribute it and/or
13 // modify it under the terms of the GNU Lesser General Public
14 // License as published by the Free Software Foundation; either
15 // version 2.1 of the License, or (at your option) any later version.
17 // This library is distributed in the hope that it will be useful,
18 // but WITHOUT ANY WARRANTY; without even the implied warranty of
19 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 // Lesser General Public License for more details.
22 // You should have received a copy of the GNU Lesser General Public
23 // License along with this library; if not, write to the Free Software
24 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
26 using System;
27 using System.Collections;
28 using System.IO;
29 using System.Text;
30 using System.Net;
32 using NpgsqlTypes;
34 namespace Npgsql
37 /// <summary>
38 /// This class represents the AsciiRow (version 2) and DataRow (version 3+)
39 /// message sent from the PostgreSQL server.
40 /// </summary>
41 internal sealed class NpgsqlAsciiRow : NpgsqlRow
43 // Logging related values
44 private static readonly String CLASSNAME = "NpgsqlAsciiRow";
46 private readonly Int16 READ_BUFFER_SIZE = 300; //[FIXME] Is this enough??
48 public NpgsqlAsciiRow(NpgsqlRowDescription rowDesc, ProtocolVersion protocolVersion)
49 : base(rowDesc, protocolVersion)
51 NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, CLASSNAME);
54 public override void ReadFromStream(Stream inputStream, Encoding encoding)
56 switch (protocol_version) {
57 case ProtocolVersion.Version2 :
58 ReadFromStream_Ver_2(inputStream, encoding);
59 break;
61 case ProtocolVersion.Version3 :
62 ReadFromStream_Ver_3(inputStream, encoding);
63 break;
68 private void ReadFromStream_Ver_2(Stream inputStream, Encoding encoding)
70 NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "ReadFromStream_Ver_2");
72 Byte[] input_buffer = new Byte[READ_BUFFER_SIZE];
73 Byte[] null_map_array = new Byte[(row_desc.NumFields + 7)/8];
75 Array.Clear(null_map_array, 0, null_map_array.Length);
78 // Decoders used to get decoded chars when using unicode like encodings which may have chars crossing the byte buffer bounds.
80 Decoder decoder = encoding.GetDecoder();
81 Char[] chars = null;
82 Int32 charCount;
85 // Read the null fields bitmap.
86 PGUtil.CheckedStreamRead(inputStream, null_map_array, 0, null_map_array.Length );
88 // Get the data.
89 for (Int16 field_count = 0; field_count < row_desc.NumFields; field_count++)
91 // Check if this field is null
92 if (IsBackendNull(null_map_array, field_count))
94 data.Add(DBNull.Value);
95 continue;
98 // Read the first data of the first row.
100 PGUtil.CheckedStreamRead(inputStream, input_buffer, 0, 4);
102 NpgsqlRowDescriptionFieldData field_descr = row_desc[field_count];
103 Int32 field_value_size = IPAddress.NetworkToHostOrder(BitConverter.ToInt32(input_buffer, 0));
104 field_value_size -= 4;
105 Int32 bytes_left = field_value_size;
107 StringBuilder result = new StringBuilder();
109 while (bytes_left > READ_BUFFER_SIZE)
111 // Now, read just the field value.
112 PGUtil.CheckedStreamRead(inputStream, input_buffer, 0, READ_BUFFER_SIZE);
114 charCount = decoder.GetCharCount(input_buffer, 0, READ_BUFFER_SIZE);
116 chars = new Char[charCount];
118 decoder.GetChars(input_buffer, 0, READ_BUFFER_SIZE, chars, 0);
120 result.Append(new String(chars));
122 bytes_left -= READ_BUFFER_SIZE;
125 // Now, read just the field value.
126 PGUtil.CheckedStreamRead(inputStream, input_buffer, 0, bytes_left);
129 charCount = decoder.GetCharCount(input_buffer, 0, bytes_left);
130 chars = new Char[charCount];
131 decoder.GetChars(input_buffer, 0, bytes_left, chars, 0);
133 result.Append(new String(chars));
136 // Add them to the AsciiRow data.
137 data.Add(NpgsqlTypesHelper.ConvertBackendStringToSystemType(field_descr.type_info, result.ToString(), field_descr.type_size, field_descr.type_modifier));
142 private void ReadFromStream_Ver_3(Stream inputStream, Encoding encoding)
144 NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "ReadFromStream_Ver_3");
146 Byte[] input_buffer = new Byte[READ_BUFFER_SIZE];
148 PGUtil.ReadInt32(inputStream, input_buffer);
149 Int16 numCols = PGUtil.ReadInt16(inputStream, input_buffer);
151 Decoder decoder = encoding.GetDecoder();
152 Char[] chars = null;
153 Int32 charCount;
155 for (Int16 field_count = 0; field_count < numCols; field_count++)
157 Int32 field_value_size = PGUtil.ReadInt32(inputStream, input_buffer);
159 // Check if this field is null
160 if (field_value_size == -1) // Null value
162 data.Add(DBNull.Value);
163 continue;
166 NpgsqlRowDescriptionFieldData field_descr = row_desc[field_count];
167 Int32 bytes_left = field_value_size;
168 StringBuilder result = new StringBuilder();
170 while (bytes_left > READ_BUFFER_SIZE)
173 // Now, read just the field value.
174 PGUtil.CheckedStreamRead(inputStream, input_buffer, 0, READ_BUFFER_SIZE);
176 // Read the bytes as string.
177 //result.Append(new String(encoding.GetChars(input_buffer, 0, READ_BUFFER_SIZE)));
178 charCount = decoder.GetCharCount(input_buffer, 0, READ_BUFFER_SIZE);
180 chars = new Char[charCount];
182 decoder.GetChars(input_buffer, 0, READ_BUFFER_SIZE, chars, 0);
184 result.Append(new String(chars));
186 bytes_left -= READ_BUFFER_SIZE;
188 // Now, read just the field value.
189 /*PGUtil.CheckedStreamRead(inputStream, input_buffer, 0, READ_BUFFER_SIZE);
191 // Read the bytes as string.
192 result.Append(new String(encoding.GetChars(input_buffer, 0, READ_BUFFER_SIZE)));
194 bytes_left -= READ_BUFFER_SIZE;*/
197 // Now, read just the field value.
198 PGUtil.CheckedStreamRead(inputStream, input_buffer, 0, bytes_left);
200 if (row_desc[field_count].format_code == FormatCode.Text)
202 // Read the bytes as string.
203 //result.Append(new String(encoding.GetChars(input_buffer, 0, bytes_left)));
206 charCount = decoder.GetCharCount(input_buffer, 0, bytes_left);
207 chars = new Char[charCount];
208 decoder.GetChars(input_buffer, 0, bytes_left, chars, 0);
210 result.Append(new String(chars));
212 // Add them to the AsciiRow data.
213 data.Add(NpgsqlTypesHelper.ConvertBackendStringToSystemType(field_descr.type_info, result.ToString(), field_descr.type_size, field_descr.type_modifier));
216 else
217 // FIXME: input_buffer isn't holding all the field value. This code isn't handling binary data correctly.
218 data.Add(NpgsqlTypesHelper.ConvertBackendBytesToSystemType(field_descr.type_info, input_buffer, encoding, field_value_size, field_descr.type_modifier));
222 // Using the given null field map (provided by the backend),
223 // determine if the given field index is mapped null by the backend.
224 // We only need to do this for version 2 protocol.
225 private static Boolean IsBackendNull(Byte[] null_map_array, Int32 index)
227 // Get the byte that holds the bit index position.
228 Byte test_byte = null_map_array[index/8];
230 // Now, check if index bit is set.
231 // To do this, get its position in the byte, shift to
232 // MSB and test it with the byte 10000000.
233 return (((test_byte << (index%8)) & 0x80) == 0);