2003-06-02 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                         if (index >= data.Length)
129                                 throw new ArgumentOutOfRangeException ("index");
130
131                         if ((index + count) > data.Length)
132                                 throw new ArgumentOutOfRangeException ("count");
133
134                         int j = 0;
135                         for (int i = index; i < chars.Length; i++) {
136                                 
137                                 if (fUnicode) {
138                                         chars [i] = (char)(data[j] << 16);
139                                         chars [i] += (char)data[j+1];
140                                         j += 2;
141                                 } else {
142                                         chars [i] = (char)data [j];
143                                         j++;
144                                 }
145                         }
146
147                         this.value = new String (chars);
148                         this.lcid = lcid;
149                         this.compareOptions = compareOptions;
150                         notNull = true;
151                 }
152
153                 #endregion // Constructors
154
155
156                 #region Public Properties
157
158                 public CompareInfo CompareInfo {
159                         get { 
160                                 return new CultureInfo (lcid).CompareInfo;
161                         }
162                 }
163
164                 public CultureInfo CultureInfo {
165                         get { 
166                                 return new CultureInfo (lcid);
167                         }
168                 }
169
170                 public bool IsNull {
171                         get { return !notNull; }
172                 }
173
174                 // geographics location and language (locale id)
175                 public int LCID {
176                         get { 
177                                 return lcid;
178                         }
179                 }
180         
181                 public SqlCompareOptions SqlCompareOptions {
182                         get { 
183                                 return compareOptions;
184                         }
185                 }
186
187                 public string Value {
188                         get {
189                                 if (this.IsNull)
190                                         throw new SqlNullValueException (Locale.GetText ("The property contains Null."));
191                                 else
192                                         return value;
193                         }
194                 }
195
196                 #endregion // Public Properties
197
198                 #region Public Methods
199
200                 public SqlString Clone() 
201                 {
202                         return new  SqlString (value, lcid, compareOptions);
203                 }
204
205                 public static CompareOptions CompareOptionsFromSqlCompareOptions (SqlCompareOptions compareOptions) 
206                 {
207                         CompareOptions options = CompareOptions.None;
208                         
209                         if ((compareOptions & SqlCompareOptions.IgnoreCase) != 0)
210                                 options |= CompareOptions.IgnoreCase;
211                         if ((compareOptions & SqlCompareOptions.IgnoreKanaType) != 0)
212                                 options |= CompareOptions.IgnoreKanaType;
213                         if ((compareOptions & SqlCompareOptions.IgnoreNonSpace) != 0)
214                                 options |= CompareOptions.IgnoreNonSpace;
215                         if ((compareOptions & SqlCompareOptions.IgnoreWidth) != 0)
216                                 options |= CompareOptions.IgnoreWidth;
217                         if ((compareOptions & SqlCompareOptions.BinarySort) != 0)
218                                 // FIXME: Exception string
219                                 throw new ArgumentOutOfRangeException (); 
220                         
221                         return options;         
222                 }
223
224                 // **********************************
225                 // Comparison Methods
226                 // **********************************
227
228                 public int CompareTo(object value)
229                 {
230                         if (value == null)
231                                 return 1;
232                         else if (!(value is SqlString))
233                                 throw new ArgumentException (Locale.GetText ("Value is not a System.Data.SqlTypes.SqlString"));
234                         else if (((SqlString)value).IsNull)
235                                 return 1;
236                         else
237                                 return this.value.CompareTo (((SqlString)value).Value);
238                 }
239
240                 public static SqlString Concat(SqlString x, SqlString y) 
241                 {
242                         return (x + y);
243                 }
244
245                 public override bool Equals(object value) 
246                 {
247                         if (!(value is SqlString))
248                                 return false;
249                         if (this.IsNull && ((SqlString)value).IsNull)
250                                 return true;
251                         else if (((SqlString)value).IsNull)
252                                 return false;
253                         else
254                                 return (bool) (this == (SqlString)value);
255                 }
256
257                 public static SqlBoolean Equals(SqlString x, SqlString y) 
258                 {
259                         return (x == y);
260                 }
261
262                 public override int GetHashCode() 
263                 {
264                         int result = 10;
265                         for (int i = 0; i < value.Length; i++)
266                                 result = 91 * result + (int)(value [i] ^ (value [i] >> 32));
267                                                 
268                         result = 91 * result + lcid.GetHashCode ();
269                         result = 91 * result + (int)compareOptions;
270
271                         return result;
272                 }
273
274                 public byte[] GetNonUnicodeBytes() 
275                 {
276                         byte [] bytes = new byte [value.Length];
277
278                         for (int i = 0; i < bytes.Length; i++) 
279                                 bytes [i] = (byte)value [i];
280
281                         return bytes;
282                 }
283
284                 public byte[] GetUnicodeBytes() 
285                 {
286                         byte [] bytes = new byte [value.Length * 2];
287                         
288                         int j = 0;
289                         for (int i = 0; i < value.Length; i++) {                                
290                                 bytes [j] = (byte)(value [i] & 0x0000FFFF);
291                                 bytes [j + 1] = (byte)((value [i] & 0xFFFF0000) >> 16);
292                                 j += 2;
293                         }
294                         
295                         return bytes;
296                 }
297
298                 public static SqlBoolean GreaterThan(SqlString x, SqlString y) 
299                 {
300                         return (x > y);
301                 }
302
303                 public static SqlBoolean GreaterThanOrEqual(SqlString x, SqlString y) 
304                 {
305                         return (x >= y);
306                 }
307
308                 public static SqlBoolean LessThan(SqlString x, SqlString y) 
309                 {
310                         return (x < y);
311                 }
312
313                 public static SqlBoolean LessThanOrEqual(SqlString x, SqlString y) 
314                 {
315                         return (x <= y);
316                 }
317
318                 public static SqlBoolean NotEquals(SqlString x, SqlString y) 
319                 {
320                         return (x != y);
321                 }
322
323                 // ****************************************
324                 // Type Conversions From SqlString To ...
325                 // ****************************************
326
327                 public SqlBoolean ToSqlBoolean() 
328                 {
329                         return ((SqlBoolean)this);
330                 }
331
332                 public SqlByte ToSqlByte() 
333                 {
334                         return ((SqlByte)this);
335                 }
336
337                 public SqlDateTime ToSqlDateTime() 
338                 {
339                         return ((SqlDateTime)this);
340                 }
341
342                 public SqlDecimal ToSqlDecimal() 
343                 {
344                         return ((SqlDecimal)this);
345                 }
346
347                 public SqlDouble ToSqlDouble() 
348                 {
349                         return ((SqlDouble)this);
350                 }
351
352                 public SqlGuid ToSqlGuid() 
353                 {
354                         return ((SqlGuid)this);
355                 }
356
357                 public SqlInt16 ToSqlInt16() 
358                 {
359                         return ((SqlInt16)this);
360                 }
361
362                 public SqlInt32 ToSqlInt32() 
363                 {
364                         return ((SqlInt32)this);
365                 }
366
367                 public SqlInt64 ToSqlInt64() 
368                 {
369                         return ((SqlInt64)this);
370                 }
371
372                 public SqlMoney ToSqlMoney() 
373                 {
374                         return ((SqlMoney)this);
375                 }
376
377                 public SqlSingle ToSqlSingle() 
378                 {
379                         return ((SqlSingle)this);
380                 }
381
382                 public override string ToString() 
383                 {
384                         return ((string)this);
385                 }
386
387                 // ***********************************
388                 // Operators
389                 // ***********************************
390
391                 // Concatenates
392                 public static SqlString operator + (SqlString x, SqlString y) 
393                 {
394                         if (x.IsNull || y.IsNull)
395                                 return SqlString.Null;
396
397                         return new SqlString (x.Value + y.Value);
398                 }
399
400                 // Equality
401                 public static SqlBoolean operator == (SqlString x, SqlString y) 
402                 {
403                         if (x.IsNull || y.IsNull)
404                                 return SqlBoolean.Null;
405                         else
406                                 return new SqlBoolean (x.Value == y.Value);
407                 }
408
409                 // Greater Than
410                 public static SqlBoolean operator > (SqlString x, SqlString y) 
411                 {
412                         if (x.IsNull || y.IsNull)
413                                 return SqlBoolean.Null;
414                         else
415                                 return new SqlBoolean (x.CompareTo (y) > 0);
416                 }
417
418                 // Greater Than Or Equal
419                 public static SqlBoolean operator >= (SqlString x, SqlString y) 
420                 {
421                         if (x.IsNull || y.IsNull)
422                                 return SqlBoolean.Null;
423                         else
424                                 return new SqlBoolean (x.CompareTo (y) >= 0);
425                 }
426
427                 public static SqlBoolean operator != (SqlString x, SqlString y) 
428                 { 
429                         if (x.IsNull || y.IsNull)
430                                 return SqlBoolean.Null;
431                         else
432                                 return new SqlBoolean (x.Value != y.Value);
433                 }
434
435                 // Less Than
436                 public static SqlBoolean operator < (SqlString x, SqlString y) 
437                 {
438                         if (x.IsNull || y.IsNull)
439                                 return SqlBoolean.Null;
440                         else
441                                 return new SqlBoolean (x.CompareTo (y) < 0);
442                 }
443
444                 // Less Than Or Equal
445                 public static SqlBoolean operator <= (SqlString x, SqlString y) 
446                 {
447                         if (x.IsNull || y.IsNull)
448                                 return SqlBoolean.Null;
449                         else
450                                 return new SqlBoolean (x.CompareTo (y) <= 0);
451                 }
452
453                 // **************************************
454                 // Type Conversions
455                 // **************************************
456
457                 public static explicit operator SqlString (SqlBoolean x) 
458                 {
459                         if (x.IsNull)
460                                 return Null;
461                         else
462                                 return new SqlString (x.Value.ToString ());
463                 }
464
465                 public static explicit operator SqlString (SqlByte x) 
466                 {
467                         if (x.IsNull)
468                                 return Null;
469                         else
470                                 return new SqlString (x.Value.ToString ());
471                 }
472
473                 public static explicit operator SqlString (SqlDateTime x) 
474                 {
475                         if (x.IsNull)
476                                 return Null;
477                         else
478                                 return new SqlString (x.Value.ToString ());
479                 }
480
481                 public static explicit operator SqlString (SqlDecimal x) 
482                 {
483                         if (x.IsNull)
484                                 return Null;
485                         else
486                                 return new SqlString (x.Value.ToString ());
487                 }
488
489                 public static explicit operator SqlString (SqlDouble x) 
490                 {
491                         if (x.IsNull)
492                                 return Null;
493                         else
494                                 return new SqlString (x.Value.ToString ());
495                 }
496
497                 public static explicit operator SqlString (SqlGuid x) 
498                 {
499                         if (x.IsNull)
500                                 return Null;
501                         else
502                                 return new SqlString (x.Value.ToString ());
503                 }
504
505                 public static explicit operator SqlString (SqlInt16 x) 
506                 {
507                         if (x.IsNull)
508                                 return Null;
509                         else
510                                 return new SqlString (x.Value.ToString ());
511                 }
512
513                 public static explicit operator SqlString (SqlInt32 x) 
514                 {
515                         if (x.IsNull)
516                                 return Null;
517                         else
518                                 return new SqlString (x.Value.ToString ());
519                 }
520
521                 public static explicit operator SqlString (SqlInt64 x) 
522                 {
523                         if (x.IsNull)
524                                 return Null;
525                         else
526                                 return new SqlString (x.Value.ToString ());
527                 }
528
529                 public static explicit operator SqlString (SqlMoney x) 
530                 {
531                         if (x.IsNull)
532                                 return Null;
533                         else
534                                 return new SqlString (x.Value.ToString ());
535                 }
536
537                 public static explicit operator SqlString (SqlSingle x) 
538                 {
539                         if (x.IsNull)
540                                 return Null;
541                         else
542                                 return new SqlString (x.Value.ToString ());
543                 }
544
545                 public static explicit operator string (SqlString x) 
546                 {
547                         return x.Value;
548                 }
549
550                 public static implicit operator SqlString (string x) 
551                 {
552                         return new SqlString (x);
553                 }
554
555                 #endregion // Public Methods
556         }
557 }