* SqlString.cs: changed accessibility of CompareOptions property
[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                 internal static readonly NumberFormatInfo MoneyFormat;
45                 internal static NumberFormatInfo DecimalFormat;
46                 #endregion // Fields
47
48                 #region Constructors
49
50                 static SqlString ()
51                 {
52                         MoneyFormat = (NumberFormatInfo) NumberFormatInfo.InvariantInfo.Clone ();
53                         MoneyFormat.NumberDecimalDigits = 4;
54                         MoneyFormat.NumberGroupSeparator = String.Empty;
55
56                         DecimalFormat = (NumberFormatInfo) NumberFormatInfo.InvariantInfo.Clone ();
57                         DecimalFormat.NumberDecimalDigits = 13;
58                         DecimalFormat.NumberGroupSeparator = String.Empty;
59                 }
60
61                 // init with a string data
62                 public SqlString (string data) 
63                 {
64                         this.value = data;
65                         lcid = CultureInfo.CurrentCulture.LCID;
66                         notNull = true;
67                         this.compareOptions = SqlCompareOptions.IgnoreCase |
68                                 SqlCompareOptions.IgnoreKanaType |
69                                 SqlCompareOptions.IgnoreWidth;
70                 }
71
72                 // init with a string data and locale id values.
73                 public SqlString (string data, int lcid) 
74                 {
75                         this.value = data;
76                         this.lcid = lcid;
77                         notNull = true;
78                         this.compareOptions = SqlCompareOptions.IgnoreCase |
79                                 SqlCompareOptions.IgnoreKanaType |
80                                 SqlCompareOptions.IgnoreWidth;
81                 }
82
83                 // init with locale id, compare options, 
84                 // and an array of bytes data
85                 public SqlString (int lcid, SqlCompareOptions compareOptions, byte[] data) 
86                         : this (lcid, compareOptions, data, true) { }
87
88                 // init with string data, locale id, and compare options
89                 public SqlString (string data, int lcid, SqlCompareOptions compareOptions) 
90                 {
91                         this.value = data;
92                         this.lcid = lcid;
93                         this.compareOptions = compareOptions;
94                         notNull = true;
95                 }
96
97                 // init with locale id, compare options, array of bytes data,
98                 // and whether unicode is encoded or not
99                 public SqlString (int lcid, SqlCompareOptions compareOptions, byte[] data, bool fUnicode) 
100                 {
101                         char [] chars;
102
103                         if (fUnicode)
104                                 chars = new char [data.Length/2];
105                         else
106                                 chars = new char [data.Length];
107                         
108                         int j = 0;
109                         for (int i = 0; i < chars.Length; i++) {
110
111                                 if (fUnicode) {
112                                         chars [i] = (char)(data [j] << 16);
113                                         chars [i] += (char)data [j + 1];
114                                         j += 2;
115                                 } else {
116                                         chars [i] = (char)data[i];
117                                 }
118                         }
119                                 
120                         this.value = new String (chars);
121                         this.lcid = lcid;
122                         this.compareOptions = compareOptions;
123                         notNull = true;
124                 }
125
126                 // init with locale id, compare options, array of bytes data,
127                 // starting index in the byte array, 
128                 // and number of bytes to copy
129                 public SqlString (int lcid, SqlCompareOptions compareOptions, byte[] data, 
130                                   int index, int count) 
131                         : this (lcid, compareOptions, data, index, count, true) { }
132
133                 // init with locale id, compare options, array of bytes data,
134                 // starting index in the byte array, number of byte to copy,
135                 // and whether unicode is encoded or not
136                 public SqlString (int lcid, SqlCompareOptions compareOptions, byte[] data, int index, int count, bool fUnicode) 
137                 {                      
138                         char [] chars;
139
140                         if (fUnicode)
141                                 chars = new char [(count - index) / 2];
142                         else
143                                 chars = new char [count - index];
144
145                         if (index >= data.Length)
146                                 throw new ArgumentOutOfRangeException ("index");
147
148                         if ((index + count) > data.Length)
149                                 throw new ArgumentOutOfRangeException ("count");
150
151                         int j = 0;
152                         for (int i = index; i < chars.Length; i++) {
153                                 
154                                 if (fUnicode) {
155                                         chars [i] = (char)(data[j] << 16);
156                                         chars [i] += (char)data[j+1];
157                                         j += 2;
158                                 } else {
159                                         chars [i] = (char)data [j];
160                                         j++;
161                                 }
162                         }
163
164                         this.value = new String (chars);
165                         this.lcid = lcid;
166                         this.compareOptions = compareOptions;
167                         notNull = true;
168                 }
169
170                 #endregion // Constructors
171
172
173                 #region Public Properties
174
175                 public CompareInfo CompareInfo {
176                         get { 
177                                 return new CultureInfo (lcid).CompareInfo;
178                         }
179                 }
180
181                 public CultureInfo CultureInfo {
182                         get { 
183                                 return new CultureInfo (lcid);
184                         }
185                 }
186
187                 public bool IsNull {
188                         get { return !notNull; }
189                 }
190
191                 // geographics location and language (locale id)
192                 public int LCID {
193                         get { 
194                                 return lcid;
195                         }
196                 }
197         
198                 public SqlCompareOptions SqlCompareOptions {
199                         get { 
200                                 return compareOptions;
201                         }
202                 }
203
204                 public string Value {
205                         get {
206                                 if (this.IsNull)
207                                         throw new SqlNullValueException (Locale.GetText ("The property contains Null."));
208                                 else
209                                         return value;
210                         }
211                 }
212
213                 #endregion // Public Properties\r
214 \r
215                 #region Private Properties\r
216 \r
217                 private CompareOptions CompareOptions {\r
218                         get {\r
219                                 return\r
220                                         (this.compareOptions & SqlCompareOptions.BinarySort) != 0 ?\r
221                                         CompareOptions.Ordinal :\r
222                                         // 27 == all SqlCompareOptions - BinarySort \r
223                                         // (1,2,8,24 are common to CompareOptions)\r
224                                         (CompareOptions)((int)this.compareOptions & 27);\r
225                         }\r
226                 }\r
227 \r
228                 #endregion Private Properties
229
230                 #region Public Methods
231
232                 public SqlString Clone() 
233                 {
234                         return new  SqlString (value, lcid, compareOptions);
235                 }
236
237                 public static CompareOptions CompareOptionsFromSqlCompareOptions (SqlCompareOptions compareOptions) 
238                 {
239                         CompareOptions options = CompareOptions.None;
240                         
241                         if ((compareOptions & SqlCompareOptions.IgnoreCase) != 0)
242                                 options |= CompareOptions.IgnoreCase;
243                         if ((compareOptions & SqlCompareOptions.IgnoreKanaType) != 0)
244                                 options |= CompareOptions.IgnoreKanaType;
245                         if ((compareOptions & SqlCompareOptions.IgnoreNonSpace) != 0)
246                                 options |= CompareOptions.IgnoreNonSpace;
247                         if ((compareOptions & SqlCompareOptions.IgnoreWidth) != 0)
248                                 options |= CompareOptions.IgnoreWidth;
249                         if ((compareOptions & SqlCompareOptions.BinarySort) != 0)
250                                 // FIXME: Exception string
251                                 throw new ArgumentOutOfRangeException (); 
252                         
253                         return options;         
254                 }
255
256                 // **********************************
257                 // Comparison Methods
258                 // **********************************
259
260                 public int CompareTo (object value)
261                 {
262                         if (value == null)
263                                 return 1;
264                         else if (!(value is SqlString))
265                                 throw new ArgumentException (Locale.GetText ("Value is not a System.Data.SqlTypes.SqlString"));
266                         else if (((SqlString)value).IsNull)
267                                 return 1;
268 //                      else
269 //                              return String.Compare (this.value, ((SqlString)value).Value, (this.SqlCompareOptions & SqlCompareOptions.IgnoreCase) != 0, this.CultureInfo);
270                         return CultureInfo.CompareInfo.Compare (this.value, ((SqlString)value).Value, this.CompareOptions);
271                 }
272
273                 public static SqlString Concat(SqlString x, SqlString y) 
274                 {
275                         return (x + y);
276                 }
277
278                 public override bool Equals(object value) 
279                 {
280                         if (!(value is SqlString))
281                                 return false;
282                         if (this.IsNull && ((SqlString)value).IsNull)
283                                 return true;
284                         else if (((SqlString)value).IsNull)
285                                 return false;
286                         else
287                                 return (bool) (this == (SqlString)value);
288                 }
289
290                 public static SqlBoolean Equals(SqlString x, SqlString y) 
291                 {
292                         return (x == y);
293                 }
294
295                 public override int GetHashCode() 
296                 {
297                         int result = 10;
298                         for (int i = 0; i < value.Length; i++)
299                                 result = 91 * result + (int)(value [i] ^ (value [i] >> 32));
300                                                 
301                         result = 91 * result + lcid.GetHashCode ();
302                         result = 91 * result + (int)compareOptions;
303
304                         return result;
305                 }
306
307                 public byte[] GetNonUnicodeBytes() 
308                 {
309                         byte [] bytes = new byte [value.Length];
310
311                         for (int i = 0; i < bytes.Length; i++) 
312                                 bytes [i] = (byte)value [i];
313
314                         return bytes;
315                 }
316
317                 public byte[] GetUnicodeBytes() 
318                 {
319                         byte [] bytes = new byte [value.Length * 2];
320                         
321                         int j = 0;
322                         for (int i = 0; i < value.Length; i++) {                                
323                                 bytes [j] = (byte)(value [i] & 0x0000FFFF);
324                                 bytes [j + 1] = (byte)((value [i] & 0xFFFF0000) >> 16);
325                                 j += 2;
326                         }
327                         
328                         return bytes;
329                 }
330
331                 public static SqlBoolean GreaterThan(SqlString x, SqlString y) 
332                 {
333                         return (x > y);
334                 }
335
336                 public static SqlBoolean GreaterThanOrEqual(SqlString x, SqlString y) 
337                 {
338                         return (x >= y);
339                 }
340
341                 public static SqlBoolean LessThan(SqlString x, SqlString y) 
342                 {
343                         return (x < y);
344                 }
345
346                 public static SqlBoolean LessThanOrEqual(SqlString x, SqlString y) 
347                 {
348                         return (x <= y);
349                 }
350
351                 public static SqlBoolean NotEquals(SqlString x, SqlString y) 
352                 {
353                         return (x != y);
354                 }
355
356                 // ****************************************
357                 // Type Conversions From SqlString To ...
358                 // ****************************************
359
360                 public SqlBoolean ToSqlBoolean() 
361                 {
362                         return ((SqlBoolean)this);
363                 }
364
365                 public SqlByte ToSqlByte() 
366                 {
367                         return ((SqlByte)this);
368                 }
369
370                 public SqlDateTime ToSqlDateTime() 
371                 {
372                         return ((SqlDateTime)this);
373                 }
374
375                 public SqlDecimal ToSqlDecimal() 
376                 {
377                         return ((SqlDecimal)this);
378                 }
379
380                 public SqlDouble ToSqlDouble() 
381                 {
382                         return ((SqlDouble)this);
383                 }
384
385                 public SqlGuid ToSqlGuid() 
386                 {
387                         return ((SqlGuid)this);
388                 }
389
390                 public SqlInt16 ToSqlInt16() 
391                 {
392                         return ((SqlInt16)this);
393                 }
394
395                 public SqlInt32 ToSqlInt32() 
396                 {
397                         return ((SqlInt32)this);
398                 }
399
400                 public SqlInt64 ToSqlInt64() 
401                 {
402                         return ((SqlInt64)this);
403                 }
404
405                 public SqlMoney ToSqlMoney() 
406                 {
407                         return ((SqlMoney)this);
408                 }
409
410                 public SqlSingle ToSqlSingle() 
411                 {
412                         return ((SqlSingle)this);
413                 }
414
415                 public override string ToString() 
416                 {
417                         return ((string)this);
418                 }
419
420                 // ***********************************
421                 // Operators
422                 // ***********************************
423
424                 // Concatenates
425                 public static SqlString operator + (SqlString x, SqlString y) 
426                 {
427                         if (x.IsNull || y.IsNull)
428                                 return SqlString.Null;
429
430                         return new SqlString (x.Value + y.Value);
431                 }
432
433                 // Equality
434                 public static SqlBoolean operator == (SqlString x, SqlString y) 
435                 {
436                         if (x.IsNull || y.IsNull)
437                                 return SqlBoolean.Null;
438                         else
439                                 return new SqlBoolean (x.Value == y.Value);
440                 }
441
442                 // Greater Than
443                 public static SqlBoolean operator > (SqlString x, SqlString y) 
444                 {
445                         if (x.IsNull || y.IsNull)
446                                 return SqlBoolean.Null;
447                         else
448                                 return new SqlBoolean (x.CompareTo (y) > 0);
449                 }
450
451                 // Greater Than Or Equal
452                 public static SqlBoolean operator >= (SqlString x, SqlString y) 
453                 {
454                         if (x.IsNull || y.IsNull)
455                                 return SqlBoolean.Null;
456                         else
457                                 return new SqlBoolean (x.CompareTo (y) >= 0);
458                 }
459
460                 public static SqlBoolean operator != (SqlString x, SqlString y) 
461                 { 
462                         if (x.IsNull || y.IsNull)
463                                 return SqlBoolean.Null;
464                         else
465                                 return new SqlBoolean (x.Value != y.Value);
466                 }
467
468                 // Less Than
469                 public static SqlBoolean operator < (SqlString x, SqlString y) 
470                 {
471                         if (x.IsNull || y.IsNull)
472                                 return SqlBoolean.Null;
473                         else
474                                 return new SqlBoolean (x.CompareTo (y) < 0);
475                 }
476
477                 // Less Than Or Equal
478                 public static SqlBoolean operator <= (SqlString x, SqlString y) 
479                 {
480                         if (x.IsNull || y.IsNull)
481                                 return SqlBoolean.Null;
482                         else
483                                 return new SqlBoolean (x.CompareTo (y) <= 0);
484                 }
485
486                 // **************************************
487                 // Type Conversions
488                 // **************************************
489
490                 public static explicit operator SqlString (SqlBoolean x) 
491                 {
492                         if (x.IsNull)
493                                 return Null;
494                         else
495                                 return new SqlString (x.Value.ToString ());
496                 }
497
498                 public static explicit operator SqlString (SqlByte x) 
499                 {
500                         if (x.IsNull)
501                                 return Null;
502                         else
503                                 return new SqlString (x.Value.ToString ());
504                 }
505
506                 public static explicit operator SqlString (SqlDateTime x) 
507                 {
508                         if (x.IsNull)
509                                 return Null;
510                         else
511                                 return new SqlString (x.Value.ToString ());
512                 }
513
514                 public static explicit operator SqlString (SqlDecimal x)
515                 {
516                         if (x.IsNull)
517                                 return Null;
518                         else
519                                 return new SqlString (x.Value.ToString ());
520                                 // return new SqlString (x.Value.ToString ("N", DecimalFormat));
521                 }
522
523                 public static explicit operator SqlString (SqlDouble 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 (SqlGuid 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 SqlString (SqlInt16 x) 
540                 {
541                         if (x.IsNull)
542                                 return Null;
543                         else
544                                 return new SqlString (x.Value.ToString ());
545                 }
546
547                 public static explicit operator SqlString (SqlInt32 x) 
548                 {
549                         if (x.IsNull)
550                                 return Null;
551                         else
552                                 return new SqlString (x.Value.ToString ());
553                 }
554
555                 public static explicit operator SqlString (SqlInt64 x) 
556                 {
557                         if (x.IsNull)
558                                 return Null;
559                         else
560                                 return new SqlString (x.Value.ToString ());
561                 }
562
563                 public static explicit operator SqlString (SqlMoney x) 
564                 {
565                         if (x.IsNull)
566                                 return Null;
567                         else
568                                 return new SqlString (x.Value.ToString ());
569                                 // return new SqlString (x.Value.ToString ("N", MoneyFormat));
570                 }
571
572                 public static explicit operator SqlString (SqlSingle x) 
573                 {
574                         if (x.IsNull)
575                                 return Null;
576                         else
577                                 return new SqlString (x.Value.ToString ());
578                 }
579
580                 public static explicit operator string (SqlString x) 
581                 {
582                         return x.Value;
583                 }
584
585                 public static implicit operator SqlString (string x) 
586                 {
587                         return new SqlString (x);
588                 }
589
590                 #endregion // Public Methods
591         }
592 }