New test.
[mono.git] / mcs / class / FirebirdSql.Data.Firebird / FirebirdSql.Data.Common / IscHelper.cs
1 /*
2  *      Firebird ADO.NET Data provider for .NET and Mono 
3  * 
4  *         The contents of this file are subject to the Initial 
5  *         Developer's Public License Version 1.0 (the "License"); 
6  *         you may not use this file except in compliance with the 
7  *         License. You may obtain a copy of the License at 
8  *         http://www.firebirdsql.org/index.php?op=doc&id=idpl
9  *
10  *         Software distributed under the License is distributed on 
11  *         an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either 
12  *         express or implied. See the License for the specific 
13  *         language governing rights and limitations under the License.
14  * 
15  *      Copyright (c) 2002, 2005 Carlos Guzman Alvarez
16  *      All Rights Reserved.
17  */
18
19 using System;
20 using System.Collections;
21 using System.Globalization;
22 using System.Resources;
23 using System.Text;
24
25 namespace FirebirdSql.Data.Common
26 {
27         internal sealed class IscHelper
28         {
29                 #region Constructors
30
31                 private IscHelper()
32                 {
33                 }
34
35                 #endregion
36
37                 #region General Static Methods
38
39                 public static ArrayList ParseDatabaseInfo(byte[] buffer)
40                 {
41                         ArrayList info = new ArrayList();
42
43                         int pos         = 0;
44                         int length      = 0;
45                         int type        = 0;
46
47                         while ((type = buffer[pos++]) != IscCodes.isc_info_end)
48                         {
49                                 length = VaxInteger(buffer, pos, 2);
50                                 pos += 2;
51
52                                 switch (type)
53                                 {
54                                         //
55                                         // Database     characteristics
56                                         //
57                                         case IscCodes.isc_info_allocation:
58                                                 // Number of database pages     allocated
59                                                 info.Add(VaxInteger(buffer, pos, length));
60                                                 break;
61
62                                         case IscCodes.isc_info_base_level:
63                                                 /* Database     version (level) number:
64                                                  *              1 byte containing the number 1
65                                                  *              1 byte containing the version number
66                                                  */
67                                                 info.Add(String.Format(CultureInfo.CurrentCulture, "{0}.{1}", buffer[pos], buffer[pos + 1]));
68                                                 break;
69
70                                         case IscCodes.isc_info_db_id:
71                                                 /* Database     file name and site name:
72                                                  *              \95 1    byte containing the     number 2
73                                                  *              \95 1    byte containing the     length, d, of the database file name in bytes
74                                                  *              \95 A    string of d     bytes, containing the database file     name
75                                                  *              \95 1    byte containing the     length, l, of the site name     in bytes
76                                                  *              \95 A    string of l     bytes, containing the site name
77                                                  */
78                                                 string  dbFile          = Encoding.Default.GetString(buffer, pos + 2, buffer[pos + 1]);
79                                                 int             sitePos         = pos + 2 + buffer[pos + 1];
80                                                 int             siteLength      = buffer[sitePos];
81                                                 string  siteName        = Encoding.Default.GetString(buffer, sitePos + 1, siteLength);
82
83                                                 sitePos         += siteLength + 1;
84                                                 siteLength      = buffer[sitePos];
85                                                 siteName        += "." + Encoding.Default.GetString(buffer, sitePos + 1, siteLength);
86
87                                                 info.Add(siteName + ":" + dbFile);
88                                                 break;
89
90                                         case IscCodes.isc_info_implementation:
91                                                 /* Database     implementation number:
92                                                  *              \95 1    byte containing a 1
93                                                  *              \95 1    byte containing the     implementation number
94                                                  *              \95 1    byte containing a \93class\94 number, either 1 or 12
95                                                  */
96                                                 info.Add(String.Format(CultureInfo.CurrentCulture, "{0}.{1}.{2}", buffer[pos], buffer[pos + 1], buffer[pos + 2]));
97                                                 break;
98
99                                         case IscCodes.isc_info_no_reserve:
100                                                 /* 0 or 1
101                                                  *              \95 0    indicates space is reserved     on each database page for holding
102                                                  *                      backup versions of modified     records [Default]
103                                                  *              \95 1    indicates no space is reserved for such records
104                                                  */
105                                                 info.Add(buffer[pos] == 1 ? true : false);
106                                                 break;
107
108                                         case IscCodes.isc_info_ods_version:
109                                                 /* ODS major version number
110                                                  *              \95 Databases    with different major version numbers have different
111                                                  *                      physical layouts; a     database engine can     only access     databases
112                                                  *                      with a particular ODS major     version number
113                                                  *              \95 Trying to    attach to a     database with a different ODS number
114                                                  *                      results in an error
115                                                  */
116                                                 info.Add(VaxInteger(buffer, pos, length));
117                                                 break;
118
119                                         case IscCodes.isc_info_ods_minor_version:
120                                                 /* On-disk structure (ODS) minor version number; an     increase in     a
121                                                  * minor version number indicates a     non-structural change, one that
122                                                  * still allows the     database to     be accessed     by database     engines with
123                                                  * the same     major version number but possibly different     minor
124                                                  * version numbers
125                                                  */
126                                                 info.Add(VaxInteger(buffer, pos, length));
127                                                 break;
128
129                                         case IscCodes.isc_info_page_size:
130                                                 /* Number of bytes per page     of the attached database; use with
131                                                  * isc_info_allocation to determine     the     size of the     database
132                                                  */
133                                                 info.Add(VaxInteger(buffer, pos, length));
134                                                 break;
135
136                                         case IscCodes.isc_info_isc_version:
137                                                 /* Version identification string of     the     database implementation:
138                                                  *              \95 1    byte containing the     number 1
139                                                  *              \95 1    byte specifying the     length, n, of the following     string
140                                                  *              \95 n    bytes containing the version identification     string
141                                                  */
142                                                 info.Add(Encoding.Default.GetString(buffer, pos + 2, buffer[pos + 1]));
143                                                 break;
144
145                                         //
146                                         // Environmental characteristics
147                                         //
148
149                                         case IscCodes.isc_info_current_memory:
150                                                 // Amount of server     memory (in bytes) currently     in use
151                                                 info.Add(VaxInteger(buffer, pos, length));
152                                                 break;
153
154                                         case IscCodes.isc_info_forced_writes:
155                                                 /* Number specifying the mode in which database writes are performed
156                                                  * (0 for asynchronous, 1 for synchronous)
157                                                  */
158                                                 info.Add(buffer[pos] == 1 ? true : false);
159                                                 break;
160
161                                         case IscCodes.isc_info_max_memory:
162                                                 /* Maximum amount of memory     (in     bytes) used     at one time     since the first
163                                                  * process attached     to the database
164                                                  */
165                                                 info.Add(VaxInteger(buffer, pos, length));
166                                                 break;
167
168                                         case IscCodes.isc_info_num_buffers:
169                                                 // Number of memory     buffers currently allocated
170                                                 info.Add(VaxInteger(buffer, pos, length));
171                                                 break;
172
173                                         case IscCodes.isc_info_sweep_interval:
174                                                 /* Number of transactions that are committed between \93sweeps\94 to
175                                                  * remove database record versions that are     no longer needed
176                                                  */
177                                                 info.Add(VaxInteger(buffer, pos, length));
178                                                 break;
179
180                                         //
181                                         // Performance statistics
182                                         //
183
184                                         case IscCodes.isc_info_fetches:
185                                                 // Number of reads from the     memory buffer cache
186                                                 info.Add(VaxInteger(buffer, pos, length));
187                                                 break;
188
189                                         case IscCodes.isc_info_marks:
190                                                 // Number of writes     to the memory buffer cache
191                                                 info.Add(VaxInteger(buffer, pos, length));
192                                                 break;
193
194                                         case IscCodes.isc_info_reads:
195                                                 // Number of page reads
196                                                 info.Add(VaxInteger(buffer, pos, length));
197                                                 break;
198
199                                         case IscCodes.isc_info_writes:
200                                                 // Number of page writes
201                                                 info.Add(VaxInteger(buffer, pos, length));
202                                                 break;
203
204                                         //
205                                         // Database     operation counts
206                                         //
207                                         case IscCodes.isc_info_backout_count:
208                                                 // Number of removals of a version of a record
209                                                 info.Add(VaxInteger(buffer, pos, length));
210                                                 break;
211
212                                         case IscCodes.isc_info_delete_count:
213                                                 // Number of database deletes since     the     database was last attached
214                                                 info.Add(VaxInteger(buffer, pos, length));
215                                                 break;
216
217                                         case IscCodes.isc_info_expunge_count:
218                                                 /* Number of removals of a record and all of its ancestors,     for     records
219                                                  * whose deletions have been committed
220                                                  */
221                                                 info.Add(VaxInteger(buffer, pos, length));
222                                                 break;
223
224                                         case IscCodes.isc_info_insert_count:
225                                                 // Number of inserts into the database since the database was last attached     
226                                                 info.Add(VaxInteger(buffer, pos, length));
227                                                 break;
228
229                                         case IscCodes.isc_info_purge_count:
230                                                 // Number of removals of old versions of fully mature records
231                                                 info.Add(VaxInteger(buffer, pos, length));
232                                                 break;
233
234                                         case IscCodes.isc_info_read_idx_count:
235                                                 // Number of reads done via     an index since the database     was     last attached
236                                                 info.Add(VaxInteger(buffer, pos, length));
237                                                 break;
238
239                                         case IscCodes.isc_info_read_seq_count:
240                                                 /* Number of sequential sequential table scans (row     reads) done     on each 
241                                                  * table since the database     was     last attached
242                                                  */
243                                                 info.Add(VaxInteger(buffer, pos, length));
244                                                 break;
245
246                                         case IscCodes.isc_info_update_count:
247                                                 // Number of database updates since     the     database was last attached
248                                                 info.Add(VaxInteger(buffer, pos, length));
249                                                 break;
250
251                                         //
252                                         // Misc
253                                         //
254                                         case IscCodes.isc_info_firebird_version:
255                                                 info.Add(Encoding.Default.GetString(buffer, pos + 2, buffer[pos + 1]));
256                                                 break;
257
258                                         case IscCodes.isc_info_db_class:
259                                                 int serverClass = VaxInteger(buffer, pos, length);
260                                                 if (serverClass == IscCodes.isc_info_db_class_classic_access)
261                                                 {
262                                                         info.Add("CLASSIC SERVER");
263                                                 }
264                                                 else
265                                                 {
266                                                         info.Add("SUPER SERVER");
267                                                 }
268                                                 break;
269
270                                         case IscCodes.isc_info_db_read_only:
271                                                 info.Add(buffer[pos] == 1 ? true : false);
272                                                 break;
273
274                                         case IscCodes.isc_info_db_size_in_pages:
275                                                 // Database     size in pages.
276                                                 info.Add(VaxInteger(buffer, pos, length));
277                                                 break;
278
279                                         case IscCodes.isc_info_oldest_transaction:
280                                                 // Number of oldest     transaction
281                                                 info.Add(VaxInteger(buffer, pos, length));
282                                                 break;
283
284                                         case IscCodes.isc_info_oldest_active:
285                                                 // Number of oldest     active transaction
286                                                 info.Add(VaxInteger(buffer, pos, length));
287                                                 break;
288
289                                         case IscCodes.isc_info_oldest_snapshot:
290                                                 // Number of oldest     snapshot transaction
291                                                 info.Add(VaxInteger(buffer, pos, length));
292                                                 break;
293
294                                         case IscCodes.isc_info_next_transaction:
295                                                 // Number of next transaction
296                                                 info.Add(VaxInteger(buffer, pos, length));
297                                                 break;
298
299                                         case IscCodes.isc_info_active_transactions:
300                                                 // Number of active     transactions
301                                                 info.Add(VaxInteger(buffer, pos, length));
302                                                 break;
303
304                     case IscCodes.isc_info_user_names:
305                         // Active user name
306                         info.Add(Encoding.Default.GetString(buffer, pos + 1, buffer[pos]));
307                         break;
308                                 }
309
310                                 pos += length;
311                         }
312
313                         return info;
314                 }
315
316                 public static int VaxInteger(byte[] buffer, int index, int length)
317                 {
318                         int newValue;
319                         int shift;
320
321                         newValue = shift = 0;
322
323                         int i = index;
324                         while (--length >= 0)
325                         {
326                                 newValue += (buffer[i++] & 0xff) << shift;
327                                 shift += 8;
328                         }
329
330                         return newValue;
331                 }
332
333                 #endregion
334         }
335 }