2003-06-01 Ville Palo <vi64pa@kolumbus.fi>
[mono.git] / mcs / class / System.Data / System.Data.SqlTypes / SqlString.cs
1 //
2 // System.Data.SqlTypes.SqlString
3 //
4 // Author:
5 //   Rodrigo Moya (rodrigo@ximian.com)
6 //   Daniel Morgan (danmorg@sc.rr.com)
7 //   Tim Coleman (tim@timcoleman.com)
8 //   Ville Palo (vi64pa@koti.soon.fi)
9 //
10 // (C) Ximian, Inc. 2002
11 // (C) Copyright 2002 Tim Coleman
12 //
13
14 using System;
15 using System.Globalization;
16 using System.Threading;
17
18 namespace System.Data.SqlTypes
19 {
20         /// <summary>
21         /// A variable-length stream of characters 
22         /// to be stored in or retrieved from the database
23         /// </summary>
24         public struct SqlString : INullable, IComparable 
25         {
26
27                 #region Fields
28
29                 string value;
30
31                 private bool notNull;
32
33                 // FIXME: locale id is not working yet
34                 private int lcid;
35                 private SqlCompareOptions compareOptions;
36
37                 public static readonly int BinarySort = 0x8000;
38                 public static readonly int IgnoreCase = 0x1;
39                 public static readonly int IgnoreKanaType = 0x8;
40                 public static readonly int IgnoreNonSpace = 0x2;
41                 public static readonly int IgnoreWidth = 0x10;
42                 public static readonly SqlString Null;
43
44                 #endregion // Fields
45
46                 #region Constructors
47
48                 // init with a string data
49                 public SqlString (string data) 
50                 {
51                         this.value = data;
52                         lcid = CultureInfo.CurrentCulture.LCID;
53                         notNull = true;
54                         this.compareOptions = SqlCompareOptions.None;
55                 }
56
57                 // init with a string data and locale id values.
58                 public SqlString (string data, int lcid) 
59                 {
60                         this.value = data;
61                         this.lcid = lcid;
62                         notNull = true;
63                         this.compareOptions = SqlCompareOptions.None;
64                 }
65
66                 // init with locale id, compare options, 
67                 // and an array of bytes data
68                 public SqlString (int lcid, SqlCompareOptions compareOptions, byte[] data) 
69                         : this (lcid, compareOptions, data, true) { }
70
71                 // init with string data, locale id, and compare options
72                 public SqlString (string data, int lcid, SqlCompareOptions compareOptions) 
73                 {
74                         this.value = data;
75                         this.lcid = lcid;
76                         this.compareOptions = compareOptions;
77                         notNull = true;
78                 }
79
80                 // init with locale id, compare options, array of bytes data,
81                 // and whether unicode is encoded or not
82                 public SqlString (int lcid, SqlCompareOptions compareOptions, byte[] data, bool fUnicode) 
83                 {
84                         char [] chars;
85
86                         if (fUnicode)
87                                 chars = new char [data.Length/2];
88                         else
89                                 chars = new char [data.Length];
90                         
91                         int j = 0;
92                         for (int i = 0; i < chars.Length; i++) {
93
94                                 if (fUnicode) {
95                                         chars [i] = (char)(data [j] << 16);
96                                         chars [i] += (char)data [j + 1];
97                                         j += 2;
98                                 } else {
99                                         chars [i] = (char)data[i];
100                                 }
101                         }
102                                 
103                         this.value = new String (chars);
104                         this.lcid = lcid;
105                         this.compareOptions = compareOptions;
106                         notNull = true;
107                 }
108
109                 // init with locale id, compare options, array of bytes data,
110                 // starting index in the byte array, 
111                 // and number of bytes to copy
112                 public SqlString (int lcid, SqlCompareOptions compareOptions, byte[] data, 
113                                   int index, int count) 
114                         : this (lcid, compareOptions, data, index, count, true) { }
115
116                 // init with locale id, compare options, array of bytes data,
117                 // starting index in the byte array, number of byte to copy,
118                 // and whether unicode is encoded or not
119                 public SqlString (int lcid, SqlCompareOptions compareOptions, byte[] data, int index, int count, bool fUnicode) 
120                 {                      
121                         char [] chars;
122
123                         if (fUnicode)
124                                 chars = new char [(count - index) / 2];
125                         else
126                                 chars = new char [count - index];
127                         
128                         int j = 0;
129                         for (int i = index; i < chars.Length; i++) {
130                                 
131                                 if (fUnicode) {
132                                         chars [i] = (char)(data[j] << 16);
133                                         chars [i] += (char)data[j+1];
134                                         j += 2;
135                                 } else {
136                                         chars [i] = (char)data [j];
137                                         j++;
138                                 }
139                         }
140
141                         this.value = new String (chars);
142                         this.lcid = lcid;
143                         this.compareOptions = compareOptions;
144                         notNull = true;
145                 }
146
147                 #endregion // Constructors
148
149
150                 #region Public Properties
151
152                 public CompareInfo CompareInfo {
153                         get { 
154                                 return new CultureInfo (lcid).CompareInfo;
155                         }
156                 }
157
158                 public CultureInfo CultureInfo {
159                         get { 
160                                 return new CultureInfo (lcid);
161                         }
162                 }
163
164                 public bool IsNull {
165                         get { return !notNull; }
166                 }
167
168                 // geographics location and language (locale id)
169                 public int LCID {
170                         get { 
171                                 return lcid;
172                         }
173                 }
174         
175                 public SqlCompareOptions SqlCompareOptions {
176                         get { 
177                                 return compareOptions;
178                         }
179                 }
180
181                 public string Value {
182                         get {
183                                 if (this.IsNull)
184                                         throw new SqlNullValueException (Locale.GetText ("The property contains Null."));
185                                 else
186                                         return value;
187                         }
188                 }
189
190                 #endregion // Public Properties
191
192                 #region Public Methods
193
194                 public SqlString Clone() 
195                 {
196                         return new  SqlString (value, lcid, compareOptions);
197                 }
198
199                 public static CompareOptions CompareOptionsFromSqlCompareOptions (SqlCompareOptions compareOptions) 
200                 {
201                         CompareOptions options = CompareOptions.None;
202                         
203                         if ((compareOptions & SqlCompareOptions.IgnoreCase) != 0)
204                                 options |= CompareOptions.IgnoreCase;
205                         if ((compareOptions & SqlCompareOptions.IgnoreKanaType) != 0)
206                                 options |= CompareOptions.IgnoreKanaType;
207                         if ((compareOptions & SqlCompareOptions.IgnoreNonSpace) != 0)
208                                 options |= CompareOptions.IgnoreNonSpace;
209                         if ((compareOptions & SqlCompareOptions.IgnoreWidth) != 0)
210                                 options |= CompareOptions.IgnoreWidth;
211                         if ((compareOptions & SqlCompareOptions.BinarySort) != 0)
212                                 // FIXME: Exception string
213                                 throw new ArgumentOutOfRangeException (); 
214                         
215                         return options;         
216                 }
217
218                 // **********************************
219                 // Comparison Methods
220                 // **********************************
221
222                 public int CompareTo(object value)
223                 {
224                         if (value == null)
225                                 return 1;
226                         else if (!(value is SqlString))
227                                 throw new ArgumentException (Locale.GetText ("Value is not a System.Data.SqlTypes.SqlString"));
228                         else if (((SqlString)value).IsNull)
229                                 return 1;
230                         else
231                                 return this.value.CompareTo (((SqlString)value).Value);
232                 }
233
234                 public static SqlString Concat(SqlString x, SqlString y) 
235                 {
236                         return (x + y);
237                 }
238
239                 public override bool Equals(object value) 
240                 {
241                         if (!(value is SqlString))
242                                 return false;
243                         if (this.IsNull && ((SqlString)value).IsNull)
244                                 return true;
245                         else if (((SqlString)value).IsNull)
246                                 return false;
247                         else
248                                 return (bool) (this == (SqlString)value);
249                 }
250
251                 public static SqlBoolean Equals(SqlString x, SqlString y) 
252                 {
253                         return (x == y);
254                 }
255
256                 public override int GetHashCode() 
257                 {
258                         int result = 10;
259                         for (int i = 0; i < value.Length; i++)
260                                 result = 91 * result + (int)(value [i] ^ (value [i] >> 32));
261                                                 
262                         result = 91 * result + lcid.GetHashCode ();
263                         result = 91 * result + (int)compareOptions;
264
265                         return result;
266                 }
267
268                 public byte[] GetNonUnicodeBytes() 
269                 {
270                         byte [] bytes = new byte [value.Length];
271
272                         for (int i = 0; i < bytes.Length; i++) 
273                                 bytes [i] = (byte)value [i];
274
275                         return bytes;
276                 }
277
278                 public byte[] GetUnicodeBytes() 
279                 {
280                         byte [] bytes = new byte [value.Length * 2];
281                         
282                         int j = 0;
283                         for (int i = 0; i < value.Length; i++) {                                
284                                 bytes [j] = (byte)(value [i] & 0x0000FFFF);
285                                 bytes [j + 1] = (byte)((value [i] & 0xFFFF0000) >> 16);
286                                 j += 2;
287                         }
288                         
289                         return bytes;
290                 }
291
292                 public static SqlBoolean GreaterThan(SqlString x, SqlString y) 
293                 {
294                         return (x > y);
295                 }
296
297                 public static SqlBoolean GreaterThanOrEqual(SqlString x, SqlString y) 
298                 {
299                         return (x >= y);
300                 }
301
302                 public static SqlBoolean LessThan(SqlString x, SqlString y) 
303                 {
304                         return (x < y);
305                 }
306
307                 public static SqlBoolean LessThanOrEqual(SqlString x, SqlString y) 
308                 {
309                         return (x <= y);
310                 }
311
312                 public static SqlBoolean NotEquals(SqlString x, SqlString y) 
313                 {
314                         return (x != y);
315                 }
316
317                 // ****************************************
318                 // Type Conversions From SqlString To ...
319                 // ****************************************
320
321                 public SqlBoolean ToSqlBoolean() 
322                 {
323                         return ((SqlBoolean)this);
324                 }
325
326                 public SqlByte ToSqlByte() 
327                 {
328                         return ((SqlByte)this);
329                 }
330
331                 public SqlDateTime ToSqlDateTime() 
332                 {
333                         return ((SqlDateTime)this);
334                 }
335
336                 public SqlDecimal ToSqlDecimal() 
337                 {
338                         return ((SqlDecimal)this);
339                 }
340
341                 public SqlDouble ToSqlDouble() 
342                 {
343                         return ((SqlDouble)this);
344                 }
345
346                 public SqlGuid ToSqlGuid() 
347                 {
348                         return ((SqlGuid)this);
349                 }
350
351                 public SqlInt16 ToSqlInt16() 
352                 {
353                         return ((SqlInt16)this);
354                 }
355
356                 public SqlInt32 ToSqlInt32() 
357                 {
358                         return ((SqlInt32)this);
359                 }
360
361                 public SqlInt64 ToSqlInt64() 
362                 {
363                         return ((SqlInt64)this);
364                 }
365
366                 public SqlMoney ToSqlMoney() 
367                 {
368                         return ((SqlMoney)this);
369                 }
370
371                 public SqlSingle ToSqlSingle() 
372                 {
373                         return ((SqlSingle)this);
374                 }
375
376                 public override string ToString() 
377                 {
378                         return ((string)this);
379                 }
380
381                 // ***********************************
382                 // Operators
383                 // ***********************************
384
385                 // Concatenates
386                 public static SqlString operator + (SqlString x, SqlString y) 
387                 {
388                         if (x.IsNull || y.IsNull)
389                                 return SqlString.Null;
390
391                         return new SqlString (x.Value + y.Value);
392                 }
393
394                 // Equality
395                 public static SqlBoolean operator == (SqlString x, SqlString y) 
396                 {
397                         if (x.IsNull || y.IsNull)
398                                 return SqlBoolean.Null;
399                         else
400                                 return new SqlBoolean (x.Value == y.Value);
401                 }
402
403                 // Greater Than
404                 public static SqlBoolean operator > (SqlString x, SqlString y) 
405                 {
406                         if (x.IsNull || y.IsNull)
407                                 return SqlBoolean.Null;
408                         else
409                                 throw new NotImplementedException ();
410                 }
411
412                 // Greater Than Or Equal
413                 public static SqlBoolean operator >= (SqlString x, SqlString y) 
414                 {
415                         if (x.IsNull || y.IsNull)
416                                 return SqlBoolean.Null;
417                         else
418                                 throw new NotImplementedException ();
419                 }
420
421                 public static SqlBoolean operator != (SqlString x, SqlString y) 
422                 { 
423                         if (x.IsNull || y.IsNull)
424                                 return SqlBoolean.Null;
425                         else
426                                 return new SqlBoolean (x.Value != y.Value);
427                 }
428
429                 // Less Than
430                 public static SqlBoolean operator < (SqlString x, SqlString y) 
431                 {
432                         if (x.IsNull || y.IsNull)
433                                 return SqlBoolean.Null;
434                         else
435                                 throw new NotImplementedException ();
436                 }
437
438                 // Less Than Or Equal
439                 public static SqlBoolean operator <= (SqlString x, SqlString y) 
440                 {
441                         if (x.IsNull || y.IsNull)
442                                 return SqlBoolean.Null;
443                         else
444                                 throw new NotImplementedException ();
445                 }
446
447                 // **************************************
448                 // Type Conversions
449                 // **************************************
450
451                 public static explicit operator SqlString (SqlBoolean x) 
452                 {
453                         if (x.IsNull)
454                                 return Null;
455                         else
456                                 return new SqlString (x.Value.ToString ());
457                 }
458
459                 public static explicit operator SqlString (SqlByte x) 
460                 {
461                         if (x.IsNull)
462                                 return Null;
463                         else
464                                 return new SqlString (x.Value.ToString ());
465                 }
466
467                 public static explicit operator SqlString (SqlDateTime x) 
468                 {
469                         if (x.IsNull)
470                                 return Null;
471                         else
472                                 return new SqlString (x.Value.ToString ());
473                 }
474
475                 public static explicit operator SqlString (SqlDecimal x) 
476                 {
477                         if (x.IsNull)
478                                 return Null;
479                         else
480                                 return new SqlString (x.Value.ToString ());
481                 }
482
483                 public static explicit operator SqlString (SqlDouble x) 
484                 {
485                         if (x.IsNull)
486                                 return Null;
487                         else
488                                 return new SqlString (x.Value.ToString ());
489                 }
490
491                 public static explicit operator SqlString (SqlGuid x) 
492                 {
493                         if (x.IsNull)
494                                 return Null;
495                         else
496                                 return new SqlString (x.Value.ToString ());
497                 }
498
499                 public static explicit operator SqlString (SqlInt16 x) 
500                 {
501                         if (x.IsNull)
502                                 return Null;
503                         else
504                                 return new SqlString (x.Value.ToString ());
505                 }
506
507                 public static explicit operator SqlString (SqlInt32 x) 
508                 {
509                         if (x.IsNull)
510                                 return Null;
511                         else
512                                 return new SqlString (x.Value.ToString ());
513                 }
514
515                 public static explicit operator SqlString (SqlInt64 x) 
516                 {
517                         if (x.IsNull)
518                                 return Null;
519                         else
520                                 return new SqlString (x.Value.ToString ());
521                 }
522
523                 public static explicit operator SqlString (SqlMoney x) 
524                 {
525                         if (x.IsNull)
526                                 return Null;
527                         else
528                                 return new SqlString (x.Value.ToString ());
529                 }
530
531                 public static explicit operator SqlString (SqlSingle x) 
532                 {
533                         if (x.IsNull)
534                                 return Null;
535                         else
536                                 return new SqlString (x.Value.ToString ());
537                 }
538
539                 public static explicit operator string (SqlString x) 
540                 {
541                         return x.Value;
542                 }
543
544                 public static implicit operator SqlString (string x) 
545                 {
546                         return new SqlString (x);
547                 }
548
549                 #endregion // Public Methods
550         }
551 }