+2003-06-11 Tim Coleman <tim@timcoleman.com>
+ * SybaseConnection.cs:
+ Make connection parameter parsing "more correct"
+ and throw appropriate exceptions, similar to MS SqlClient
+ * SybaseBinary.cs:
+ * SybaseBoolean.cs:
+ * SybaseByte.cs:
+ * SybaseDateTime.cs:
+ * SybaseDecimal.cs:
+ * SybaseDouble.cs:
+ * SybaseMoney.cs:
+ * SybaseString.cs:
+ Mass import of code from SqlClient to make this behave
+ better.
+
2003-02-16 Daniel Morgan <danmorg@sc.rr.com>
* SybaseConnection.cs: - parse data source for 2 possible uses:
// Tim Coleman (tim@timcoleman.com)
// Daniel Morgan (danmorg@sc.rr.com)
//
-// Copyright (C) Tim Coleman, 2002, 2003
+// Copyright (C) Tim Coleman, 2002-2003
// Copyright (C) Daniel Morgan, 2003
//
int minPoolSize;
int maxPoolSize;
int packetSize;
- int port = 1533;
+ int port = 2048;
// The current state
ConnectionState state = ConnectionState.Closed;
public void Open ()
{
string serverName = "";
- if (connectionString == null)
+ if (connectionString == null || connectionString.Equals (""))
throw new InvalidOperationException ("Connection string has not been initialized.");
try {
private void ParseDataSource (string theDataSource, out int thePort, out string theServerName)
{
theServerName = "";
- thePort = 1433; // default TCP port for SQL Server
- \r
- int idx = 0;\r
- if ((idx = theDataSource.IndexOf (",")) > -1) {\r
+ thePort = 2048;
+
+ int idx = 0;
+ if ((idx = theDataSource.IndexOf (",")) > -1) {
theServerName = theDataSource.Substring (0, idx);
string p = theDataSource.Substring (idx + 1);
thePort = Int32.Parse (p);
}
}
- void SetConnectionString (string connectionString)
- {
- connectionString += ";";
- NameValueCollection parameters = new NameValueCollection ();
-
- if (connectionString == String.Empty)
- return;
-
- bool inQuote = false;
- bool inDQuote = false;
-
- string name = String.Empty;
- string value = String.Empty;
- StringBuilder sb = new StringBuilder ();
-
- foreach (char c in connectionString)
- {
- switch (c) {
- case '\'':
- inQuote = !inQuote;
- break;
- case '"' :
- inDQuote = !inDQuote;
- break;
- case ';' :
- if (!inDQuote && !inQuote) {
- if (name != String.Empty && name != null) {
- value = sb.ToString ();
- parameters [name.ToUpper ().Trim ()] = value.Trim ();
- }
- name = String.Empty;
- value = String.Empty;
- sb = new StringBuilder ();
- }
- else
- sb.Append (c);
- break;
- case '=' :
- if (!inDQuote && !inQuote) {
- name = sb.ToString ();
- sb = new StringBuilder ();
- }
- else
- sb.Append (c);
- break;
- default:
- sb.Append (c);
- break;
- }
- }
-
- if (this.ConnectionString == null)
- {
- SetDefaultConnectionParameters (parameters);
- }
-
- SetProperties (parameters);
-
- this.connectionString = connectionString;
- }
-
- void SetDefaultConnectionParameters (NameValueCollection parameters)
- {
- if (null == parameters.Get ("APPLICATION NAME"))
- parameters["APPLICATION NAME"] = ".Net SybaseClient Data Provider";
- if (null == parameters.Get ("CONNECT TIMEOUT") && null == parameters.Get ("CONNECTION TIMEOUT"))
- parameters["CONNECT TIMEOUT"] = "15";
- if (null == parameters.Get ("CONNECTION LIFETIME"))
- parameters["CONNECTION LIFETIME"] = "0";
- if (null == parameters.Get ("CONNECTION RESET"))
- parameters["CONNECTION RESET"] = "true";
- if (null == parameters.Get ("ENLIST"))
- parameters["ENLIST"] = "true";
- if (null == parameters.Get ("INTEGRATED SECURITY") && null == parameters.Get ("TRUSTED_CONNECTION"))
- parameters["INTEGRATED SECURITY"] = "false";
- if (null == parameters.Get ("MAX POOL SIZE"))
- parameters["MAX POOL SIZE"] = "100";
- if (null == parameters.Get ("MIN POOL SIZE"))
- parameters["MIN POOL SIZE"] = "0";
- if (null == parameters.Get ("NETWORK LIBRARY") && null == parameters.Get ("NET"))
- parameters["NETWORK LIBRARY"] = "dbmssocn";
- if (null == parameters.Get ("PACKET SIZE"))
- parameters["PACKET SIZE"] = "512";
- if (null == parameters.Get ("PERSIST SECURITY INFO"))
- parameters["PERSIST SECURITY INFO"] = "false";
- if (null == parameters.Get ("POOLING"))
- parameters["POOLING"] = "true";
- if (null == parameters.Get ("WORKSTATION ID"))
- parameters["WORKSTATION ID"] = Dns.GetHostByName ("localhost").HostName;
- }
-
- private void SetProperties (NameValueCollection parameters)
- {
- string value;
- foreach (string name in parameters) {
- value = parameters[name];
-
- switch (name) {
- case "APPLICATION NAME" :
- parms.ApplicationName = value;
- break;
- case "ATTACHDBFILENAME" :
- case "EXTENDED PROPERTIES" :
- case "INITIAL FILE NAME" :
- break;
- case "CONNECT TIMEOUT" :
- case "CONNECTION TIMEOUT" :
- connectionTimeout = Int32.Parse (value);
- break;
- case "CONNECTION LIFETIME" :
- break;
- case "CONNECTION RESET" :
- connectionReset = !(value.ToUpper ().Equals ("FALSE") || value.ToUpper ().Equals ("NO"));
- break;
- case "CURRENT LANGUAGE" :
- parms.Language = value;
- break;
- case "DATA SOURCE" :
- case "SERVER" :
- case "ADDRESS" :
- case "ADDR" :
- case "NETWORK ADDRESS" :
- dataSource = value;
- break;
- case "ENLIST" :
- break;
- case "INITIAL CATALOG" :
- case "DATABASE" :
- parms.Database = value;
- break;
- case "INTEGRATED SECURITY" :
- case "TRUSTED_CONNECTION" :
- break;
- case "MAX POOL SIZE" :
- maxPoolSize = Int32.Parse (value);
- break;
- case "MIN POOL SIZE" :
- minPoolSize = Int32.Parse (value);
- break;
- case "NET" :
- case "NETWORK LIBRARY" :
- if (!value.ToUpper ().Equals ("DBMSSOCN"))
- throw new ArgumentException ("Unsupported network library.");
- break;
- case "PACKET SIZE" :
- packetSize = Int32.Parse (value);
- break;
- case "PASSWORD" :
- case "PWD" :
- parms.Password = value;
- break;
- case "PERSIST SECURITY INFO" :
- break;
- case "POOLING" :
- pooling = !(value.ToUpper ().Equals ("FALSE") || value.ToUpper ().Equals ("NO"));
- break;
- case "USER ID" :
- parms.User = value;
- break;
- case "WORKSTATION ID" :
- parms.Hostname = value;
- break;
- }
+ private string ParseValue (string name, string value)
+ {
+ if (name.Length == 0 && value.Length > 0)
+ throw new ArgumentException ("Expected '=' delimiter while parsing connection value pair.");
+ if (name.Length > 0)
+ return value.Trim ();
+ return String.Empty;
+ }
+
+ private void SetConnectionString (string connectionString)
+ {
+ if (connectionString == String.Empty) {
+ this.connectionString = connectionString;
+ return;
}
+
+ NameValueCollection parameters = new NameValueCollection ();
+
+ string name = String.Empty;
+ string value = String.Empty;
+ StringBuilder sb = new StringBuilder ();
+
+ char delimiter = '\0';
+
+ foreach (char c in connectionString) {
+ switch (c) {
+ case '\'' :
+ case '"' :
+ if (delimiter.Equals (c))
+ delimiter = '\0';
+ else if (delimiter.Equals ('\0'))
+ delimiter = c;
+ else
+ sb.Append (c);
+ break;
+ case ';' :
+ if (delimiter.Equals ('\0')) {
+ value = ParseValue (name, sb.ToString ());
+ if (!value.Equals (""))
+ parameters [name.ToUpper ().Trim ()] = value;
+ name = String.Empty;
+ sb = new StringBuilder ();
+ }
+ else
+ sb.Append (c);
+ break;
+ case '=' :
+ if (delimiter.Equals ('\0')) {
+ name = sb.ToString ();
+ sb = new StringBuilder ();
+ }
+ else
+ sb.Append (c);
+ break;
+ default:
+ sb.Append (c);
+ break;
+ }
+ }
+
+ if (!delimiter.Equals ('\0'))
+ throw new ArgumentException (String.Format ("Matching end delimiter {0} not found in connection option value.", delimiter));
+
+ value = ParseValue (name, sb.ToString ());
+ if (!value.Equals (""))
+ parameters [name.ToUpper ().Trim ()] = value;
+
+ if (this.ConnectionString == null)
+ SetDefaultConnectionParameters (parameters);
+
+ SetProperties (parameters);
+
+ this.connectionString = connectionString;
}
+ private void SetDefaultConnectionParameters (NameValueCollection parameters)
+ {
+ if (null == parameters.Get ("APPLICATION NAME"))
+ parameters["APPLICATION NAME"] = "Mono SybaseClient Data Provider";
+ if (null == parameters.Get ("CONNECT TIMEOUT") && null == parameters.Get ("CONNECTION TIMEOUT"))
+ parameters["CONNECT TIMEOUT"] = "15";
+ if (null == parameters.Get ("CONNECTION LIFETIME"))
+ parameters["CONNECTION LIFETIME"] = "0";
+ if (null == parameters.Get ("CONNECTION RESET"))
+ parameters["CONNECTION RESET"] = "true";
+ if (null == parameters.Get ("ENLIST"))
+ parameters["ENLIST"] = "true";
+ if (null == parameters.Get ("INTEGRATED SECURITY") && null == parameters.Get ("TRUSTED_CONNECTION"))
+ parameters["INTEGRATED SECURITY"] = "false";
+ if (null == parameters.Get ("MAX POOL SIZE"))
+ parameters["MAX POOL SIZE"] = "100";
+ if (null == parameters.Get ("MIN POOL SIZE"))
+ parameters["MIN POOL SIZE"] = "0";
+ if (null == parameters.Get ("NETWORK LIBRARY") && null == parameters.Get ("NET"))
+ parameters["NETWORK LIBRARY"] = "dbmssocn";
+ if (null == parameters.Get ("PACKET SIZE"))
+ parameters["PACKET SIZE"] = "512";
+ if (null == parameters.Get ("PERSIST SECURITY INFO"))
+ parameters["PERSIST SECURITY INFO"] = "false";
+ if (null == parameters.Get ("POOLING"))
+ parameters["POOLING"] = "true";
+ if (null == parameters.Get ("WORKSTATION ID"))
+ parameters["WORKSTATION ID"] = Dns.GetHostByName ("localhost").HostName;
+ }
+
+ private void SetProperties (NameValueCollection parameters)
+ {
+ string value;
+ foreach (string name in parameters) {
+ value = parameters [name];
+
+ switch (name) {
+ case "APPLICATION NAME" :
+ parms.ApplicationName = value;
+ break;
+ case "ATTACHDBFILENAME" :
+ case "EXTENDED PROPERTIES" :
+ case "INITIAL FILE NAME" :
+ break;
+ case "CONNECT TIMEOUT" :
+ case "CONNECTION TIMEOUT" :
+ connectionTimeout = Int32.Parse (value);
+ break;
+ case "CONNECTION LIFETIME" :
+ break;
+ case "CONNECTION RESET" :
+ connectionReset = !(value.ToUpper ().Equals ("FALSE") || value.ToUpper ().Equals ("NO"));
+ break;
+ case "CURRENT LANGUAGE" :
+ parms.Language = value;
+ break;
+ case "DATA SOURCE" :
+ case "SERVER" :
+ case "ADDRESS" :
+ case "ADDR" :
+ case "NETWORK ADDRESS" :
+ dataSource = value;
+ break;
+ case "ENLIST" :
+ break;
+ case "INITIAL CATALOG" :
+ case "DATABASE" :
+ parms.Database = value;
+ break;
+ case "INTEGRATED SECURITY" :
+ case "TRUSTED_CONNECTION" :
+ break;
+ case "MAX POOL SIZE" :
+ maxPoolSize = Int32.Parse (value);
+ break;
+ case "MIN POOL SIZE" :
+ minPoolSize = Int32.Parse (value);
+ break;
+ case "NET" :
+ case "NETWORK LIBRARY" :
+ if (!value.ToUpper ().Equals ("DBMSSOCN"))
+ throw new ArgumentException ("Unsupported network library.");
+ break;
+ case "PACKET SIZE" :
+ packetSize = Int32.Parse (value);
+ break;
+ case "PASSWORD" :
+ case "PWD" :
+ parms.Password = value;
+ break;
+ case "PERSIST SECURITY INFO" :
+ break;
+ case "POOLING" :
+ pooling = !(value.ToUpper ().Equals ("FALSE") || value.ToUpper ().Equals ("NO"));
+ break;
+ case "USER ID" :
+ parms.User = value;
+ break;
+ case "WORKSTATION ID" :
+ parms.Hostname = value;
+ break;
+ }
+ }
+ }
- static bool IsValidDatabaseName (string database)
+ private static bool IsValidDatabaseName (string database)
{
if (database.Length > 32 || database.Length < 1)
return false;
// Author:
// Tim Coleman (tim@timcoleman.com)
//
-// (C) Copyright Tim Coleman, 2002
+// Based on System.Data.SqlTypes.SqlBinary
+//
+// (C) Ximian, Inc. 2002-2003
+// (C) Copyright Tim Coleman, 2002-2003
//
using Mono.Data.SybaseClient;
#region Methods
- [MonoTODO]
public int CompareTo (object value)
{
- throw new NotImplementedException ();
+ if (value == null)
+ return 1;
+ else if (!(value is SybaseBinary))
+ throw new ArgumentException ("Value is not a Mono.Data.SybaseTypes.SybaseBinary.");
+ else if (((SybaseBinary) value).IsNull)
+ return 1;
+ else
+ return Compare (this, (SybaseBinary) value);
}
public static SybaseBinary Concat (SybaseBinary x, SybaseBinary y)
return (x == y);
}
- [MonoTODO]
public override int GetHashCode ()
{
- throw new NotImplementedException ();
+ int result = 10;
+ for (int i = 0; i < value.Length; i += 1)
+ result = 91 * result + ((int) value [i]);
+ return result;
}
#endregion
#region Operators
- [MonoTODO]
public static SybaseBinary operator + (SybaseBinary x, SybaseBinary y)
{
- throw new NotImplementedException ();
+ byte[] b = new byte [x.Length + y.Length];
+ int j = 0;
+ int i;
+
+ for (i = 0; i < x.Length; i += 1)
+ b [i] = x [i];
+
+ for (; i < x.Length + y.Length; i += 1) {
+ b [i] = y [j];
+ j += 1;
+ }
+
+ return new SybaseBinary (b);
}
- [MonoTODO]
public static SybaseBoolean operator == (SybaseBinary x, SybaseBinary y)
{
if (x.IsNull || y.IsNull)
return SybaseBoolean.Null;
else
- throw new NotImplementedException ();
+ return new SybaseBoolean (Compare (x, y) == 0);
}
- [MonoTODO]
public static SybaseBoolean operator > (SybaseBinary x, SybaseBinary y)
{
if (x.IsNull || y.IsNull)
return SybaseBoolean.Null;
else
- throw new NotImplementedException ();
+ return new SybaseBoolean (Compare (x, y) > 0);
}
- [MonoTODO]
public static SybaseBoolean operator >= (SybaseBinary x, SybaseBinary y)
{
if (x.IsNull || y.IsNull)
return SybaseBoolean.Null;
else
- throw new NotImplementedException ();
+ return new SybaseBoolean (Compare (x, y) >= 0);
}
- [MonoTODO]
public static SybaseBoolean operator != (SybaseBinary x, SybaseBinary y)
{
if (x.IsNull || y.IsNull)
return SybaseBoolean.Null;
else
- throw new NotImplementedException ();
+ return new SybaseBoolean (Compare (x, y) != 0);
}
- [MonoTODO]
public static SybaseBoolean operator < (SybaseBinary x, SybaseBinary y)
{
if (x.IsNull || y.IsNull)
return SybaseBoolean.Null;
else
- throw new NotImplementedException ();
+ return new SybaseBoolean (Compare (x, y) < 0);
}
- [MonoTODO]
public static SybaseBoolean operator <= (SybaseBinary x, SybaseBinary y)
{
if (x.IsNull || y.IsNull)
return SybaseBoolean.Null;
else
- throw new NotImplementedException ();
+ return new SybaseBoolean (Compare (x, y) <= 0);
}
public static explicit operator byte[] (SybaseBinary x)
return x.Value;
}
- [MonoTODO]
public static explicit operator SybaseBinary (SybaseGuid x)
{
- throw new NotImplementedException ();
+ return new SybaseBinary (x.ToByteArray ());
}
public static implicit operator SybaseBinary (byte[] x)
return new SybaseBinary (x);
}
+ private static int Compare (SybaseBinary x, SybaseBinary y)
+ {
+ int lengthDiff = 0;
+
+ if (x.Length != y.Length) {
+ lengthDiff = x.Length - y.Length;
+
+ // if diff more than 0, x is longer
+ if (lengthDiff > 0) {
+ for (int i = x.Length - 1; i > x.Length - lengthDiff; i -= 1)
+ if (x [i] != (byte) 0)
+ return 1;
+ } else {
+ for (int i = y.Length - 1; i > y.Length - lengthDiff; i -= 1)
+ if (y [i] != (byte) 0)
+ return -1;
+ }
+ }
+
+ // choose shorter
+ int len = (lengthDiff > 0) ? y.Length : x.Length;
+
+ for (int i = len - 1; i > 0; i -= 1) {
+ byte bx = x [i];
+ byte by = y [i];
+
+ if (bx > by)
+ return 1;
+ else if (bx < by)
+ return -1;
+ }
+
+ return 0;
+ }
+
#endregion
}
}
// Author:
// Tim Coleman (tim@timcoleman.com)
//
-// (C) Copyright Tim Coleman, 2002
+// Based on System.Data.SqlTypes.SqlBoolean
+//
+// (C) Ximian, Inc. 2002-2003
+// (C) Copyright Tim Coleman, 2002-2003
//
using Mono.Data.SybaseClient;
using System;
-using System.Data.SqlTypes;
+using System.Data.SqlTypes;
using System.Globalization;
namespace Mono.Data.SybaseTypes {
// Author:
// Tim Coleman <tim@timcoleman.com>
//
+// Based on System.Data.SqlTypes.SqlByte
+//
+//
+// (C) Ximian, Inc. 2002-2003
// (C) Copyright Tim Coleman, 2002
//
// Author:
// Tim Coleman <tim@timcoleman.com>
//
-// (C) Copyright Tim Coleman, 2002
+// Based on System.Data.SqlTypes.SqlDateTime
+//
+// (C) Ximian, Inc. 2002-2003
+// (C) Copyright Tim Coleman, 2002-2003
//
using Mono.Data.SybaseClient;
#region Fields
private DateTime value;
private bool notNull;
+ private static readonly float DateTimeTicksPerHour = 3.6E+10f;
+ private static readonly DateTime Epoch = new DateTime (1900, 1, 1);
- public static readonly SybaseDateTime MaxValue = new SybaseDateTime (9999,12,31);
+ public static readonly SybaseDateTime MaxValue = new SybaseDateTime (9999, 12, 31, 23, 59, 59);
public static readonly SybaseDateTime MinValue = new SybaseDateTime (1753,1,1);
public static readonly SybaseDateTime Null;
- public static readonly int SQLTicksPerHour;
- public static readonly int SQLTicksPerMinute;
- public static readonly int SQLTicksPerSecond;
+ public static readonly int SQLTicksPerHour = 1080000;
+ public static readonly int SQLTicksPerMinute = 18000;
+ public static readonly int SQLTicksPerSecond = 300;
#endregion
notNull = true;
}
- [MonoTODO]
public SybaseDateTime (int dayTicks, int timeTicks)
{
- throw new NotImplementedException ();
+ this.value = new DateTime (Epoch.Ticks + (long) (dayTicks + timeTicks));
+ notNull = true;
}
public SybaseDateTime (int year, int month, int day)
notNull = true;
}
- [MonoTODO]
public SybaseDateTime (int year, int month, int day, int hour, int minute, int second, double millisecond)
{
- throw new NotImplementedException ();
+ DateTime t = new DateTime (year, month, day);
+ this.value = new DateTime ((long) (t.Day * 24 * SQLTicksPerHour + hour * SQLTicksPerHour + minute * SQLTicksPerMinute + second * SQLTicksPerSecond + millisecond * 1000));
+ notNull = true;
}
- [MonoTODO]
public SybaseDateTime (int year, int month, int day, int hour, int minute, int second, int bilisecond)
{
- throw new NotImplementedException ();
+ DateTime t = new DateTime (year, month, day);
+ this.value = new DateTime ((long) (t.Day * 24 * SQLTicksPerHour + hour * SQLTicksPerHour + minute * SQLTicksPerMinute + second * SQLTicksPerSecond + bilisecond));
+ notNull = true;
}
#endregion
#region Properties
- [MonoTODO]
public int DayTicks {
- get { throw new NotImplementedException (); }
+ get {
+ return (int) ((this.Value.Ticks - Epoch.Ticks) / (24 * DateTimeTicksPerHour));
+ }
}
public bool IsNull {
get { return !notNull; }
}
- [MonoTODO]
public int TimeTicks {
- get { throw new NotImplementedException (); }
+ get {
+ if (this.IsNull)
+ throw new SybaseNullValueException ();
+ return (int) (value.Hour * SQLTicksPerHour + value.Minute * SQLTicksPerMinute + value.Second * SQLTicksPerSecond + value.Millisecond);
+ }
}
public DateTime Value {
return (x == y);
}
- [MonoTODO]
public override int GetHashCode ()
{
- return 42;
+ return value.GetHashCode ();
}
public static SybaseBoolean GreaterThan (SybaseDateTime x, SybaseDateTime y)
return (x != y);
}
- [MonoTODO]
public static SybaseDateTime Parse (string s)
{
- throw new NotImplementedException ();
+ return new SybaseDateTime (DateTime.Parse (s));
}
public SybaseString ToSybaseString ()
return value.ToString ();
}
- [MonoTODO]
public static SybaseDateTime operator + (SybaseDateTime x, TimeSpan t)
{
- throw new NotImplementedException ();
+ if (x.IsNull)
+ return SybaseDateTime.Null;
+ return new SybaseDateTime (x.Value + t);
}
public static SybaseBoolean operator == (SybaseDateTime x, SybaseDateTime y)
return new SybaseBoolean (x.Value <= y.Value);
}
- [MonoTODO]
public static SybaseDateTime operator - (SybaseDateTime x, TimeSpan t)
{
- throw new NotImplementedException ();
+ if (x.IsNull)
+ return SybaseDateTime.Null;
+ return new SybaseDateTime (x.Value - t);
}
public static explicit operator DateTime (SybaseDateTime x)
return x.Value;
}
- [MonoTODO]
public static explicit operator SybaseDateTime (SybaseString x)
{
- throw new NotImplementedException();
+ return SybaseDateTime.Parse (x.Value);
}
public static implicit operator SybaseDateTime (DateTime x)
// Author:
// Tim Coleman <tim@timcoleman.com>
//
+// Based on System.Data.SqlTypes.SqlDecimal
+//
+// (C) Ximian, Inc. 2002-2003
// (C) Copyright Tim Coleman, 2002
//
using System;
using System.Data.SqlTypes;
using System.Globalization;
+using System.Text;
namespace Mono.Data.SybaseTypes {
public struct SybaseDecimal : INullable, IComparable
const int SCALE_SHIFT = 16;
const int SIGN_SHIFT = 31;
const int RESERVED_SS32_BITS = 0x7F00FFFF;
+ const ulong LIT_GUINT64_HIGHBIT = 0x8000000000000000;
+ const ulong LIT_GUINT32_HIGHBIT = 0x80000000;
+ const byte DECIMAL_MAX_INTFACTORS = 9;
+ static uint [] constantsDecadeInt32Factors = new uint [10]
+ {
+ 1u, 10u, 100u, 1000u, 10000u, 100000u, 1000000u,
+ 10000000u, 100000000u, 1000000000u
+ };
public static readonly byte MaxPrecision = 38;
public static readonly byte MaxScale = 38;
{
int[] binData = Decimal.GetBits (value);
- this.precision = MaxPrecision; // this value seems unclear
-
this.scale = (byte)(binData[3] >> SCALE_SHIFT);
if (this.scale > MaxScale || (this.scale & RESERVED_SS32_BITS) != 0)
throw new ArgumentException(Locale.GetText ("Invalid scale"));
- this.positive = ((binData[3] >> SIGN_SHIFT) > 0);
this.value = new int[4];
this.value[0] = binData[0];
this.value[1] = binData[1];
this.value[2] = binData[2];
this.value[3] = 0;
notNull = true;
+
+ positive = (value >= 0);
+ precision = GetPrecision (value);
}
public SybaseDecimal (double value) : this ((decimal)value) { }
this.value[2] = data3;
this.value[3] = data4;
notNull = true;
+
+ if (precision < scale)
+ throw new ArgumentException ("Invalid scale");
+ if (this.ToDouble () > (Math.Pow (10, 38) -1) || this.ToDouble () < -(Math.Pow (10, 38)))
+ throw new SybaseTypeException ("Can't convert to SybaseDecimal.");
}
#endregion
#region Properties
- [MonoTODO]
public byte[] BinData {
- get { throw new NotImplementedException (); }
+ get {
+ byte[] b = new byte [value.Length * 4];
+ int j = 0;
+ for (int i = 0; i < value.Length; i += 1) {
+ b [j++] = (byte) (0xff & value [i]);
+ b [j++] = (byte) (0xff & value [i] >> 8);
+ b [j++] = (byte) (0xff & value [i] >> 16);
+ b [j++] = (byte) (0xff & value [i] >> 24);
+ }
+ return b;
+ }
}
public int[] Data {
get {
if (this.IsNull)
throw new SybaseNullValueException ();
- else
- if (this.value[3] > 0)
- throw new OverflowException ();
- else
- System.Console.WriteLine( "boo!" );
- return new decimal (value[0], value[1], value[2], !positive, scale);
+ if (this.value[3] > 0)
+ throw new OverflowException ();
+ return new decimal (value[0], value[1], value[2], !positive, scale);
}
}
#region Methods
- [MonoTODO]
public static SybaseDecimal Abs (SybaseDecimal n)
{
- throw new NotImplementedException();
+ return new SybaseDecimal (n.Precision, n.Scale, true, n.BinData [0], n.BinData [1], n.BinData [2], n.BinData [3]);
}
public static SybaseDecimal Add (SybaseDecimal x, SybaseDecimal y)
return (x + y);
}
- [MonoTODO]
public static SybaseDecimal AdjustScale (SybaseDecimal n, int digits, bool fRound)
{
- throw new NotImplementedException ();
+ byte prec = n.Precision;
+ if (n.IsNull)
+ throw new SybaseNullValueException ();
+ if (digits > 0)
+ prec = (byte) (prec + digits);
+ if (fRound)
+ n = Round (n, digits + n.Scale);
+ return new SybaseDecimal (prec, (byte) (n.Scale + digits), n.IsPositive, n.Data);
}
- [MonoTODO]
public static SybaseDecimal Ceiling (SybaseDecimal n)
{
- throw new NotImplementedException();
+ return AdjustScale (n, -(n.Scale), true);
}
public int CompareTo (object value)
return this.Value.CompareTo (((SybaseDecimal)value).Value);
}
- [MonoTODO]
public static SybaseDecimal ConvertToPrecScale (SybaseDecimal n, int precision, int scale)
{
- throw new NotImplementedException ();
+ return new SybaseDecimal ((byte) precision, (byte) scale, n.IsPositive, n.Data);
}
public static SybaseDecimal Divide (SybaseDecimal x, SybaseDecimal y)
{
if (!(value is SybaseDecimal))
return false;
+ else if (this.IsNull && ((SybaseDecimal) value).IsNull)
+ return true;
+ else if (((SybaseDecimal) value).IsNull)
+ return false;
else
return (bool) (this == (SybaseDecimal)value);
}
return (x == y);
}
- [MonoTODO]
public static SybaseDecimal Floor (SybaseDecimal n)
{
- throw new NotImplementedException ();
+ return AdjustScale (n, -(n.Scale), false);
}
internal static SybaseDecimal FromTdsBigDecimal (TdsBigDecimal x)
public override int GetHashCode ()
{
- return (int)this.Value;
+ int result = 10;
+ result = 91 * result + this.Data [0];
+ result = 91 * result + this.Data [1];
+ result = 91 * result + this.Data [2];
+ result = 91 * result + this.Data [3];
+ result = 91 * result + (int) this.Scale;
+ result = 91 * result + (int) this.Precision;
+
+ return result;
}
public static SybaseBoolean GreaterThan (SybaseDecimal x, SybaseDecimal y)
return (x != y);
}
- [MonoTODO]
public static SybaseDecimal Parse (string s)
{
- throw new NotImplementedException ();
+ if (s == null)
+ throw new ArgumentNullException ();
+ else
+ return SybaseDouble.Parse (s).ToSybaseDecimal ();
}
- [MonoTODO]
public static SybaseDecimal Power (SybaseDecimal n, double exp)
{
- throw new NotImplementedException ();
+ if (n.IsNull)
+ return SybaseDecimal.Null;
+ return new SybaseDecimal (Math.Pow (n.ToDouble (), exp));
}
- [MonoTODO]
public static SybaseDecimal Round (SybaseDecimal n, int position)
{
- throw new NotImplementedException ();
+ if (n.IsNull)
+ throw new SybaseNullValueException ();
+ SybaseDecimal result = new SybaseDecimal (Math.Round ((double) (n.ToDouble () * Math.Pow (10, position))));
+ result = result / new SybaseDecimal (Math.Pow (10, position));
+ return result;
}
- [MonoTODO]
public static SybaseInt32 Sign (SybaseDecimal n)
{
- throw new NotImplementedException ();
+ SybaseInt32 result = 0;
+ if (n >= new SybaseDecimal (0))
+ result = 1;
+ else
+ result = -1;
+ return result;
}
public static SybaseDecimal Subtract (SybaseDecimal x, SybaseDecimal y)
return (x - y);
}
+ private static byte GetPrecision (decimal value)
+ {
+ string str = value.ToString ();
+ byte result = 0;
+ foreach (char c in str)
+ if (c >= '0' && c <= '9')
+ result ++;
+ return result;
+ }
+
public double ToDouble ()
{
- return ((double)this.Value);
+ // FIXME: This is the wrong way to do this
+ double d = (uint) this.Data [0];
+ d += ((uint) this.Data [1]) * Math.Pow (2, 32);
+ d += ((uint) this.Data [2]) * Math.Pow (2, 64);
+ d += ((uint) this.Data [3]) * Math.Pow (2, 96);
+ d /= Math.Pow (10, scale);
+ return d;
}
public SybaseBoolean ToSybaseBoolean ()
{
if (this.IsNull)
return String.Empty;
+
+ // convert int [4] -> ulong [2]
+ ulong lo = (uint) this.Data [0] + (ulong) ((ulong) this.Data [1] << 32);
+ ulong hi = (uint) this.Data [2] + (ulong) ((ulong) this.Data [3] << 32);
+
+ uint rest = 0;
+ StringBuilder result = new StringBuilder ();
+ for (int i = 0; lo != 0 || hi != 0; i += 1) {
+ Div128By32 (ref hi, ref lo, 10, ref rest);
+ result.Insert (0, rest.ToString ());
+ }
+ while (result.Length < Precision)
+ result.Append ("0");
+ while (result.Length > Precision)
+ result.Remove (result.Length - 1, 1);
+ if (Scale > 0)
+ result.Insert (result.Length - Scale, ".");
+ return result.ToString ();
+ }
+
+ // from decimal.c
+ private static int Div128By32 (ref ulong hi, ref ulong lo, uint divider)
+ {
+ uint t = 0;
+ return Div128By32 (ref hi, ref lo, divider, ref t);
+ }
+
+ // from decimal.c
+ private static int Div128By32 (ref ulong hi, ref ulong lo, uint divider, ref uint rest)
+ {
+ ulong a = 0;
+ ulong b = 0;
+ ulong c = 0;
+
+ a = (uint) (hi >> 32);
+ b = a / divider;
+ a -= b * divider;
+ a <<= 32;
+ a |= (uint) hi;
+ c = a / divider;
+ a -= c * divider;
+ a <<= 32;
+ hi = b << 32 | (uint) c;
+
+ a = (uint) (lo >> 32);
+ b = a / divider;
+ a -= b * divider;
+ a <<= 32;
+ a |= (uint) lo;
+ c = a / divider;
+ a -= c * divider;
+ a <<= 32;
+ lo = b << 32 | (uint) c;
+
+ rest = (uint) a;
+ a <<= 1;
+
+ return (a > divider || (a == divider && (c & 1) == 1)) ? 1 : 0;
+ }
+
+ [MonoTODO ("Find out what is the right way to set scale and precision")]
+ private static SybaseDecimal DecimalDiv (SybaseDecimal x, SybaseDecimal y)
+ {
+ ulong lo = 0;
+ ulong hi = 0;
+ int sc = 0; // scale
+ int texp = 0;
+ byte prec = 0;
+
+ prec = x.Precision >= y.Precision ? x.Precision : y.Precision;
+ DecimalDivSub (ref x, ref y, ref lo, ref hi, ref texp);
+
+ sc = x.Scale - y.Scale;
+
+ Rescale128 (ref lo, ref hi, ref sc, texp, 0, 38, 1);
+
+ uint r = 0;
+ while (prec < sc) {
+ Div128By32 (ref hi, ref lo, 10, ref r);
+ sc -= 1;
+ }
+
+ if (r >= 5)
+ lo += 1;
+
+ while ((((double) hi) * Math.Pow (2, 64) + lo) - Math.Pow (10, prec) > 0)
+ prec += 1;
+
+ while ((prec + sc) > MaxScale) {
+ Div128By32 (ref hi, ref lo, 10, ref r);
+ sc -= 1;
+ if (r >= 5)
+ lo += 1;
+ }
+
+ int resultLo = (int) lo;
+ int resultMi = (int) (lo >> 32);
+ int resultMi2 = (int) hi;
+ int resultHi = (int) (hi >> 32);
+
+ return new SybaseDecimal (prec, (byte) sc, true, resultLo, resultMi, resultMi2, resultHi);
+ }
+
+ // From decimal.c
+ private static void Rescale128 (ref ulong clo, ref ulong chi, ref int scale, int texp, int minScale, int maxScale, int roundFlag)
+ {
+ uint factor = 0;
+ uint overhang = 0;
+ int sc = 0;
+ int i = 0;
+ int roundBit = 0;
+
+ sc = scale;
+ if (texp > 0) {
+ // reduce exp
+ while (texp > 0 && sc <= maxScale) {
+ overhang = (uint) (chi >> 64);
+ while (texp > 0 && (((clo & 1) == 0) || overhang > 0)) {
+ if (--texp == 0)
+ roundBit = (int) (clo & 1);
+ RShift128 (ref clo, ref chi);
+ overhang = (uint) (chi >> 32);
+ }
+
+ if (texp > DECIMAL_MAX_INTFACTORS)
+ i = DECIMAL_MAX_INTFACTORS;
+ else
+ i = texp;
+
+ if (sc + i > maxScale)
+ i = maxScale - sc;
+ if (i == 0)
+ break;
+
+ texp -= i;
+ sc += i;
+
+ // 10^i/2^i=5^i
+ factor = constantsDecadeInt32Factors [i] >> i;
+ Mult128By32 (ref clo, ref chi, factor, 0);
+ }
+
+ while (texp > 0) {
+ if (--texp == 0)
+ roundBit = (int) (clo & 1);
+ RShift128 (ref clo, ref chi);
+
+ }
+ }
+
+ while (sc > maxScale) {
+ i = scale - maxScale;
+ if (i > DECIMAL_MAX_INTFACTORS)
+ i = DECIMAL_MAX_INTFACTORS;
+ sc -= i;
+ roundBit = Div128By32 (ref clo, ref chi, constantsDecadeInt32Factors [i]);
+ }
+
+ while (sc < minScale) {
+ if (roundFlag == 0)
+ roundBit = 0;
+ i = minScale - sc;
+ if (i > DECIMAL_MAX_INTFACTORS)
+ i = DECIMAL_MAX_INTFACTORS;
+ sc += i;
+ Mult128By32 (ref clo, ref chi, constantsDecadeInt32Factors [i], roundBit);
+ roundBit = 0;
+ }
+ scale = sc;
+ Normalize128 (ref clo, ref chi, ref sc, roundFlag, roundBit);
+ }
+
+ // from decimal.c
+ private static void Normalize128 (ref ulong clo, ref ulong chi, ref int scale, int roundFlag, int roundBit)
+ {
+ if ((roundFlag != 0) && (roundBit != 0))
+ RoundUp128 (ref clo, ref chi);
+ }
+
+ // from decimal.c
+ private static void RoundUp128 (ref ulong lo, ref ulong hi)
+ {
+ if ((++lo) == 0)
+ ++hi;
+ }
+
+ // from decimal.c
+ private static void DecimalDivSub (ref SybaseDecimal x, ref SybaseDecimal y, ref ulong clo, ref ulong chi, ref int exp)
+ {
+ ulong xlo, xmi, xhi;
+ ulong tlo = 0;
+ ulong tmi = 0;
+ ulong thi = 0;
+ uint ylo = 0;
+ uint ymi = 0;
+ uint ymi2 = 0;
+ uint yhi = 0;
+ int ashift = 0;
+ int bshift = 0;
+ int extraBit = 0;
+
+ xhi = (ulong) ((ulong) x.Data [3] << 32) | (ulong) x.Data [2];
+ xmi = (ulong) ((ulong) x.Data [1] << 32) | (ulong) x.Data [0];
+ xlo = (uint) 0;
+ ylo = (uint) y.Data [0];
+ ymi = (uint) y.Data [1];
+ ymi2 = (uint) y.Data [2];
+ yhi = (uint) y.Data [3];
+
+ if (ylo == 0 && ymi == 0 && ymi2 == 0 && yhi == 0)
+ throw new DivideByZeroException ();
+ if (xmi == 0 && xhi == 0) {
+ clo = chi = 0;
+ return;
+ }
+
+ // enlarge dividend to get maximal precision
+ for (ashift = 0; (xhi & LIT_GUINT64_HIGHBIT) == 0; ++ashift)
+ LShift128 (ref xmi, ref xhi);
+
+ // ensure that divisor is at least 2^95
+ for (bshift = 0; (yhi & LIT_GUINT32_HIGHBIT) == 0; ++bshift)
+ LShift128 (ref ylo, ref ymi, ref ymi2, ref yhi);
+
+ thi = ((ulong) yhi) << 32 | (ulong) ymi2;
+ tmi = ((ulong) ymi) << 32 | (ulong) ylo;
+ tlo = 0;
+
+ if (xhi > thi || (xhi == thi && xmi >= tmi)) {
+ Sub192 (xlo, xmi, xhi, tlo, tmi, thi, ref xlo, ref xmi, ref xhi);
+ extraBit = 1;
+ } else {
+ extraBit = 0;
+ }
+
+ Div192By128To128 (xlo, xmi, xhi, ylo, ymi, ymi2, yhi, ref clo, ref chi);
+
+ exp = 128 + ashift - bshift;
+
+ if (extraBit != 0) {
+ RShift128 (ref clo, ref chi);
+ chi += LIT_GUINT64_HIGHBIT;
+ exp -= 1;
+ }
+
+ // try loss free right shift
+ while (exp > 0 && (clo & 1) == 0) {
+ RShift128 (ref clo, ref chi);
+ exp -= 1;
+ }
+ }
+
+ // From decimal.c
+ private static void RShift192 (ref ulong lo, ref ulong mi, ref ulong hi)
+ {
+ lo >>= 1;
+ if ((mi & 1) != 0)
+ lo |= LIT_GUINT64_HIGHBIT;
+
+ mi >>= 1;
+ if ((hi & 1) != 0)
+ mi |= LIT_GUINT64_HIGHBIT;
+
+ hi >>= 1;
+ }
+
+ // From decimal.c
+ private static void RShift128 (ref ulong lo, ref ulong hi)
+ {
+ lo >>= 1;
+ if ((hi & 1) != 0)
+ lo |= LIT_GUINT64_HIGHBIT;
+ hi >>= 1;
+ }
+
+ // From decimal.c
+ private static void LShift128 (ref ulong lo, ref ulong hi)
+ {
+ hi <<= 1;
+
+ if ((lo & LIT_GUINT64_HIGHBIT) != 0)
+ hi += 1;
+
+ lo <<= 1;
+ }
+
+ // From decimal.c
+ private static void LShift128 (ref uint lo, ref uint mi, ref uint mi2, ref uint hi)
+ {
+ hi <<= 1;
+ if ((mi2 & LIT_GUINT32_HIGHBIT) != 0)
+ hi += 1;
+
+ mi2 <<= 1;
+ if ((mi & LIT_GUINT32_HIGHBIT) != 0)
+ mi2 += 1;
+
+ mi <<= 1;
+ if ((lo & LIT_GUINT32_HIGHBIT) != 0)
+ mi += 1;
+
+ lo <<= 1;
+ }
+
+ // From decimal.c
+ private static void Div192By128To128 (ulong xlo, ulong xmi, ulong xhi, uint ylo, uint ymi, uint ymi2, uint yhi, ref ulong clo, ref ulong chi)
+ {
+ ulong rlo, rmi, rhi; // remainders
+ uint h, c;
+
+ rlo = xlo;
+ rmi = xmi;
+ rhi = xhi;
+
+ h = Div192By128To32WithRest (ref rlo, ref rmi, ref rhi, ylo, ymi, ymi2, yhi);
+
+ // mid 32 bit
+ rhi = (rhi << 32) | (rmi >> 32);
+ rmi = (rmi << 32) | (rlo >> 32);
+ rlo <<= 32;
+
+ chi = (((ulong)h) << 32) | Div192By128To32WithRest (ref rlo, ref rmi, ref rhi, ylo, ymi, ymi2, yhi);
+
+ // low 32 bit
+ rhi = (rhi << 32) | (rmi >> 32);
+ rmi = (rmi << 32) | (rlo >> 32);
+ rlo <<= 32;
+
+ h = Div192By128To32WithRest (ref rlo, ref rmi, ref rhi, ylo, ymi, ymi2, yhi);
+
+ // estimate lowest 32 bit (two last bits may be wrong)
+ if (rhi >= yhi)
+ c = 0xFFFFFFFF;
+ else {
+ rhi <<= 32;
+ c = (uint)(rhi / yhi);
+ }
+
+ clo = (((ulong)h) << 32) | c;
+ }
+
+ // From decimal.c
+ private static uint Div192By128To32WithRest (ref ulong xlo, ref ulong xmi, ref ulong xhi, uint ylo, uint ymi, uint ymi2, uint yhi)
+ {
+ ulong rlo, rmi, rhi; // remainder
+ ulong tlo = 0;
+ ulong thi = 0;
+ uint c;
+
+ rlo = xlo;
+ rmi = xmi;
+ rhi = xhi;
+
+ if (rhi >= (((ulong)yhi << 32)))
+ c = 0xFFFFFFFF;
else
- return value.ToString ();
+ c = (uint) (rhi / yhi);
+
+ Mult128By32To128 (ylo, ymi, ymi2, yhi, c, ref tlo, ref thi);
+ Sub192 (rlo, rmi, rhi, 0, tlo, thi, ref rlo, ref rmi, ref rhi);
+
+ while (((long)rhi) < 0) {
+ c--;
+ Add192 (rlo, rmi, rhi, 0, (((ulong)ymi) << 32) | ylo, yhi | ymi2, ref rlo, ref rmi, ref rhi);
+ }
+ xlo = rlo;
+ xmi = rmi;
+ xhi = rhi;
+
+ return c;
+ }
+
+ // From decimal.c
+ private static void Mult192By32 (ref ulong clo, ref ulong cmi, ref ulong chi, ulong factor, int roundBit)
+ {
+ ulong a = 0;
+ uint h0 = 0;
+ uint h1 = 0;
+
+ a = ((ulong)(uint)clo) * factor;
+
+ if (roundBit != 0)
+ a += factor / 2;
+
+ h0 = (uint)a;
+ a >>= 32;
+ a += (clo >> 32) * factor;
+ h1 = (uint)a;
+
+ clo = ((ulong)h1) << 32 | h0;
+
+ a >>= 32;
+ a += ((ulong)(uint)cmi) * factor;
+ h0 = (uint)a;
+
+ a >>= 32;
+ a += (cmi >> 32) * factor;
+ h1 = (uint)a;
+
+ cmi = ((ulong)h1) << 32 | h0;
+ a >>= 32;
+ a += ((ulong)(uint)chi) * factor;
+ h0 = (uint)a;
+
+ a >>= 32;
+ a += (chi >> 32) * factor;
+ h1 = (uint)a;
+ chi = ((ulong)h1) << 32 | h0;
+ }
+
+ // From decimal.c
+ private static void Mult128By32 (ref ulong clo, ref ulong chi, uint factor, int roundBit)
+ {
+ ulong a = 0;
+ uint h0 = 0;
+ uint h1 = 0;
+
+ a = ((ulong)(uint)clo) * factor;
+
+ if (roundBit != 0)
+ a += factor / 2;
+
+ h0 = (uint)a;
+
+ a >>= 32;
+ a += (clo >> 32) * factor;
+ h1 = (uint)a;
+
+ clo = ((ulong)h1) << 32 | h0;
+
+ a >>= 32;
+ a += ((ulong)(uint)chi) * factor;
+ h0 = (uint)a;
+
+ a >>= 32;
+ a += (chi >> 32) * factor;
+ h1 = (uint)a;
+
+ chi = ((ulong)h1) << 32 | h0;
+ }
+
+ // From decimal.c
+ private static void Mult128By32To128 (uint xlo, uint xmi, uint xmi2, uint xhi, uint factor, ref ulong clo, ref ulong chi)
+ {
+ ulong a;
+ uint h0, h1, h2;
+
+ a = ((ulong)xlo) * factor;
+ h0 = (uint)a;
+
+ a >>= 32;
+ a += ((ulong)xmi) * factor;
+ h1 = (uint)a;
+
+ a >>= 32;
+ a += ((ulong)xmi2) * factor;
+ h2 = (uint)a;
+
+ a >>= 32;
+ a += ((ulong)xhi) * factor;
+
+ clo = ((ulong)h1) << 32 | h0;
+ chi = a | h2;
+ }
+
+ // From decimal.c
+ private static void Add192 (ulong xlo, ulong xmi, ulong xhi, ulong ylo, ulong ymi, ulong yhi, ref ulong clo, ref ulong cmi, ref ulong chi)
+ {
+ xlo += ylo;
+ if (xlo < ylo) {
+ xmi++;
+ if (xmi == 0)
+ xhi++;
+ }
+
+ xmi += ymi;
+
+ if (xmi < ymi)
+ xmi++;
+
+ xhi += yhi;
+ clo = xlo;
+ cmi = xmi;
+ chi = xhi;
+ }
+
+ // From decimal.c
+ private static void Sub192 (ulong xlo, ulong xmi, ulong xhi, ulong ylo, ulong ymi, ulong yhi, ref ulong lo, ref ulong mi, ref ulong hi)
+ {
+ ulong clo = 0;
+ ulong cmi = 0;
+ ulong chi = 0;
+
+ clo = xlo - ylo;
+ cmi = xmi - ymi;
+ chi = xhi - yhi;
+
+ if (xlo < ylo) {
+ if (cmi == 0)
+ chi--;
+ cmi--;
+ }
+
+ if (xmi < ymi)
+ chi--;
+
+ lo = clo;
+ mi = cmi;
+ hi = chi;
}
- [MonoTODO]
public static SybaseDecimal Truncate (SybaseDecimal n, int position)
{
- throw new NotImplementedException ();
+ return new SybaseDecimal ((byte) n.Precision, (byte) position, n.IsPositive, n.Data);
}
public static SybaseDecimal operator + (SybaseDecimal x, SybaseDecimal y)
return new SybaseDecimal (resultPrecision, x.Scale, x.IsPositive, resultBits);
}
- [MonoTODO]
public static SybaseDecimal operator / (SybaseDecimal x, SybaseDecimal y)
{
- throw new NotImplementedException ();
+ return DecimalDiv (x, y);
}
public static SybaseBoolean operator == (SybaseDecimal x, SybaseDecimal y)
// Author:
// Tim Coleman <tim@timcoleman.com>
//
-// (C) Copyright Tim Coleman, 2002
+// Based on System.Data.SqlTypes.SqlDouble
+//
+// (C) Ximian, Inc. 2002-2003
+// (C) Copyright Tim Coleman, 2002-2003
//
using Mono.Data.SybaseClient;
private bool notNull;
- public static readonly SybaseDouble MaxValue = new SybaseDouble (1.7976931348623157e308);
- public static readonly SybaseDouble MinValue = new SybaseDouble (-1.7976931348623157e308);
+ public static readonly SybaseDouble MaxValue = new SybaseDouble (1.7976931348623157E+308);
+ public static readonly SybaseDouble MinValue = new SybaseDouble (-1.7976931348623157E+308);
public static readonly SybaseDouble Null;
public static readonly SybaseDouble Zero = new SybaseDouble (0);
// Author:
// Tim Coleman <tim@timcoleman.com>
//
-// (C) Copyright 2002 Tim Coleman
+// Based on System.Data.SqlTypes.SqlMoney
+//
+// (C) Ximian, Inc. 2002-2003
+// (C) Copyright Tim Coleman, 2002-2003
//
using Mono.Data.SybaseClient;
#region Properties
- [MonoTODO]
public bool IsNull {
get { return !notNull; }
}
// Author:
// Tim Coleman (tim@timcoleman.com)
//
-// (C) Copyright Tim Coleman, 2002
+// Based on System.Data.SqlTypes.SqlString
+//
+// (C) Ximian, Inc. 2002-2003
+// (C) Copyright Tim Coleman, 2002-2003
//
using Mono.Data.SybaseClient;
using System;
using System.Data.SqlTypes;
using System.Globalization;
+using System.Text;
namespace Mono.Data.SybaseTypes {
public struct SybaseString : INullable, IComparable
private bool notNull;
- public static readonly int BinarySort;
- public static readonly int IgnoreCase;
- public static readonly int IgnoreKanaType;
- public static readonly int IgnoreNonSpace;
- public static readonly int IgnoreWidth;
+ private CultureInfo cultureInfo;
+ private SybaseCompareOptions compareOptions;
+
+ public static readonly int BinarySort = 0x8000;
+ public static readonly int IgnoreCase = 0x1;
+ public static readonly int IgnoreKanaType = 0x8;
+ public static readonly int IgnoreNonSpace = 0x2;
+ public static readonly int IgnoreWidth = 0x10;
public static readonly SybaseString Null;
#endregion // Fields
public SybaseString (string data)
{
this.value = data;
- notNull = true;
+ this.cultureInfo = CultureInfo.CurrentCulture;
+ this.compareOptions = SybaseCompareOptions.None;
+ this.notNull = true;
}
// init with a string data and locale id values.
- [MonoTODO]
public SybaseString (string data, int lcid)
+ : this (data, lcid, SybaseCompareOptions.None)
{
- throw new NotImplementedException ();
}
// init with locale id, compare options,
// and an array of bytes data
- [MonoTODO]
public SybaseString (int lcid, SybaseCompareOptions compareOptions, byte[] data)
+ : this (lcid, compareOptions, data, true)
{
- throw new NotImplementedException ();
}
// init with string data, locale id, and compare options
- [MonoTODO]
public SybaseString (string data, int lcid, SybaseCompareOptions compareOptions)
{
- throw new NotImplementedException ();
+ this.value = data;
+ this.cultureInfo = new CultureInfo (lcid);
+ this.compareOptions = compareOptions;
+ this.notNull = true;
}
// init with locale id, compare options, array of bytes data,
// and whether unicode is encoded or not
- [MonoTODO]
public SybaseString (int lcid, SybaseCompareOptions compareOptions, byte[] data, bool fUnicode)
{
- throw new NotImplementedException ();
+ Encoding encoding;
+ if (fUnicode)
+ encoding = new UnicodeEncoding ();
+ else
+ encoding = new ASCIIEncoding ();
+
+ this.value = encoding.GetString (data);
+ this.cultureInfo = new CultureInfo (lcid);
+ this.compareOptions = compareOptions;
+ this.notNull = true;
}
// init with locale id, compare options, array of bytes data,
// starting index in the byte array,
// and number of bytes to copy
- [MonoTODO]
public SybaseString (int lcid, SybaseCompareOptions compareOptions, byte[] data, int index, int count)
+ : this (lcid, compareOptions, data, index, count, true)
{
- throw new NotImplementedException ();
}
// init with locale id, compare options, array of bytes data,
// starting index in the byte array, number of byte to copy,
// and whether unicode is encoded or not
- [MonoTODO]
public SybaseString (int lcid, SybaseCompareOptions compareOptions, byte[] data, int index, int count, bool fUnicode)
{
- throw new NotImplementedException ();
+ Encoding encoding;
+ if (fUnicode)
+ encoding = new UnicodeEncoding ();
+ else
+ encoding = new ASCIIEncoding ();
+
+ this.value = encoding.GetString (data, index, count);
+ this.cultureInfo = new CultureInfo (lcid);
+ this.compareOptions = compareOptions;
+ this.notNull = true;
}
#endregion // Constructors
#region Public Properties
public CompareInfo CompareInfo {
- [MonoTODO]
- get { throw new NotImplementedException ();
- }
+ get { return cultureInfo.CompareInfo; }
}
public CultureInfo CultureInfo {
- [MonoTODO]
- get { throw new NotImplementedException ();
- }
+ get { return cultureInfo; }
}
public bool IsNull {
// geographics location and language (locale id)
public int LCID {
- [MonoTODO]
- get { throw new NotImplementedException ();
- }
+ get { return cultureInfo.LCID; }
}
public SybaseCompareOptions SybaseCompareOptions {
- [MonoTODO]
- get { throw new NotImplementedException ();
- }
+ get { return compareOptions; }
}
- public string Value {
- get {
- if (this.IsNull)
- throw new SybaseNullValueException ("The property contains Null.");
- else
- return value;
- }
- }
+ public string Value {
+ get {
+ if (this.IsNull)
+ throw new SybaseNullValueException ("The property contains Null.");
+ else
+ return value;
+ }
+ }
#endregion // Public Properties
#region Public Methods
- [MonoTODO]
public SybaseString Clone()
{
- throw new NotImplementedException ();
+ return new SybaseString (value, LCID, SybaseCompareOptions);
}
- [MonoTODO]
public static CompareOptions CompareOptionsFromSybaseCompareOptions (SybaseCompareOptions compareOptions)
{
- throw new NotImplementedException ();
+ CompareOptions options = CompareOptions.None;
+ if ((compareOptions & SybaseCompareOptions.IgnoreCase) != 0)
+ options |= CompareOptions.IgnoreCase;
+ if ((compareOptions & SybaseCompareOptions.IgnoreKanaType) != 0)
+ options |= CompareOptions.IgnoreKanaType;
+ if ((compareOptions & SybaseCompareOptions.IgnoreNonSpace) != 0)
+ options |= CompareOptions.IgnoreNonSpace;
+ if ((compareOptions & SybaseCompareOptions.IgnoreWidth) != 0)
+ options |= CompareOptions.IgnoreWidth;
+ if ((compareOptions & SybaseCompareOptions.BinarySort) != 0)
+ throw new ArgumentOutOfRangeException ();
+ return options;
}
// **********************************
return (x == y);
}
- [MonoTODO]
public override int GetHashCode()
{
- throw new NotImplementedException ();
+ int result = 10;
+ for (int i = 0; i < value.Length; i += 1)
+ result = 91 * result + (int) (value [i] ^ (value [i] >> 32));
+ result = 91 * result + LCID.GetHashCode ();
+ result = 91 * result + (int) compareOptions;
+ return result;
}
- [MonoTODO]
public byte[] GetNonUnicodeBytes()
{
- throw new NotImplementedException ();
+ return GetBytes (new ASCIIEncoding ());
}
- [MonoTODO]
public byte[] GetUnicodeBytes()
{
- throw new NotImplementedException ();
+ return GetBytes (new UnicodeEncoding ());
+ }
+
+ private byte[] GetBytes (Encoding encoding)
+ {
+ int blen = encoding.GetByteCount (value);
+ int clen = value.Length;
+ byte[] bytes = new byte [blen];
+ encoding.GetBytes (value, 0, clen, bytes, 0);
+ return bytes;
}
public static SybaseBoolean GreaterThan(SybaseString x, SybaseString y)