* FileSystemInfo.cs: corrected COM visibility of UTC properties
[mono.git] / mcs / class / Npgsql / Npgsql / NpgsqlBinaryRow.cs
1 // created on 4/3/2003 at 19:45
2
3 // Npgsql.NpgsqlBinaryRow.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
11 //
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.
16 //
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.
21 //
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
25
26 using System;
27 using System.Collections;
28 using System.IO;
29 using System.Text;
30 using System.Net;
31 using NpgsqlTypes;
32
33
34 namespace Npgsql
35 {
36
37     /// <summary>
38     /// This class represents the AsciiRow message sent from PostgreSQL
39     /// server.
40     /// </summary>
41     ///
42     internal sealed class NpgsqlBinaryRow
43     {
44         // Logging related values
45         private static readonly String CLASSNAME = "NpgsqlBinaryRow";
46
47         private ArrayList                                                       data;
48         //        private readonly Int16        READ_BUFFER_SIZE = 300; //[FIXME] Is this enough??
49         private NpgsqlRowDescription row_desc;
50
51         public NpgsqlBinaryRow(NpgsqlRowDescription rowDesc)
52         {
53             NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, CLASSNAME);
54
55             data = new ArrayList();
56             row_desc = rowDesc;
57
58         }
59
60
61         public void ReadFromStream(Stream inputStream, Encoding encoding)
62         {
63             NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "ReadFromStream");
64
65             //Byte[] input_buffer = new Byte[READ_BUFFER_SIZE];
66             Byte[]       input_buffer = null;
67             Byte[]       null_map_array = new Byte[(row_desc.NumFields + 7)/8];
68
69             null_map_array = new Byte[(row_desc.NumFields + 7)/8];
70             Array.Clear(null_map_array, 0, null_map_array.Length);
71
72             // Read the null fields bitmap.
73             inputStream.Read(null_map_array, 0, null_map_array.Length );
74
75             // Get the data.
76             for (Int16 field_count = 0; field_count < row_desc.NumFields; field_count++)
77             {
78
79                 // Check if this field isn't null
80                 if (IsBackendNull(null_map_array, field_count))
81                 {
82                     // Field is null just keep next field.
83                    
84                     data.Add(DBNull.Value);
85                     continue;
86                 }
87
88                 // Read the first data of the first row.
89
90                 PGUtil.CheckedStreamRead(inputStream, input_buffer, 0, 4);
91
92                 Int32 field_value_size = IPAddress.NetworkToHostOrder(BitConverter.ToInt32(input_buffer, 0));
93
94                 Int32 bytes_left = field_value_size; //Size of data is the value read.
95
96                 input_buffer = new Byte[bytes_left];
97
98
99                 // Now, read just the field value.
100                 PGUtil.CheckedStreamRead(inputStream, input_buffer, 0, bytes_left);
101
102                 // Add them to the BinaryRow data.
103                 data.Add(input_buffer);
104
105             }
106
107         }
108
109         // Using the given null field map (provided by the backend),
110         // determine if the given field index is mapped null by the backend.
111         // We only need to do this for version 2 protocol.
112         private static Boolean IsBackendNull(Byte[] null_map_array, Int32 index)
113         {
114             // Get the byte that holds the bit index position.
115             Byte test_byte = null_map_array[index/8];
116
117             // Now, check if index bit is set.
118             // To this, get its position in the byte, shift to
119             // MSB and test it with the byte 10000000.
120             return (((test_byte << (index%8)) & 0x80) == 0);
121         }
122
123
124         public Boolean IsDBNull(Int32 index)
125         {
126             NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "IsDBNull", index);
127
128             // Check valid index range.
129             if ((index < 0) || (index >= row_desc.NumFields))
130                 throw new ArgumentOutOfRangeException("index");
131
132             return (this.data[index] == DBNull.Value);
133         }
134
135         public Object this[Int32 index]
136         {
137             get
138             {
139                 NpgsqlEventLog.LogIndexerGet(LogLevel.Debug, CLASSNAME, index);
140                 if ((index < 0) || (index >= row_desc.NumFields))
141                     throw new ArgumentOutOfRangeException("this[] index value");
142                 return data[index];
143
144
145
146             }
147         }
148     }
149
150 }