// (C) Copyright 2002 Tim Coleman
//
+//
+// Copyright (C) 2004 Novell, Inc (http://www.novell.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
using System;
-using System.Globalization;
+using System.Xml;
+using System.Text;
using System.Threading;
+using System.Xml.Schema;
+using System.Globalization;
+using System.Xml.Serialization;
namespace System.Data.SqlTypes
{
/// A variable-length stream of characters
/// to be stored in or retrieved from the database
/// </summary>
+#if NET_2_0
+ [SerializableAttribute]
+ [XmlSchemaProvider ("GetXsdType")]
+#endif
public struct SqlString : INullable, IComparable
+#if NET_2_0
+ , IXmlSerializable
+#endif
{
#region Fields
public static readonly int IgnoreWidth = 0x10;
public static readonly SqlString Null;
- internal static readonly NumberFormatInfo MoneyFormat;
internal static NumberFormatInfo DecimalFormat;
#endregion // Fields
static SqlString ()
{
- MoneyFormat = (NumberFormatInfo) NumberFormatInfo.InvariantInfo.Clone ();
- MoneyFormat.NumberDecimalDigits = 4;
- MoneyFormat.NumberGroupSeparator = String.Empty;
-
DecimalFormat = (NumberFormatInfo) NumberFormatInfo.InvariantInfo.Clone ();
DecimalFormat.NumberDecimalDigits = 13;
DecimalFormat.NumberGroupSeparator = String.Empty;
{
this.value = data;
lcid = CultureInfo.CurrentCulture.LCID;
- notNull = true;
+ if (value != null)
+ notNull = true;
+ else
+ notNull = false;
this.compareOptions = SqlCompareOptions.IgnoreCase |
SqlCompareOptions.IgnoreKanaType |
SqlCompareOptions.IgnoreWidth;
{
this.value = data;
this.lcid = lcid;
- notNull = true;
+ if (value != null)
+ notNull = true;
+ else
+ notNull = false;
this.compareOptions = SqlCompareOptions.IgnoreCase |
SqlCompareOptions.IgnoreKanaType |
SqlCompareOptions.IgnoreWidth;
this.value = data;
this.lcid = lcid;
this.compareOptions = compareOptions;
- notNull = true;
+ if (value != null)
+ notNull = true;
+ else
+ notNull = false;
}
// init with locale id, compare options, array of bytes data,
// and whether unicode is encoded or not
public SqlString (int lcid, SqlCompareOptions compareOptions, byte[] data, bool fUnicode)
{
- char [] chars;
-
- if (fUnicode)
- chars = new char [data.Length/2];
- else
- chars = new char [data.Length];
-
- int j = 0;
- for (int i = 0; i < chars.Length; i++) {
-
- if (fUnicode) {
- chars [i] = (char)(data [j] << 16);
- chars [i] += (char)data [j + 1];
- j += 2;
- } else {
- chars [i] = (char)data[i];
- }
- }
-
- this.value = new String (chars);
+ Encoding encoding = (fUnicode ? Encoding.Unicode : Encoding.ASCII);
+ this.value = encoding.GetString (data);
this.lcid = lcid;
this.compareOptions = compareOptions;
- notNull = true;
+ if (value != null)
+ notNull = true;
+ else
+ notNull = false;
}
// init with locale id, compare options, array of bytes data,
// and whether unicode is encoded or not
public SqlString (int lcid, SqlCompareOptions compareOptions, byte[] data, int index, int count, bool fUnicode)
{
- char [] chars;
-
- if (fUnicode)
- chars = new char [(count - index) / 2];
- else
- chars = new char [count - index];
-
- if (index >= data.Length)
- throw new ArgumentOutOfRangeException ("index");
-
- if ((index + count) > data.Length)
- throw new ArgumentOutOfRangeException ("count");
-
- int j = 0;
- for (int i = index; i < chars.Length; i++) {
-
- if (fUnicode) {
- chars [i] = (char)(data[j] << 16);
- chars [i] += (char)data[j+1];
- j += 2;
- } else {
- chars [i] = (char)data [j];
- j++;
- }
- }
-
- this.value = new String (chars);
+ Encoding encoding = (fUnicode ? Encoding.Unicode : Encoding.ASCII);
+ this.value = encoding.GetString (data, index, count);
this.lcid = lcid;
this.compareOptions = compareOptions;
- notNull = true;
+ if (value != null)
+ notNull = true;
+ else
+ notNull = false;
}
#endregion // Constructors
}
}
- public CompareOptions CompareOptions {
- get {
- return
- (this.compareOptions & SqlCompareOptions.BinarySort) != 0 ?
- CompareOptions.Ordinal :
- // 27 == all SqlCompareOptions - BinarySort
- // (1,2,8,24 are common to CompareOptions)
- (CompareOptions) ((int) this.compareOptions & 27);
- }
- }
-
public bool IsNull {
get { return !notNull; }
}
#endregion // Public Properties
+ #region Private Properties
+
+ private CompareOptions CompareOptions {
+ get {
+ return
+ (this.compareOptions & SqlCompareOptions.BinarySort) != 0 ?
+ CompareOptions.Ordinal :
+ // 27 == all SqlCompareOptions - BinarySort
+ // (1,2,8,24 are common to CompareOptions)
+ (CompareOptions)((int)this.compareOptions & 27);
+ }
+ }
+
+ #endregion Private Properties
+
#region Public Methods
public SqlString Clone()
return 1;
else if (!(value is SqlString))
throw new ArgumentException (Locale.GetText ("Value is not a System.Data.SqlTypes.SqlString"));
- else if (((SqlString)value).IsNull)
+
+ return CompareSqlString ((SqlString)value);
+ }
+
+
+ private int CompareSqlString (SqlString value)
+ {
+ if (value.IsNull)
return 1;
+ else if (value.CompareOptions != this.CompareOptions)
+ throw new SqlTypeException (Locale.GetText ("Two strings to be compared have different collation"));
// else
// return String.Compare (this.value, ((SqlString)value).Value, (this.SqlCompareOptions & SqlCompareOptions.IgnoreCase) != 0, this.CultureInfo);
- return CultureInfo.CompareInfo.Compare (this.value, ((SqlString)value).Value, this.CompareOptions);
+ return CultureInfo.CompareInfo.Compare (this.value, value.Value, this.CompareOptions);
}
public static SqlString Concat(SqlString x, SqlString y)
{
if (!(value is SqlString))
return false;
- if (this.IsNull && ((SqlString)value).IsNull)
- return true;
+ if (this.IsNull)
+ return ((SqlString)value).IsNull;
else if (((SqlString)value).IsNull)
return false;
else
public byte[] GetNonUnicodeBytes()
{
- byte [] bytes = new byte [value.Length];
-
- for (int i = 0; i < bytes.Length; i++)
- bytes [i] = (byte)value [i];
-
- return bytes;
+ return Encoding.ASCII.GetBytes (value);
}
public byte[] GetUnicodeBytes()
{
- byte [] bytes = new byte [value.Length * 2];
-
- int j = 0;
- for (int i = 0; i < value.Length; i++) {
- bytes [j] = (byte)(value [i] & 0x0000FFFF);
- bytes [j + 1] = (byte)((value [i] & 0xFFFF0000) >> 16);
- j += 2;
- }
-
- return bytes;
+ return Encoding.Unicode.GetBytes (value);
}
public static SqlBoolean GreaterThan(SqlString x, SqlString y)
public override string ToString()
{
+ if (!notNull)
+ return "Null";
return ((string)this);
}
// Concatenates
public static SqlString operator + (SqlString x, SqlString y)
{
- if (x.IsNull || y.IsNull)
- return SqlString.Null;
-
- return new SqlString (x.Value + y.Value);
+ if (x.IsNull || y.IsNull)
+ return SqlString.Null;
+ else
+ return new SqlString (x.Value + y.Value);
}
// Equality
return Null;
else
return new SqlString (x.Value.ToString ());
- return new SqlString (x.Value.ToString ("N", DecimalFormat));
+ // return new SqlString (x.Value.ToString ("N", DecimalFormat));
}
public static explicit operator SqlString (SqlDouble x)
if (x.IsNull)
return Null;
else
- return new SqlString (x.Value.ToString ());
- return new SqlString (x.Value.ToString ("N", MoneyFormat));
+ return new SqlString (x.ToString ());
}
public static explicit operator SqlString (SqlSingle x)
return new SqlString (x);
}
+#if NET_2_0
+ public static SqlString Add (SqlString x, SqlString y)
+ {
+ return (x + y);
+ }
+
+ public int CompareTo (SqlString value)
+ {
+ return CompareSqlString (value);
+ }
+#endif
+
+
+
#endregion // Public Methods
+#if NET_2_0
+ public static XmlQualifiedName GetXsdType (XmlSchemaSet schemaSet)
+ {
+ if (schemaSet != null && schemaSet.Count == 0) {
+ XmlSchema xs = new XmlSchema ();
+ XmlSchemaComplexType ct = new XmlSchemaComplexType ();
+ ct.Name = "string";
+ xs.Items.Add (ct);
+ schemaSet.Add (xs);
+ }
+ return new XmlQualifiedName ("string", "http://www.w3.org/2001/XMLSchema");
+ }
+
+ XmlSchema IXmlSerializable.GetSchema ()
+ {
+ return null;
+ }
+
+ void IXmlSerializable.ReadXml (XmlReader reader)
+ {
+ if (reader == null)
+ return;
+
+ switch (reader.ReadState) {
+ case ReadState.EndOfFile:
+ case ReadState.Error:
+ case ReadState.Closed:
+ return;
+ }
+ // Skip XML declaration and prolog
+ // or do I need to validate for the <string> tag?
+ reader.MoveToContent ();
+ if (reader.EOF)
+ return;
+
+ reader.Read ();
+ if (reader.NodeType == XmlNodeType.EndElement)
+ return;
+
+ if (reader.Value.Length > 0) {
+ if (String.Compare ("Null", reader.Value) == 0) {
+ // means a null reference/invalid value
+ notNull = false;
+ return;
+ }
+ // FIXME: Validate the value for expected format
+ this.value = reader.Value;
+ this.notNull = true;
+ this.compareOptions = SqlCompareOptions.IgnoreCase |
+ SqlCompareOptions.IgnoreKanaType |
+ SqlCompareOptions.IgnoreWidth;
+ }
+ }
+
+ void IXmlSerializable.WriteXml (XmlWriter writer)
+ {
+ writer.WriteString (this.ToString ());
+ }
+#endif
}
}