2007-07-24 Nagappan A <anagappan@novell.com>
[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 //
15 // Copyright (C) 2004 Novell, Inc (http://www.novell.com)
16 //
17 // Permission is hereby granted, free of charge, to any person obtaining
18 // a copy of this software and associated documentation files (the
19 // "Software"), to deal in the Software without restriction, including
20 // without limitation the rights to use, copy, modify, merge, publish,
21 // distribute, sublicense, and/or sell copies of the Software, and to
22 // permit persons to whom the Software is furnished to do so, subject to
23 // the following conditions:
24 // 
25 // The above copyright notice and this permission notice shall be
26 // included in all copies or substantial portions of the Software.
27 // 
28 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
29 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
30 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
31 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
32 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
33 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
34 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
35 //
36
37 using System;
38 using System.Xml;
39 using System.Text;
40 using System.Threading;
41 using System.Xml.Schema;
42 using System.Globalization;
43 using System.Xml.Serialization;
44
45 namespace System.Data.SqlTypes
46 {
47         /// <summary>
48         /// A variable-length stream of characters 
49         /// to be stored in or retrieved from the database
50         /// </summary>
51 #if NET_2_0
52         [SerializableAttribute]
53         [XmlSchemaProvider ("GetXsdType")]
54 #endif
55         public struct SqlString : INullable, IComparable 
56 #if NET_2_0
57                                 , IXmlSerializable
58 #endif
59         {
60
61                 #region Fields
62
63                 string value;
64
65                 private bool notNull;
66
67                 // FIXME: locale id is not working yet
68                 private int lcid;
69                 private SqlCompareOptions compareOptions;
70
71                 public static readonly int BinarySort = 0x8000;
72                 public static readonly int IgnoreCase = 0x1;
73                 public static readonly int IgnoreKanaType = 0x8;
74                 public static readonly int IgnoreNonSpace = 0x2;
75                 public static readonly int IgnoreWidth = 0x10;
76                 public static readonly SqlString Null;
77
78                 internal static NumberFormatInfo DecimalFormat;
79                 #endregion // Fields
80
81                 #region Constructors
82
83                 static SqlString ()
84                 {
85                         DecimalFormat = (NumberFormatInfo) NumberFormatInfo.InvariantInfo.Clone ();
86                         DecimalFormat.NumberDecimalDigits = 13;
87                         DecimalFormat.NumberGroupSeparator = String.Empty;
88                 }
89
90                 // init with a string data
91                 public SqlString (string data) 
92                 {
93                         this.value = data;
94                         lcid = CultureInfo.CurrentCulture.LCID;
95                         notNull = true;
96                         this.compareOptions = SqlCompareOptions.IgnoreCase |
97                                 SqlCompareOptions.IgnoreKanaType |
98                                 SqlCompareOptions.IgnoreWidth;
99                 }
100
101                 // init with a string data and locale id values.
102                 public SqlString (string data, int lcid) 
103                 {
104                         this.value = data;
105                         this.lcid = lcid;
106                         notNull = true;
107                         this.compareOptions = SqlCompareOptions.IgnoreCase |
108                                 SqlCompareOptions.IgnoreKanaType |
109                                 SqlCompareOptions.IgnoreWidth;
110                 }
111
112                 // init with locale id, compare options, 
113                 // and an array of bytes data
114                 public SqlString (int lcid, SqlCompareOptions compareOptions, byte[] data) 
115                         : this (lcid, compareOptions, data, true) { }
116
117                 // init with string data, locale id, and compare options
118                 public SqlString (string data, int lcid, SqlCompareOptions compareOptions) 
119                 {
120                         this.value = data;
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                 // and whether unicode is encoded or not
128                 public SqlString (int lcid, SqlCompareOptions compareOptions, byte[] data, bool fUnicode) 
129                 {
130                         Encoding encoding = (fUnicode ? Encoding.Unicode : Encoding.ASCII);
131                         this.value = encoding.GetString (data);
132                         this.lcid = lcid;
133                         this.compareOptions = compareOptions;
134                         notNull = true;
135                 }
136
137                 // init with locale id, compare options, array of bytes data,
138                 // starting index in the byte array, 
139                 // and number of bytes to copy
140                 public SqlString (int lcid, SqlCompareOptions compareOptions, byte[] data, 
141                                   int index, int count) 
142                         : this (lcid, compareOptions, data, index, count, true) { }
143
144                 // init with locale id, compare options, array of bytes data,
145                 // starting index in the byte array, number of byte to copy,
146                 // and whether unicode is encoded or not
147                 public SqlString (int lcid, SqlCompareOptions compareOptions, byte[] data, int index, int count, bool fUnicode) 
148                 {                      
149                         Encoding encoding = (fUnicode ? Encoding.Unicode : Encoding.ASCII);
150                         this.value = encoding.GetString (data, index, count);
151                         this.lcid = lcid;
152                         this.compareOptions = compareOptions;
153                         notNull = true;
154                 }
155
156                 #endregion // Constructors
157
158
159                 #region Public Properties
160
161                 public CompareInfo CompareInfo {
162                         get { 
163                                 return new CultureInfo (lcid).CompareInfo;
164                         }
165                 }
166
167                 public CultureInfo CultureInfo {
168                         get { 
169                                 return new CultureInfo (lcid);
170                         }
171                 }
172
173                 public bool IsNull {
174                         get { return !notNull; }
175                 }
176
177                 // geographics location and language (locale id)
178                 public int LCID {
179                         get { 
180                                 return lcid;
181                         }
182                 }
183         
184                 public SqlCompareOptions SqlCompareOptions {
185                         get { 
186                                 return compareOptions;
187                         }
188                 }
189
190                 public string Value {
191                         get {
192                                 if (this.IsNull)
193                                         throw new SqlNullValueException (Locale.GetText ("The property contains Null."));
194                                 else
195                                         return value;
196                         }
197                 }
198
199                 #endregion // Public Properties
200
201                 #region Private Properties
202
203                 private CompareOptions CompareOptions {
204                         get {
205                                 return
206                                         (this.compareOptions & SqlCompareOptions.BinarySort) != 0 ?
207                                         CompareOptions.Ordinal :
208                                         // 27 == all SqlCompareOptions - BinarySort 
209                                         // (1,2,8,24 are common to CompareOptions)
210                                         (CompareOptions)((int)this.compareOptions & 27);
211                         }
212                 }
213
214                 #endregion Private Properties
215
216                 #region Public Methods
217
218                 public SqlString Clone() 
219                 {
220                         return new  SqlString (value, lcid, compareOptions);
221                 }
222
223                 public static CompareOptions CompareOptionsFromSqlCompareOptions (SqlCompareOptions compareOptions) 
224                 {
225                         CompareOptions options = CompareOptions.None;
226                         
227                         if ((compareOptions & SqlCompareOptions.IgnoreCase) != 0)
228                                 options |= CompareOptions.IgnoreCase;
229                         if ((compareOptions & SqlCompareOptions.IgnoreKanaType) != 0)
230                                 options |= CompareOptions.IgnoreKanaType;
231                         if ((compareOptions & SqlCompareOptions.IgnoreNonSpace) != 0)
232                                 options |= CompareOptions.IgnoreNonSpace;
233                         if ((compareOptions & SqlCompareOptions.IgnoreWidth) != 0)
234                                 options |= CompareOptions.IgnoreWidth;
235                         if ((compareOptions & SqlCompareOptions.BinarySort) != 0)
236                                 // FIXME: Exception string
237                                 throw new ArgumentOutOfRangeException (); 
238                         
239                         return options;         
240                 }
241
242                 // **********************************
243                 // Comparison Methods
244                 // **********************************
245
246                 public int CompareTo (object value)
247                 {
248                         if (value == null)
249                                 return 1;
250                         else if (!(value is SqlString))
251                                 throw new ArgumentException (Locale.GetText ("Value is not a System.Data.SqlTypes.SqlString"));
252                         
253                         return CompareSqlString ((SqlString)value);
254                 }
255
256                 
257                 private int CompareSqlString (SqlString value)
258                 {
259                         if (value.IsNull)
260                                 return 1;
261                         else if (value.CompareOptions != this.CompareOptions)
262                                 throw new SqlTypeException (Locale.GetText ("Two strings to be compared have different collation"));
263 //                      else
264 //                              return String.Compare (this.value, ((SqlString)value).Value, (this.SqlCompareOptions & SqlCompareOptions.IgnoreCase) != 0, this.CultureInfo);
265                         return CultureInfo.CompareInfo.Compare (this.value, value.Value, this.CompareOptions);
266                 }
267
268                 public static SqlString Concat(SqlString x, SqlString y) 
269                 {
270                         return (x + y);
271                 }
272
273                 public override bool Equals(object value) 
274                 {
275                         if (!(value is SqlString))
276                                 return false;
277                         if (this.IsNull && ((SqlString)value).IsNull)
278                                 return true;
279                         else if (((SqlString)value).IsNull)
280                                 return false;
281                         else
282                                 return (bool) (this == (SqlString)value);
283                 }
284
285                 public static SqlBoolean Equals(SqlString x, SqlString y) 
286                 {
287                         return (x == y);
288                 }
289
290                 public override int GetHashCode() 
291                 {
292                         int result = 10;
293                         for (int i = 0; i < value.Length; i++)
294                                 result = 91 * result + (int)(value [i] ^ (value [i] >> 32));
295                                                 
296                         result = 91 * result + lcid.GetHashCode ();
297                         result = 91 * result + (int)compareOptions;
298
299                         return result;
300                 }
301
302                 public byte[] GetNonUnicodeBytes() 
303                 {
304                         return Encoding.ASCII.GetBytes (value);
305                 }
306
307                 public byte[] GetUnicodeBytes() 
308                 {
309                         return Encoding.Unicode.GetBytes (value);
310                 }
311
312                 public static SqlBoolean GreaterThan(SqlString x, SqlString y) 
313                 {
314                         return (x > y);
315                 }
316
317                 public static SqlBoolean GreaterThanOrEqual(SqlString x, SqlString y) 
318                 {
319                         return (x >= y);
320                 }
321
322                 public static SqlBoolean LessThan(SqlString x, SqlString y) 
323                 {
324                         return (x < y);
325                 }
326
327                 public static SqlBoolean LessThanOrEqual(SqlString x, SqlString y) 
328                 {
329                         return (x <= y);
330                 }
331
332                 public static SqlBoolean NotEquals(SqlString x, SqlString y) 
333                 {
334                         return (x != y);
335                 }
336
337                 // ****************************************
338                 // Type Conversions From SqlString To ...
339                 // ****************************************
340
341                 public SqlBoolean ToSqlBoolean() 
342                 {
343                         return ((SqlBoolean)this);
344                 }
345
346                 public SqlByte ToSqlByte() 
347                 {
348                         return ((SqlByte)this);
349                 }
350
351                 public SqlDateTime ToSqlDateTime() 
352                 {
353                         return ((SqlDateTime)this);
354                 }
355
356                 public SqlDecimal ToSqlDecimal() 
357                 {
358                         return ((SqlDecimal)this);
359                 }
360
361                 public SqlDouble ToSqlDouble() 
362                 {
363                         return ((SqlDouble)this);
364                 }
365
366                 public SqlGuid ToSqlGuid() 
367                 {
368                         return ((SqlGuid)this);
369                 }
370
371                 public SqlInt16 ToSqlInt16() 
372                 {
373                         return ((SqlInt16)this);
374                 }
375
376                 public SqlInt32 ToSqlInt32() 
377                 {
378                         return ((SqlInt32)this);
379                 }
380
381                 public SqlInt64 ToSqlInt64() 
382                 {
383                         return ((SqlInt64)this);
384                 }
385
386                 public SqlMoney ToSqlMoney() 
387                 {
388                         return ((SqlMoney)this);
389                 }
390
391                 public SqlSingle ToSqlSingle() 
392                 {
393                         return ((SqlSingle)this);
394                 }
395
396                 public override string ToString() 
397                 {
398                         if (!notNull)
399                                 return "Null";
400                         return ((string)this);
401                 }
402
403                 // ***********************************
404                 // Operators
405                 // ***********************************
406
407                 // Concatenates
408                 public static SqlString operator + (SqlString x, SqlString y) 
409                 {
410                          if (x.IsNull || y.IsNull)
411                                 return SqlString.Null;
412                         else
413                                 return new SqlString (x.Value + y.Value);
414                 }
415
416                 // Equality
417                 public static SqlBoolean operator == (SqlString x, SqlString y) 
418                 {
419                         if (x.IsNull || y.IsNull)
420                                 return SqlBoolean.Null;
421                         else
422                                 return new SqlBoolean (x.Value == y.Value);
423                 }
424
425                 // Greater Than
426                 public static SqlBoolean operator > (SqlString x, SqlString y) 
427                 {
428                         if (x.IsNull || y.IsNull)
429                                 return SqlBoolean.Null;
430                         else
431                                 return new SqlBoolean (x.CompareTo (y) > 0);
432                 }
433
434                 // Greater Than Or Equal
435                 public static SqlBoolean operator >= (SqlString x, SqlString y) 
436                 {
437                         if (x.IsNull || y.IsNull)
438                                 return SqlBoolean.Null;
439                         else
440                                 return new SqlBoolean (x.CompareTo (y) >= 0);
441                 }
442
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.Value != y.Value);
449                 }
450
451                 // Less Than
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                 // Less Than Or Equal
461                 public static SqlBoolean operator <= (SqlString x, SqlString y) 
462                 {
463                         if (x.IsNull || y.IsNull)
464                                 return SqlBoolean.Null;
465                         else
466                                 return new SqlBoolean (x.CompareTo (y) <= 0);
467                 }
468
469                 // **************************************
470                 // Type Conversions
471                 // **************************************
472
473                 public static explicit operator SqlString (SqlBoolean 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 (SqlByte 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 (SqlDateTime 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 (SqlDecimal x)
498                 {
499                         if (x.IsNull)
500                                 return Null;
501                         else
502                                 return new SqlString (x.Value.ToString ());
503                                 // return new SqlString (x.Value.ToString ("N", DecimalFormat));
504                 }
505
506                 public static explicit operator SqlString (SqlDouble 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 (SqlGuid x) 
515                 {
516                         if (x.IsNull)
517                                 return Null;
518                         else
519                                 return new SqlString (x.Value.ToString ());
520                 }
521
522                 public static explicit operator SqlString (SqlInt16 x) 
523                 {
524                         if (x.IsNull)
525                                 return Null;
526                         else
527                                 return new SqlString (x.Value.ToString ());
528                 }
529
530                 public static explicit operator SqlString (SqlInt32 x) 
531                 {
532                         if (x.IsNull)
533                                 return Null;
534                         else
535                                 return new SqlString (x.Value.ToString ());
536                 }
537
538                 public static explicit operator SqlString (SqlInt64 x) 
539                 {
540                         if (x.IsNull)
541                                 return Null;
542                         else
543                                 return new SqlString (x.Value.ToString ());
544                 }
545
546                 public static explicit operator SqlString (SqlMoney x) 
547                 {
548                         if (x.IsNull)
549                                 return Null;
550                         else
551                                 return new SqlString (x.ToString ());
552                 }
553
554                 public static explicit operator SqlString (SqlSingle x) 
555                 {
556                         if (x.IsNull)
557                                 return Null;
558                         else
559                                 return new SqlString (x.Value.ToString ());
560                 }
561
562                 public static explicit operator string (SqlString x) 
563                 {
564                         return x.Value;
565                 }
566
567                 public static implicit operator SqlString (string x) 
568                 {
569                         return new SqlString (x);
570                 }
571
572                 #if NET_2_0
573                 public static SqlString Add (SqlString x, SqlString y)
574                 {
575                         return ( x + y);
576                                                                                                     
577                 }
578
579                 public int CompareTo (SqlString value)
580                 {
581                         return CompareSqlString (value);
582                 }
583                 #endif
584
585
586
587                 #endregion // Public Methods
588 #if NET_2_0
589                 public static XmlQualifiedName GetXsdType (XmlSchemaSet schemaSet)
590                 {
591                         XmlQualifiedName qualifiedName = new XmlQualifiedName ("string", "http://www.w3.org/2001/XMLSchema");
592                         return qualifiedName;
593                 }
594
595                 [MonoTODO]
596                 XmlSchema IXmlSerializable.GetSchema ()
597                 {
598                         throw new NotImplementedException ();
599                 }
600                 
601                 [MonoTODO]
602                 void IXmlSerializable.ReadXml (XmlReader reader)
603                 {
604                         throw new NotImplementedException ();
605                 }
606                 
607                 [MonoTODO]
608                 void IXmlSerializable.WriteXml (XmlWriter writer) 
609                 {
610                         throw new NotImplementedException ();
611                 }
612 #endif
613         }
614 }