2 // System.Data.SqlTypes.SqlString
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)
10 // (C) Ximian, Inc. 2002
11 // (C) Copyright 2002 Tim Coleman
15 // Copyright (C) 2004 Novell, Inc (http://www.novell.com)
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:
25 // The above copyright notice and this permission notice shall be
26 // included in all copies or substantial portions of the Software.
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.
38 using System.Globalization;
39 using System.Threading;
41 namespace System.Data.SqlTypes
44 /// A variable-length stream of characters
45 /// to be stored in or retrieved from the database
47 public struct SqlString : INullable, IComparable
56 // FIXME: locale id is not working yet
58 private SqlCompareOptions compareOptions;
60 public static readonly int BinarySort = 0x8000;
61 public static readonly int IgnoreCase = 0x1;
62 public static readonly int IgnoreKanaType = 0x8;
63 public static readonly int IgnoreNonSpace = 0x2;
64 public static readonly int IgnoreWidth = 0x10;
65 public static readonly SqlString Null;
67 internal static NumberFormatInfo DecimalFormat;
74 DecimalFormat = (NumberFormatInfo) NumberFormatInfo.InvariantInfo.Clone ();
75 DecimalFormat.NumberDecimalDigits = 13;
76 DecimalFormat.NumberGroupSeparator = String.Empty;
79 // init with a string data
80 public SqlString (string data)
83 lcid = CultureInfo.CurrentCulture.LCID;
85 this.compareOptions = SqlCompareOptions.IgnoreCase |
86 SqlCompareOptions.IgnoreKanaType |
87 SqlCompareOptions.IgnoreWidth;
90 // init with a string data and locale id values.
91 public SqlString (string data, int lcid)
96 this.compareOptions = SqlCompareOptions.IgnoreCase |
97 SqlCompareOptions.IgnoreKanaType |
98 SqlCompareOptions.IgnoreWidth;
101 // init with locale id, compare options,
102 // and an array of bytes data
103 public SqlString (int lcid, SqlCompareOptions compareOptions, byte[] data)
104 : this (lcid, compareOptions, data, true) { }
106 // init with string data, locale id, and compare options
107 public SqlString (string data, int lcid, SqlCompareOptions compareOptions)
111 this.compareOptions = compareOptions;
115 // init with locale id, compare options, array of bytes data,
116 // and whether unicode is encoded or not
117 public SqlString (int lcid, SqlCompareOptions compareOptions, byte[] data, bool fUnicode)
122 chars = new char [data.Length/2];
124 chars = new char [data.Length];
127 for (int i = 0; i < chars.Length; i++) {
130 chars [i] = (char)(data [j] << 16);
131 chars [i] += (char)data [j + 1];
134 chars [i] = (char)data[i];
138 this.value = new String (chars);
140 this.compareOptions = compareOptions;
144 // init with locale id, compare options, array of bytes data,
145 // starting index in the byte array,
146 // and number of bytes to copy
147 public SqlString (int lcid, SqlCompareOptions compareOptions, byte[] data,
148 int index, int count)
149 : this (lcid, compareOptions, data, index, count, true) { }
151 // init with locale id, compare options, array of bytes data,
152 // starting index in the byte array, number of byte to copy,
153 // and whether unicode is encoded or not
154 public SqlString (int lcid, SqlCompareOptions compareOptions, byte[] data, int index, int count, bool fUnicode)
159 chars = new char [(count - index) / 2];
161 chars = new char [count - index];
163 if (index >= data.Length)
164 throw new ArgumentOutOfRangeException ("index");
166 if ((index + count) > data.Length)
167 throw new ArgumentOutOfRangeException ("count");
170 for (int i = index; i < chars.Length; i++) {
173 chars [i] = (char)(data[j] << 16);
174 chars [i] += (char)data[j+1];
177 chars [i] = (char)data [j];
182 this.value = new String (chars);
184 this.compareOptions = compareOptions;
188 #endregion // Constructors
191 #region Public Properties
193 public CompareInfo CompareInfo {
195 return new CultureInfo (lcid).CompareInfo;
199 public CultureInfo CultureInfo {
201 return new CultureInfo (lcid);
206 get { return !notNull; }
209 // geographics location and language (locale id)
216 public SqlCompareOptions SqlCompareOptions {
218 return compareOptions;
222 public string Value {
225 throw new SqlNullValueException (Locale.GetText ("The property contains Null."));
231 #endregion // Public Properties
233 #region Private Properties
235 private CompareOptions CompareOptions {
238 (this.compareOptions & SqlCompareOptions.BinarySort) != 0 ?
239 CompareOptions.Ordinal :
240 // 27 == all SqlCompareOptions - BinarySort
241 // (1,2,8,24 are common to CompareOptions)
242 (CompareOptions)((int)this.compareOptions & 27);
246 #endregion Private Properties
248 #region Public Methods
250 public SqlString Clone()
252 return new SqlString (value, lcid, compareOptions);
255 public static CompareOptions CompareOptionsFromSqlCompareOptions (SqlCompareOptions compareOptions)
257 CompareOptions options = CompareOptions.None;
259 if ((compareOptions & SqlCompareOptions.IgnoreCase) != 0)
260 options |= CompareOptions.IgnoreCase;
261 if ((compareOptions & SqlCompareOptions.IgnoreKanaType) != 0)
262 options |= CompareOptions.IgnoreKanaType;
263 if ((compareOptions & SqlCompareOptions.IgnoreNonSpace) != 0)
264 options |= CompareOptions.IgnoreNonSpace;
265 if ((compareOptions & SqlCompareOptions.IgnoreWidth) != 0)
266 options |= CompareOptions.IgnoreWidth;
267 if ((compareOptions & SqlCompareOptions.BinarySort) != 0)
268 // FIXME: Exception string
269 throw new ArgumentOutOfRangeException ();
274 // **********************************
275 // Comparison Methods
276 // **********************************
278 public int CompareTo (object value)
282 else if (!(value is SqlString))
283 throw new ArgumentException (Locale.GetText ("Value is not a System.Data.SqlTypes.SqlString"));
285 return CompareSqlString ((SqlString)value);
289 private int CompareSqlString (SqlString value)
293 else if (value.CompareOptions != this.CompareOptions)
294 throw new SqlTypeException (Locale.GetText ("Two strings to be compared have different collation"));
296 // return String.Compare (this.value, ((SqlString)value).Value, (this.SqlCompareOptions & SqlCompareOptions.IgnoreCase) != 0, this.CultureInfo);
297 return CultureInfo.CompareInfo.Compare (this.value, value.Value, this.CompareOptions);
300 public static SqlString Concat(SqlString x, SqlString y)
305 public override bool Equals(object value)
307 if (!(value is SqlString))
309 if (this.IsNull && ((SqlString)value).IsNull)
311 else if (((SqlString)value).IsNull)
314 return (bool) (this == (SqlString)value);
317 public static SqlBoolean Equals(SqlString x, SqlString y)
322 public override int GetHashCode()
325 for (int i = 0; i < value.Length; i++)
326 result = 91 * result + (int)(value [i] ^ (value [i] >> 32));
328 result = 91 * result + lcid.GetHashCode ();
329 result = 91 * result + (int)compareOptions;
334 public byte[] GetNonUnicodeBytes()
336 byte [] bytes = new byte [value.Length];
338 for (int i = 0; i < bytes.Length; i++)
339 bytes [i] = (byte)value [i];
344 public byte[] GetUnicodeBytes()
346 byte [] bytes = new byte [value.Length * 2];
349 for (int i = 0; i < value.Length; i++) {
350 bytes [j] = (byte)(value [i] & 0x0000FFFF);
351 bytes [j + 1] = (byte)((value [i] & 0xFFFF0000) >> 16);
358 public static SqlBoolean GreaterThan(SqlString x, SqlString y)
363 public static SqlBoolean GreaterThanOrEqual(SqlString x, SqlString y)
368 public static SqlBoolean LessThan(SqlString x, SqlString y)
373 public static SqlBoolean LessThanOrEqual(SqlString x, SqlString y)
378 public static SqlBoolean NotEquals(SqlString x, SqlString y)
383 // ****************************************
384 // Type Conversions From SqlString To ...
385 // ****************************************
387 public SqlBoolean ToSqlBoolean()
389 return ((SqlBoolean)this);
392 public SqlByte ToSqlByte()
394 return ((SqlByte)this);
397 public SqlDateTime ToSqlDateTime()
399 return ((SqlDateTime)this);
402 public SqlDecimal ToSqlDecimal()
404 return ((SqlDecimal)this);
407 public SqlDouble ToSqlDouble()
409 return ((SqlDouble)this);
412 public SqlGuid ToSqlGuid()
414 return ((SqlGuid)this);
417 public SqlInt16 ToSqlInt16()
419 return ((SqlInt16)this);
422 public SqlInt32 ToSqlInt32()
424 return ((SqlInt32)this);
427 public SqlInt64 ToSqlInt64()
429 return ((SqlInt64)this);
432 public SqlMoney ToSqlMoney()
434 return ((SqlMoney)this);
437 public SqlSingle ToSqlSingle()
439 return ((SqlSingle)this);
442 public override string ToString()
446 return ((string)this);
449 // ***********************************
451 // ***********************************
454 public static SqlString operator + (SqlString x, SqlString y)
456 if (x.IsNull || y.IsNull)
457 return SqlString.Null;
459 if (( x == null) || (y == null))
460 return SqlString.Null;
462 return new SqlString (x.Value + y.Value);
466 public static SqlBoolean operator == (SqlString x, SqlString y)
468 if (x.IsNull || y.IsNull)
469 return SqlBoolean.Null;
471 return new SqlBoolean (x.Value == y.Value);
475 public static SqlBoolean operator > (SqlString x, SqlString y)
477 if (x.IsNull || y.IsNull)
478 return SqlBoolean.Null;
480 return new SqlBoolean (x.CompareTo (y) > 0);
483 // Greater Than Or Equal
484 public static SqlBoolean operator >= (SqlString x, SqlString y)
486 if (x.IsNull || y.IsNull)
487 return SqlBoolean.Null;
489 return new SqlBoolean (x.CompareTo (y) >= 0);
492 public static SqlBoolean operator != (SqlString x, SqlString y)
494 if (x.IsNull || y.IsNull)
495 return SqlBoolean.Null;
497 return new SqlBoolean (x.Value != y.Value);
501 public static SqlBoolean operator < (SqlString x, SqlString y)
503 if (x.IsNull || y.IsNull)
504 return SqlBoolean.Null;
506 return new SqlBoolean (x.CompareTo (y) < 0);
509 // Less Than Or Equal
510 public static SqlBoolean operator <= (SqlString x, SqlString y)
512 if (x.IsNull || y.IsNull)
513 return SqlBoolean.Null;
515 return new SqlBoolean (x.CompareTo (y) <= 0);
518 // **************************************
520 // **************************************
522 public static explicit operator SqlString (SqlBoolean x)
527 return new SqlString (x.Value.ToString ());
530 public static explicit operator SqlString (SqlByte x)
535 return new SqlString (x.Value.ToString ());
538 public static explicit operator SqlString (SqlDateTime x)
543 return new SqlString (x.Value.ToString ());
546 public static explicit operator SqlString (SqlDecimal x)
551 return new SqlString (x.Value.ToString ());
552 // return new SqlString (x.Value.ToString ("N", DecimalFormat));
555 public static explicit operator SqlString (SqlDouble x)
560 return new SqlString (x.Value.ToString ());
563 public static explicit operator SqlString (SqlGuid x)
568 return new SqlString (x.Value.ToString ());
571 public static explicit operator SqlString (SqlInt16 x)
576 return new SqlString (x.Value.ToString ());
579 public static explicit operator SqlString (SqlInt32 x)
584 return new SqlString (x.Value.ToString ());
587 public static explicit operator SqlString (SqlInt64 x)
592 return new SqlString (x.Value.ToString ());
595 public static explicit operator SqlString (SqlMoney x)
600 return new SqlString (x.ToString ());
603 public static explicit operator SqlString (SqlSingle x)
608 return new SqlString (x.Value.ToString ());
611 public static explicit operator string (SqlString x)
616 public static implicit operator SqlString (string x)
618 return new SqlString (x);
622 public static SqlString Add (SqlString x, SqlString y)
628 public int CompareTo (SqlString value)
630 return CompareSqlString (value);
636 #endregion // Public Methods