X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mcs%2Fclass%2FSystem.Data%2FSystem.Data.Common%2FDataContainer.cs;h=7a46a04e229bf032d80c816b3db05028a94a5b05;hb=0dd29f1e7f47587ddf69b85480280249e035d12e;hp=cac69098381d578a5d7affe434bcc0a3b87b939a;hpb=64f85a65b023522d3f34e9932e6a843e0ad8fc3b;p=mono.git diff --git a/mcs/class/System.Data/System.Data.Common/DataContainer.cs b/mcs/class/System.Data/System.Data.Common/DataContainer.cs index cac69098381..7a46a04e229 100644 --- a/mcs/class/System.Data/System.Data.Common/DataContainer.cs +++ b/mcs/class/System.Data/System.Data.Common/DataContainer.cs @@ -1,1772 +1,1010 @@ - -// -// 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.Collections; - -namespace System.Data.Common -{ - internal abstract class AbstractDataContainer - { - #region Fields - - BitArray _nullValues; - System.Type _type; - DataColumn _column; - - #endregion //Fields - - #region Properties - - internal abstract object this[int index] { - get; - set; - } - - internal virtual int Capacity { - get { - return (_nullValues != null) ? _nullValues.Count : 0; - } - set { - if (_nullValues == null) { - _nullValues = new BitArray(value); - } - else { - _nullValues.Length = value; - } - } - } - - internal Type Type { - get { - return _type; - } - } - - protected DataColumn Column { - get { - return _column; - } - } - - #endregion //Properties - - #region Methods - - internal static AbstractDataContainer CreateInstance(Type type, DataColumn column) - { - AbstractDataContainer container; - switch (Type.GetTypeCode(type)) { - case TypeCode.Int16 : - container = new Int16DataContainer(); - break; - case TypeCode.Int32 : - container = new Int32DataContainer(); - break; - case TypeCode.Int64 : - container = new Int64DataContainer(); - break; - case TypeCode.String : - container = new StringDataContainer(); - break; - case TypeCode.Boolean: - container = new BitDataContainer(); - break; - case TypeCode.Byte : - container = new ByteDataContainer(); - break; - case TypeCode.Char : - container = new CharDataContainer(); - break; - case TypeCode.Double : - container = new DoubleDataContainer(); - break; - case TypeCode.SByte : - container = new SByteDataContainer(); - break; - case TypeCode.Single : - container = new SingleDataContainer(); - break; - case TypeCode.UInt16 : - container = new UInt16DataContainer(); - break; - case TypeCode.UInt32 : - container = new UInt32DataContainer(); - break; - case TypeCode.UInt64 : - container = new UInt64DataContainer(); - break; - case TypeCode.DateTime : - container = new DateTimeDataContainer(); - break; - case TypeCode.Decimal : - container = new DecimalDataContainer(); - break; - default : - container = new ObjectDataContainer(); - break; - } - container._type = type; - container._column = column; - return container; - } - - internal bool IsNull(int index) - { - return (_nullValues != null) ? _nullValues[index] : true; - } - - internal void SetNullBit(int index,bool isNull) - { - _nullValues[index] = isNull; - } - - protected void SetNull(int index,bool isNull,bool isDbNull) - { - SetNullBit(index,isDbNull); - // this method must be called after setting the value into value array - // otherwise the dafault value will be overriden - if ( isNull ) { - // set the value to default - CopyValue(Column.Table.DefaultValuesRowIndex,index); - } - } - - internal void FillValues(int fromIndex) - { - for(int i=0; i < Capacity; i++) { - CopyValue(fromIndex,i); - _nullValues[i] = _nullValues[fromIndex]; - } - } - - internal virtual void CopyValue(AbstractDataContainer fromContainer, int fromIndex, int toIndex) - { - _nullValues[toIndex] = fromContainer._nullValues[fromIndex]; - } - - internal virtual void CopyValue(int fromIndex, int toIndex) - { - _nullValues[toIndex] = _nullValues[fromIndex]; - } - - internal abstract void SetItemFromDataRecord(int index, IDataRecord record, int field); - - protected int CompareNulls(int index1, int index2) - { - bool null1 = IsNull(index1); - bool null2 = IsNull(index2); - - if ( null1 ^ null2 ) { - return null1 ? -1 : 1; - } - else { - return 0; - } - } - - internal abstract int CompareValues(int index1, int index2); - - internal abstract long GetInt64(int index); - - #endregion //Methods - - sealed class Int16DataContainer : AbstractDataContainer - { - #region Fields - - short[] _values; - - #endregion //Fields - - #region Properties - - internal override object this[int index] { - get { - if (IsNull(index)) { - return DBNull.Value; - } - else { - return _values[index]; - } - } - set { - bool isDbNull = (value == DBNull.Value); - if (value == null || isDbNull) { - SetValue(index,0); - } - else if( value is short ) { - SetValue(index,(short)value); - } - else { - SetValue(index,Convert.ToInt16(value)); - } - SetNull(index,value == null,isDbNull); - } - } - - internal override int Capacity { - set { - base.Capacity = value; - if (_values == null) { - _values = new short[value]; - } - else { - short[] tmp = new short[value]; - Array.Copy(_values,0,tmp,0,_values.Length); - _values = tmp; - } - } - } - - #endregion //Properties - - #region Methods - - private void SetValue(int index, short value) - { - _values[index] = value; - } - - internal override void SetItemFromDataRecord(int index, IDataRecord record, int field) - { - bool isDbNull = record.IsDBNull(field); - if (isDbNull) { - SetNull(index,false,isDbNull); - return; - } - - // if exception thrown, it should be caught in the caller method - if (record is ISafeDataRecord) { - SetValue(index,((ISafeDataRecord)record).GetInt16Safe(field)); - } - else { - this[index] = record.GetValue(field); - } - } - - internal override void CopyValue(int fromIndex, int toIndex) - { - base.CopyValue(fromIndex, toIndex); - _values[toIndex] = _values[fromIndex]; - } - - internal override void CopyValue(AbstractDataContainer fromContainer, int fromIndex, int toIndex) - { - base.CopyValue(fromContainer, fromIndex, toIndex); - _values[toIndex] = ((Int16DataContainer)fromContainer)._values[fromIndex]; - } - - internal override int CompareValues(int index1, int index2) - { - short s1 = _values[index1]; - short s2 = _values[index2]; - - if ( s1 == 0 || s2 == 0 ) { - int cn = CompareNulls(index1, index2); - if (cn != 0) - return cn; - } - - return s1 - s2; - } - - internal override long GetInt64(int index) - { - return (long) _values[index]; - } - - #endregion //Methods - } - - sealed class Int32DataContainer : AbstractDataContainer - { - #region Fields - - int[] _values; - - #endregion //Fields - - #region Properties - - internal override object this[int index] { - get { - if (IsNull(index)) { - return DBNull.Value; - } - else { - return _values[index]; - } - } - set { - bool isDbNull = (value == DBNull.Value); - if (value == null || isDbNull) { - SetValue(index,0); - } - else if( value is int ) { - SetValue(index,(int)value); - } - else { - SetValue(index,Convert.ToInt32(value)); - } - SetNull(index,value == null,isDbNull); - } - } - - internal override int Capacity { - set { - base.Capacity = value; - if (_values == null) { - _values = new int[value]; - } - else { - int[] tmp = new int[value]; - Array.Copy(_values,0,tmp,0,_values.Length); - _values = tmp; - } - } - } - - #endregion //Properties - - #region Methods - - private void SetValue(int index, int value) - { - _values[index] = value; - } - - internal override void SetItemFromDataRecord(int index, IDataRecord record, int field) - { - bool isDbNull = record.IsDBNull(field); - if (isDbNull) { - SetNull(index,false,isDbNull); - return; - } - - // if exception thrown, it should be caught in the caller method - if (record is ISafeDataRecord) { - SetValue(index,((ISafeDataRecord)record).GetInt32Safe(field)); - } - else { - this[index] = record.GetValue(field); - } - } - - internal override void CopyValue(int fromIndex, int toIndex) - { - base.CopyValue(fromIndex, toIndex); - _values[toIndex] = _values[fromIndex]; - } - - internal override void CopyValue(AbstractDataContainer fromContainer, int fromIndex, int toIndex) - { - base.CopyValue(fromContainer, fromIndex, toIndex); - _values[toIndex] = ((Int32DataContainer)fromContainer)._values[fromIndex]; - } - - internal override int CompareValues(int index1, int index2) - { - int i1 = _values[index1]; - int i2 = _values[index2]; - - if (i1 == 0 || i2 == 0) { - int cn = CompareNulls(index1, index2); - if (cn != 0) - return cn; - } - - if ( i1 <= i2 ) { - return ( i1 == i2 ) ? 0 : -1; - } - return 1; - } - - internal override long GetInt64(int index) - { - return (long) _values[index]; - } - - #endregion //Methods - } - - sealed class Int64DataContainer : AbstractDataContainer - { - #region Fields - - long[] _values; - - #endregion //Fields - - #region Properties - - internal override object this[int index] { - get { - if (IsNull(index)) { - return DBNull.Value; - } - else { - return _values[index]; - } - } - set { - bool isDbNull = (value == DBNull.Value); - if (value == null || isDbNull) { - SetValue(index,0); - } - else if( value is long ) { - SetValue(index,(long)value); - } - else { - SetValue(index,Convert.ToInt64(value)); - } - SetNull(index,value == null,isDbNull); - } - } - - internal override int Capacity { - set { - base.Capacity = value; - if (_values == null) { - _values = new long[value]; - } - else { - long[] tmp = new long[value]; - Array.Copy(_values,0,tmp,0,_values.Length); - _values = tmp; - } - } - } - - #endregion //Properties - - #region Methods - - private void SetValue(int index, long value) - { - _values[index] = value; - } - - internal override void SetItemFromDataRecord(int index, IDataRecord record, int field) - { - bool isDbNull = record.IsDBNull(field); - if (isDbNull) { - SetNull(index,false,isDbNull); - return; - } - - // if exception thrown, it should be caught in the caller method - if (record is ISafeDataRecord) { - SetValue(index,((ISafeDataRecord)record).GetInt64Safe(field)); - } - else { - this[index] = record.GetValue(field); - } - } - - internal override void CopyValue(int fromIndex, int toIndex) - { - base.CopyValue(fromIndex, toIndex); - _values[toIndex] = _values[fromIndex]; - } - - internal override void CopyValue(AbstractDataContainer fromContainer, int fromIndex, int toIndex) - { - base.CopyValue(fromContainer, fromIndex, toIndex); - _values[toIndex] = ((Int64DataContainer)fromContainer)._values[fromIndex]; - } - - internal override int CompareValues(int index1, int index2) - { - long l1 = _values[index1]; - long l2 = _values[index2]; - - if ( l1 == 0 || l2 == 0 ) { - int cn = CompareNulls(index1, index2); - if (cn != 0) { - return cn; - } - } - - if ( l1 <= l2 ) { - return ( l1 != l2 ) ? -1 : 0; - } - return 1; - } - - internal override long GetInt64(int index) - { - return _values[index]; - } - - #endregion //Methods - } - - sealed class SingleDataContainer : AbstractDataContainer - { - #region Fields - - float[] _values; - - #endregion //Fields - - #region Properties - - internal override object this[int index] { - get { - if (IsNull(index)) { - return DBNull.Value; - } - else { - return _values[index]; - } - } - set { - bool isDbNull = (value == DBNull.Value); - if (value == null || isDbNull) { - SetValue(index,0); - } - else if( value is float ) { - SetValue(index,(float)value); - } - else { - SetValue(index,Convert.ToSingle(value)); - } - SetNull(index,value == null,isDbNull); - } - } - - internal override int Capacity { - set { - base.Capacity = value; - if (_values == null) { - _values = new float[value]; - } - else { - float[] tmp = new float[value]; - Array.Copy(_values,0,tmp,0,_values.Length); - _values = tmp; - } - } - } - - #endregion //Properties - - #region Methods - - private void SetValue(int index, float value) - { - _values[index] = value; - } - - internal override void SetItemFromDataRecord(int index, IDataRecord record, int field) - { - bool isDbNull = record.IsDBNull(field); - if (isDbNull) { - SetNull(index,false,isDbNull); - return; - } - - // if exception thrown, it should be caught in the caller method - if (record is ISafeDataRecord) { - SetValue(index,((ISafeDataRecord)record).GetFloatSafe(field)); - } - else { - this[index] = record.GetValue(field); - } - } - - internal override void CopyValue(int fromIndex, int toIndex) - { - base.CopyValue(fromIndex, toIndex); - _values[toIndex] = _values[fromIndex]; - } - - internal override void CopyValue(AbstractDataContainer fromContainer, int fromIndex, int toIndex) - { - base.CopyValue(fromContainer, fromIndex, toIndex); - _values[toIndex] = ((SingleDataContainer)fromContainer)._values[fromIndex]; - } - - internal override int CompareValues(int index1, int index2) - { - float f1 = _values[index1]; - float f2 = _values[index2]; - - if ( f1 == 0 || f2 == 0 ) { - int cn = CompareNulls(index1, index2); - if (cn != 0) { - return cn; - } - } - - if ( f1 <= f2 ) { - return ( f1 != f2 ) ? -1 : 0; - } - return 1; - } - - internal override long GetInt64(int index) - { - return Convert.ToInt64(_values[index]); - } - - #endregion //Methods - } - - sealed class DoubleDataContainer : AbstractDataContainer - { - #region Fields - - double[] _values; - - #endregion //Fields - - #region Properties - - internal override object this[int index] { - get { - if (IsNull(index)) { - return DBNull.Value; - } - else { - return _values[index]; - } - } - set { - bool isDbNull = (value == DBNull.Value); - if (value == null || isDbNull) { - SetValue(index,0); - } - else if( value is double ) { - SetValue(index,(double)value); - } - else { - SetValue(index,Convert.ToDouble(value)); - } - SetNull(index,value == null,isDbNull); - } - } - - internal override int Capacity { - set { - base.Capacity = value; - if (_values == null) { - _values = new double[value]; - } - else { - double[] tmp = new double[value]; - Array.Copy(_values,0,tmp,0,_values.Length); - _values = tmp; - } - } - } - - #endregion //Properties - - #region Methods - - private void SetValue(int index, double value) - { - _values[index] = value; - } - - internal override void SetItemFromDataRecord(int index, IDataRecord record, int field) - { - bool isDbNull = record.IsDBNull(field); - if (isDbNull) { - SetNull(index,false,isDbNull); - return; - } - - // if exception thrown, it should be caught in the caller method - if (record is ISafeDataRecord) { - SetValue(index,((ISafeDataRecord)record).GetDoubleSafe(field)); - } - else { - this[index] = record.GetValue(field); - } - } - - internal override void CopyValue(int fromIndex, int toIndex) - { - base.CopyValue(fromIndex, toIndex); - _values[toIndex] = _values[fromIndex]; - } - - internal override void CopyValue(AbstractDataContainer fromContainer, int fromIndex, int toIndex) - { - base.CopyValue(fromContainer, fromIndex, toIndex); - _values[toIndex] = ((DoubleDataContainer)fromContainer)._values[fromIndex]; - } - - internal override int CompareValues(int index1, int index2) - { - double d1 = _values[index1]; - double d2 = _values[index2]; - - if ( d1 == 0 || d2 == 0 ) { - int cn = CompareNulls(index1, index2); - if (cn != 0) { - return cn; - } - } - - if ( d1 <= d2 ) { - return ( d1 != d2 ) ? -1 : 0; - } - return 1; - } - - internal override long GetInt64(int index) - { - return Convert.ToInt64(_values[index]); - } - - #endregion //Methods - } - - sealed class ByteDataContainer : AbstractDataContainer - { - #region Fields - - byte[] _values; - - #endregion //Fields - - #region Properties - - internal override object this[int index] { - get { - if (IsNull(index)) { - return DBNull.Value; - } - else { - return _values[index]; - } - } - set { - bool isDbNull = (value == DBNull.Value); - if (value == null || isDbNull) { - SetValue(index,0); - } - else if( value is byte ) { - SetValue(index,(byte)value); - } - else { - SetValue(index,Convert.ToByte(value)); - } - SetNull(index,value == null,isDbNull); - } - } - - internal override int Capacity { - set { - base.Capacity = value; - if (_values == null) { - _values = new byte[value]; - } - else { - byte[] tmp = new byte[value]; - Array.Copy(_values,0,tmp,0,_values.Length); - _values = tmp; - } - } - } - - #endregion //Properties - - #region Methods - - private void SetValue(int index, byte value) - { - _values[index] = value; - } - - internal override void SetItemFromDataRecord(int index, IDataRecord record, int field) - { - bool isDbNull = record.IsDBNull(field); - if (isDbNull) { - SetNull(index,false,isDbNull); - return; - } - - // if exception thrown, it should be caught in the caller method - if (record is ISafeDataRecord) { - SetValue(index,((ISafeDataRecord)record).GetByteSafe(field)); - } - else { - this[index] = record.GetValue(field); - } - } - - internal override void CopyValue(int fromIndex, int toIndex) - { - base.CopyValue(fromIndex, toIndex); - _values[toIndex] = _values[fromIndex]; - } - - internal override void CopyValue(AbstractDataContainer fromContainer, int fromIndex, int toIndex) - { - base.CopyValue(fromContainer, fromIndex, toIndex); - _values[toIndex] = ((ByteDataContainer)fromContainer)._values[fromIndex]; - } - - internal override int CompareValues(int index1, int index2) - { - byte b1 = _values[index1]; - byte b2 = _values[index2]; - - if ( b1 == 0 || b2 == 0 ) { - int cn = CompareNulls(index1, index2); - if (cn != 0) { - return cn; - } - } - - return b1 - b2; - } - - internal override long GetInt64(int index) - { - return (long) _values[index]; - } - - #endregion //Methods - } - - sealed class BitDataContainer : AbstractDataContainer - { - #region Fields - - bool[] _values; - - #endregion //Fields - - #region Properties - - internal override object this[int index] { - get { - bool isNull = IsNull(index); - if (isNull) { - return DBNull.Value; - } - else { - return _values[index]; - } - } - set { - bool isDbNull = (value == DBNull.Value); - if (value == null || isDbNull) { - SetValue(index,false); - } - else if( value is bool ) { - SetValue(index,(bool)value); - } - else { - SetValue(index,Convert.ToBoolean(value)); - } - SetNull(index,value == null,isDbNull); - } - } - - internal override int Capacity { - set { - base.Capacity = value; - if (_values == null) { - _values = new bool[value]; - } - else { - bool[] tmp = new bool[value]; - Array.Copy(_values,0,tmp,0,_values.Length); - _values = tmp; - } - } - } - - #endregion //Properties - - #region Methods - - private void SetValue(int index, bool value) - { - _values[index] = value; - } - - internal override void SetItemFromDataRecord(int index, IDataRecord record, int field) - { - bool isDbNull = record.IsDBNull(field); - if (isDbNull) { - SetNull(index,false,isDbNull); - return; - } - - // if exception thrown, it should be caught in the caller method - if (record is ISafeDataRecord) { - SetValue(index,((ISafeDataRecord)record).GetBooleanSafe(field)); - } - else { - this[index] = record.GetValue(field); - } - } - - internal override void CopyValue(int fromIndex, int toIndex) - { - base.CopyValue(fromIndex, toIndex); - _values[toIndex] = _values[fromIndex]; - } - - internal override void CopyValue(AbstractDataContainer fromContainer, int fromIndex, int toIndex) - { - base.CopyValue(fromContainer, fromIndex, toIndex); - _values[toIndex] = ((BitDataContainer)fromContainer)._values[fromIndex]; - } - - internal override int CompareValues(int index1, int index2) - { - bool b1 = _values[index1]; - bool b2 = _values[index2]; - - if ( b1 ^ b2 ) { - return b1 ? 1 : -1; - } - - if ( b1 ) { - return 0; - } - - return CompareNulls(index1, index2); - } - - internal override long GetInt64(int index) - { - return Convert.ToInt64(_values[index]); - } - - #endregion //Methods - } - - abstract class AbstractObjectDataContainer : AbstractDataContainer - { - #region Fields - - object[] _values; - - #endregion //Fields - - #region Properties - - internal override object this[int index] { - get { - if (IsNull(index)) - return DBNull.Value; - - return _values[index]; - } - set { - SetValue(index,value); - SetNull(index,value == null,value == DBNull.Value); - } - } - - internal override int Capacity { - set { - base.Capacity = value; - if (_values == null) { - _values = new object[value]; - } - else { - object[] tmp = new object[value]; - Array.Copy(_values,0,tmp,0,_values.Length); - _values = tmp; - } - } - } - - #endregion //Properties - - #region Methods - - protected virtual void SetValue(int index, object value) - { - if(value == null) { - value = Column.DefaultValue; - } - _values[index] = value; - } - - internal override void CopyValue(int fromIndex, int toIndex) - { - base.CopyValue(fromIndex, toIndex); - _values[toIndex] = _values[fromIndex]; - } - - internal override void CopyValue(AbstractDataContainer fromContainer, int fromIndex, int toIndex) - { - base.CopyValue(fromContainer, fromIndex, toIndex); - _values[toIndex] = ((AbstractObjectDataContainer)fromContainer)._values[fromIndex]; - } - - internal override int CompareValues(int index1, int index2) - { - object obj1 = _values[index1]; - object obj2 = _values[index2]; - if(obj1 == obj2) - { - return 0; - } - else - { - int cn = CompareNulls(index1, index2); - if (cn != 0) - return cn; - - if (obj1 is IComparable) - { - try - { - return ((IComparable)obj1).CompareTo(obj2); - } - catch - { - //just suppress - } - - if (obj2 is IComparable) - { - obj2 = Convert.ChangeType(obj2, Type.GetTypeCode(obj1.GetType())); - return ((IComparable)obj1).CompareTo(obj2); - } - } - } - - return String.Compare(obj1.ToString(), obj2.ToString()); - } - - internal override long GetInt64(int index) - { - return Convert.ToInt64(_values[index]); - } - - #endregion //Methods - - } - - sealed class ObjectDataContainer : AbstractObjectDataContainer - { - #region Methods - internal override void SetItemFromDataRecord(int index, IDataRecord record, int field) - { - bool isDbNull = record.IsDBNull(field); - if (isDbNull) { - SetNull(index,false,isDbNull); - return; - } - - // if exception thrown, it should be caught - // in the caller method - SetValue(index,record.GetValue(field)); - } - - #endregion //Methods - - } - - sealed class DateTimeDataContainer : AbstractObjectDataContainer - { - #region Methods - internal override void SetItemFromDataRecord(int index, IDataRecord record, int field) - { - bool isDbNull = record.IsDBNull(field); - if (isDbNull) { - SetNull(index,false,isDbNull); - return; - } - - // if exception thrown, it should be caught - // in the caller method - // if exception thrown, it should be caught in the caller method - if (record is ISafeDataRecord) { - SetValue(index,((ISafeDataRecord)record).GetDateTimeSafe(field)); - } - else { - this[index] = record.GetValue(field); - } - } - - protected override void SetValue(int index, object value) - { - if (value != null && value != DBNull.Value) - value = Convert.ToDateTime(value); - base.SetValue(index, value); - } - #endregion //Methods - - } - - sealed class DecimalDataContainer : AbstractObjectDataContainer - { - #region Methods - internal override void SetItemFromDataRecord(int index, IDataRecord record, int field) - { - bool isDbNull = record.IsDBNull(field); - if (isDbNull) { - SetNull(index,false,isDbNull); - return; - } - - // if exception thrown, it should be caught in the caller method - if (record is ISafeDataRecord) { - SetValue(index,((ISafeDataRecord)record).GetDecimalSafe(field)); - } - else { - this[index] = record.GetValue(field); - } - } - - protected override void SetValue(int index, object value) - { - if (value != null && value != DBNull.Value) - value = Convert.ToDecimal(value); - base.SetValue(index, value); - } - #endregion //Methods - - } - - sealed class StringDataContainer : AbstractObjectDataContainer - { - #region Methods - - private void SetValue(int index, string value) - { - if (value != null && Column.MaxLength >= 0 && Column.MaxLength < value.Length ) { - throw new ArgumentException("Cannot set column '" + Column.ColumnName + "' to '" + value + "'. The value violates the MaxLength limit of this column."); - } - base.SetValue(index,value); - } - - protected override void SetValue(int index, object value) - { - if ( value != null && value != DBNull.Value ) { - if ( value is string ) { - SetValue(index, (string) value); - } - else { - SetValue(index, Convert.ToString(value)); - } - return; - } - - base.SetValue(index, value); - } - - internal override void SetItemFromDataRecord(int index, IDataRecord record, int field) - { - bool isDbNull = record.IsDBNull(field); - if (isDbNull) { - SetNull(index,false,isDbNull); - return; - } - - // if exception thrown, it should be caught - // in the caller method - if (record is ISafeDataRecord) { - SetValue(index,((ISafeDataRecord)record).GetStringSafe(field)); - } - else { - this[index] = record.GetValue(field); - } - } - - internal override int CompareValues(int index1, int index2) - { - bool isNull1 = IsNull(index1); - bool isNull2 = IsNull(index2); - - if (isNull1) { - return isNull2 ? 0 : -1; - } - else { - if (isNull2) { - return 1; - } - } - return String.Compare((string)this[index1], (string)this[index2], !Column.Table.CaseSensitive); - } - - #endregion //Methods - } - - sealed class CharDataContainer : AbstractDataContainer - { - #region Fields - - char[] _values; - - #endregion //Fields - - #region Properties - - internal override object this[int index] { - get { - if (IsNull(index)) { - return DBNull.Value; - } - else { - return _values[index]; - } - } - set { - bool isDbNull = (value == DBNull.Value); - if (value == null || isDbNull) { - SetValue(index,'\0'); - } - else if( value is char ) { - SetValue(index,(char)value); - } - else { - SetValue(index,Convert.ToChar(value)); - } - SetNull(index,value == null,isDbNull); - } - } - - internal override int Capacity { - set { - base.Capacity = value; - if (_values == null) { - _values = new char[value]; - } - else { - char[] tmp = new char[value]; - Array.Copy(_values,0,tmp,0,_values.Length); - _values = tmp; - } - } - } - - #endregion //Properties - - #region Methods - - private void SetValue(int index, char value) - { - _values[index] = value; - } - - internal override void SetItemFromDataRecord(int index, IDataRecord record, int field) - { - bool isDbNull = record.IsDBNull(field); - if (isDbNull) { - SetNull(index,false,isDbNull); - return; - } - - // if exception thrown, it should be caught in the caller method - if (record is ISafeDataRecord) { - SetValue(index,((ISafeDataRecord)record).GetCharSafe(field)); - } - else { - this[index] = record.GetValue(field); - } - } - - internal override void CopyValue(int fromIndex, int toIndex) - { - base.CopyValue(fromIndex, toIndex); - _values[toIndex] = _values[fromIndex]; - } - - internal override void CopyValue(AbstractDataContainer fromContainer, int fromIndex, int toIndex) - { - base.CopyValue(fromContainer, fromIndex, toIndex); - _values[toIndex] = ((CharDataContainer)fromContainer)._values[fromIndex]; - } - - internal override int CompareValues(int index1, int index2) - { - char c1 = _values[index1]; - char c2 = _values[index2]; - - if ( c1 == '\0' || c2 == '\0' ) - { - int cn = CompareNulls(index1, index2); - if (cn != 0) - return cn; - } - - return c1 - c2; - } - - internal override long GetInt64(int index) - { - return Convert.ToInt64(_values[index]); - } - - #endregion //Methods - } - - sealed class UInt16DataContainer : AbstractDataContainer - { - #region Fields - - ushort[] _values; - - #endregion //Fields - - #region Properties - - internal override object this[int index] { - get { - if (IsNull(index)) { - return DBNull.Value; - } - else { - return _values[index]; - } - } - set { - bool isDbNull = (value == DBNull.Value); - if (value == null || isDbNull) { - SetValue(index,0); - } - else if( value is ushort ) { - SetValue(index,(ushort)value); - } - else { - SetValue(index,Convert.ToUInt16(value)); - } - SetNull(index,value == null,isDbNull); - } - } - - internal override int Capacity { - set { - base.Capacity = value; - if (_values == null) { - _values = new ushort[value]; - } - else { - ushort[] tmp = new ushort[value]; - Array.Copy(_values,0,tmp,0,_values.Length); - _values = tmp; - } - } - } - - #endregion //Properties - - #region Methods - - private void SetValue(int index, ushort value) - { - _values[index] = value; - } - - internal override void SetItemFromDataRecord(int index, IDataRecord record, int field) - { - bool isDbNull = record.IsDBNull(field); - if (isDbNull) { - SetNull(index,false,isDbNull); - return; - } - - // if exception thrown, it should be caught in the caller method - if (record is ISafeDataRecord) { - SetValue(index,(ushort)((ISafeDataRecord)record).GetInt16Safe(field)); - } - else { - this[index] = record.GetValue(field); - } - } - - internal override void CopyValue(int fromIndex, int toIndex) - { - base.CopyValue(fromIndex, toIndex); - _values[toIndex] = _values[fromIndex]; - } - - internal override void CopyValue(AbstractDataContainer fromContainer, int fromIndex, int toIndex) - { - base.CopyValue(fromContainer, fromIndex, toIndex); - _values[toIndex] = ((UInt16DataContainer)fromContainer)._values[fromIndex]; - } - - internal override int CompareValues(int index1, int index2) - { - ushort s1 = _values[index1]; - ushort s2 = _values[index2]; - - if ( s1 == 0 || s2 == 0 ) { - int cn = CompareNulls(index1, index2); - if (cn != 0) - return cn; - } - - return s1 - s2; - } - - internal override long GetInt64(int index) - { - return Convert.ToInt64(_values[index]); - } - - #endregion //Methods - } - - sealed class UInt32DataContainer : AbstractDataContainer - { - #region Fields - - uint[] _values; - - #endregion //Fields - - #region Properties - - internal override object this[int index] { - get { - if (IsNull(index)) { - return DBNull.Value; - } - else { - return _values[index]; - } - } - set { - bool isDbNull = (value == DBNull.Value); - if (value == null || isDbNull) { - SetValue(index,0); - } - else if( value is uint ) { - SetValue(index,(uint)value); - } - else { - SetValue(index,Convert.ToUInt32(value)); - } - SetNull(index,value == null,isDbNull); - } - } - - internal override int Capacity { - set { - base.Capacity = value; - if (_values == null) { - _values = new uint[value]; - } - else { - uint[] tmp = new uint[value]; - Array.Copy(_values,0,tmp,0,_values.Length); - _values = tmp; - } - } - } - - #endregion //Properties - - #region Methods - - private void SetValue(int index, uint value) - { - _values[index] = value; - } - - internal override void SetItemFromDataRecord(int index, IDataRecord record, int field) - { - bool isDbNull = record.IsDBNull(field); - if (isDbNull) { - SetNull(index,false,isDbNull); - return; - } - - // if exception thrown, it should be caught in the caller method - if (record is ISafeDataRecord) { - SetValue(index,(uint)((ISafeDataRecord)record).GetInt32Safe(field)); - } - else { - this[index] = record.GetValue(field); - } - } - - internal override void CopyValue(int fromIndex, int toIndex) - { - base.CopyValue(fromIndex, toIndex); - _values[toIndex] = _values[fromIndex]; - } - - internal override void CopyValue(AbstractDataContainer fromContainer, int fromIndex, int toIndex) - { - base.CopyValue(fromContainer, fromIndex, toIndex); - _values[toIndex] = ((UInt32DataContainer)fromContainer)._values[fromIndex]; - } - - internal override int CompareValues(int index1, int index2) - { - uint i1 = _values[index1]; - uint i2 = _values[index2]; - - if ( i1 == 0 || i2 == 0 ) { - int cn = CompareNulls(index1, index2); - if (cn != 0) - return cn; - } - - if ( i1 <= i2 ) { - return ( i1 != i2 ) ? -1 : 0; - } - return 1; - } - - internal override long GetInt64(int index) - { - return Convert.ToInt64(_values[index]); - } - - #endregion //Methods - } - - sealed class UInt64DataContainer : AbstractDataContainer - { - #region Fields - - ulong[] _values; - - #endregion //Fields - - #region Properties - - internal override object this[int index] { - get { - if (IsNull(index)) { - return DBNull.Value; - } - else { - return _values[index]; - } - } - set { - bool isDbNull = (value == DBNull.Value); - if (value == null || isDbNull) { - SetValue(index,0); - } - else if( value is ulong ) { - SetValue(index,(ulong)value); - } - else { - SetValue(index,Convert.ToUInt64(value)); - } - SetNull(index,value == null,isDbNull); - } - } - - internal override int Capacity { - set { - base.Capacity = value; - if (_values == null) { - _values = new ulong[value]; - } - else { - ulong[] tmp = new ulong[value]; - Array.Copy(_values,0,tmp,0,_values.Length); - _values = tmp; - } - } - } - - #endregion //Properties - - #region Methods - - private void SetValue(int index, ulong value) - { - _values[index] = value; - } - - internal override void SetItemFromDataRecord(int index, IDataRecord record, int field) - { - bool isDbNull = record.IsDBNull(field); - if (isDbNull) { - SetNull(index,false,isDbNull); - return; - } - - // if exception thrown, it should be caught in the caller method - if (record is ISafeDataRecord) { - SetValue(index,(ulong)((ISafeDataRecord)record).GetInt64Safe(field)); - } - else { - this[index] = record.GetValue(field); - } - } - - internal override void CopyValue(int fromIndex, int toIndex) - { - base.CopyValue(fromIndex, toIndex); - _values[toIndex] = _values[fromIndex]; - } - - internal override void CopyValue(AbstractDataContainer fromContainer, int fromIndex, int toIndex) - { - base.CopyValue(fromContainer, fromIndex, toIndex); - _values[toIndex] = ((UInt64DataContainer)fromContainer)._values[fromIndex]; - } - - internal override int CompareValues(int index1, int index2) - { - ulong l1 = _values[index1]; - ulong l2 = _values[index2]; - - if ( l1 == 0 || l2 == 0 ) { - int cn = CompareNulls(index1, index2); - if (cn != 0) { - return cn; - } - } - - if ( l1 <= l2 ) { - return ( l1 != l2 ) ? -1 : 0; - } - return 1; - } - - internal override long GetInt64(int index) - { - return Convert.ToInt64(_values[index]); - } - - #endregion //Methods - } - - - sealed class SByteDataContainer : AbstractDataContainer - { - #region Fields - - sbyte[] _values; - - #endregion //Fields - - #region Properties - - internal override object this[int index] { - get { - if (IsNull(index)) { - return DBNull.Value; - } - else { - return _values[index]; - } - } - set { - bool isDbNull = (value == DBNull.Value); - if (value == null || isDbNull) { - SetValue(index,0); - } - else if( value is sbyte ) { - SetValue(index,(sbyte)value); - } - else { - SetValue(index,Convert.ToSByte(value)); - } - SetNull(index,value == null,isDbNull); - } - } - - internal override int Capacity { - set { - base.Capacity = value; - if (_values == null) { - _values = new sbyte[value]; - } - else { - sbyte[] tmp = new sbyte[value]; - Array.Copy(_values,0,tmp,0,_values.Length); - _values = tmp; - } - } - } - - #endregion //Properties - - #region Methods - - private void SetValue(int index, sbyte value) - { - _values[index] = value; - } - - internal override void SetItemFromDataRecord(int index, IDataRecord record, int field) - { - bool isDbNull = record.IsDBNull(field); - if (isDbNull) { - SetNull(index,false,isDbNull); - return; - } - - // if exception thrown, it should be caught in the caller method - if (record is ISafeDataRecord) { - SetValue(index,(sbyte)((ISafeDataRecord)record).GetByteSafe(field)); - } - else { - this[index] = record.GetValue(field); - } - } - - internal override void CopyValue(int fromIndex, int toIndex) - { - base.CopyValue(fromIndex, toIndex); - _values[toIndex] = _values[fromIndex]; - } - - internal override void CopyValue(AbstractDataContainer fromContainer, int fromIndex, int toIndex) - { - base.CopyValue(fromContainer, fromIndex, toIndex); - _values[toIndex] = ((SByteDataContainer)fromContainer)._values[fromIndex]; - } - - internal override int CompareValues(int index1, int index2) - { - sbyte b1 = _values[index1]; - sbyte b2 = _values[index2]; - - if ( b1 == 0 || b2 == 0 ) { - int cn = CompareNulls(index1, index2); - if (cn != 0) { - return cn; - } - } - - return b1 - b2; - } - - internal override long GetInt64(int index) - { - return Convert.ToSByte(_values[index]); - } - - #endregion //Methods - } - - } -} +// +// Copyright (C) 2008 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.Collections; +using System.Reflection; +#if !FULL_AOT_RUNTIME +using System.Reflection.Emit; +#endif + +namespace System.Data.Common +{ + internal abstract class DataContainer { + BitArray null_values; + System.Type _type; + DataColumn _column; + + // implementing class protocol + protected internal abstract object GetValue (int index); + internal abstract long GetInt64 (int index); + + // used to set the array value to something neutral when the corresponding item is null (in the database sense) + // note: we don't actually ever look at the value written there, but the GC may like us to avoid keeping stale + // values in the array. + protected abstract void ZeroOut (int index); + protected abstract void SetValue (int index, object value); + protected abstract void SetValueFromSafeDataRecord (int index, ISafeDataRecord record, int field); + + protected abstract void DoCopyValue (DataContainer from, int from_index, int to_index); + protected abstract int DoCompareValues (int index1, int index2); + + protected abstract void Resize (int length); + + internal object this [int index] { + get { return IsNull (index) ? DBNull.Value : GetValue (index); } + set { + if (value == null) { + // Table might not have a default values row to copy from + if (Column.Table.DefaultValuesRowIndex == -1) { + ZeroOut (index); + null_values [index] = true; + } else { + CopyValue (Column.Table.DefaultValuesRowIndex, index); + } + return; + } + + bool is_dbnull = value == DBNull.Value; + if (is_dbnull) + ZeroOut (index); + else + SetValue (index, value); + null_values [index] = is_dbnull; + } + } + + internal int Capacity { + get { return null_values != null ? null_values.Count : 0; } + set { + int old_capacity = Capacity; + if (value == old_capacity) + return; + if (null_values == null) + null_values = new BitArray (value); + else + null_values.Length = value; + Resize (value); + } + } + + internal Type Type { + get { return _type; } + } + + protected DataColumn Column { + get { return _column; } + } + + internal static DataContainer Create (Type type, DataColumn column) + { + DataContainer container; + switch (Type.GetTypeCode(type)) { + case TypeCode.Int16: + container = new Int16DataContainer (); + break; + case TypeCode.Int32: + container = new Int32DataContainer (); + break; + case TypeCode.Int64: + container = new Int64DataContainer (); + break; + case TypeCode.String: + container = new StringDataContainer (); + break; + case TypeCode.Boolean: + container = new BitDataContainer (); + break; + case TypeCode.Byte: + container = new ByteDataContainer (); + break; + case TypeCode.Char: + container = new CharDataContainer (); + break; + case TypeCode.Double: + container = new DoubleDataContainer (); + break; + case TypeCode.SByte: + container = new SByteDataContainer (); + break; + case TypeCode.Single: + container = new SingleDataContainer (); + break; + case TypeCode.UInt16: + container = new UInt16DataContainer (); + break; + case TypeCode.UInt32: + container = new UInt32DataContainer (); + break; + case TypeCode.UInt64: + container = new UInt64DataContainer (); + break; + case TypeCode.DateTime: + container = new DateTimeDataContainer (); + break; + case TypeCode.Decimal: + container = new DecimalDataContainer (); + break; + default: + container = new ObjectDataContainer (); + break; + } + container._type = type; + container._column = column; + return container; + } + + internal static object GetExplicitValue (object value) + { + Type valueType = value.GetType (); + MethodInfo method = valueType.GetMethod ("op_Explicit", new Type[]{valueType}); + if (method != null) + return (method.Invoke (value, new object[]{value})); + return null; + } + + internal object GetContainerData (object value) + { + object obj; + TypeCode tc; + + if (value == null) + return null; + + if (_type.IsInstanceOfType (value)) { + return value; + } else if ((tc = Type.GetTypeCode (_type)) == TypeCode.String) { + return (Convert.ToString (value)); + } else if (value is IConvertible) { + switch (tc) { + case TypeCode.Int16: + return (Convert.ToInt16 (value)); + case TypeCode.Int32: + return (Convert.ToInt32 (value)); + case TypeCode.Int64: + return (Convert.ToInt64 (value)); + case TypeCode.Boolean: + return (Convert.ToBoolean (value)); + case TypeCode.Byte: + return (Convert.ToByte (value)); + case TypeCode.Char: + return (Convert.ToChar (value)); + case TypeCode.Double: + return (Convert.ToDouble (value)); + case TypeCode.SByte: + return (Convert.ToSByte (value)); + case TypeCode.Single: + return (Convert.ToSingle (value)); + case TypeCode.UInt16: + return (Convert.ToUInt16 (value)); + case TypeCode.UInt32: + return (Convert.ToUInt32 (value)); + case TypeCode.UInt64: + return (Convert.ToUInt64 (value)); + case TypeCode.DateTime: + if (value == DBNull.Value) + return DBNull.Value; + return (Convert.ToDateTime (value)); + case TypeCode.Decimal: + return (Convert.ToDecimal (value)); + default: + throw new InvalidCastException (string.Format ("Cannot convert from {0} to {1}", value.GetType ().FullName, _type.FullName)); + } + } else if ((obj = GetExplicitValue (value)) != null) { + return (obj); + } else { + throw new InvalidCastException (); + } + } + + internal bool IsNull (int index) + { + return null_values == null || null_values [index]; + } + + internal void FillValues (int fromIndex) + { + for (int i = 0; i < Capacity; i++) + CopyValue (fromIndex, i); + } + + internal void CopyValue (int from_index, int to_index) + { + CopyValue (this, from_index, to_index); + } + + internal void CopyValue (DataContainer from, int from_index, int to_index) + { + DoCopyValue (from, from_index, to_index); + null_values [to_index] = from.null_values [from_index]; + } + + internal void SetItemFromDataRecord (int index, IDataRecord record, int field) + { + if (record.IsDBNull (field)) + this [index] = DBNull.Value; + else if (record is ISafeDataRecord) + SetValueFromSafeDataRecord (index, (ISafeDataRecord) record, field); + else + this [index] = record.GetValue (field); + } + + internal int CompareValues (int index1, int index2) + { + bool null1 = IsNull (index1); + bool null2 = IsNull (index2); + + if (null1 == null2) + return null1 ? 0 : DoCompareValues (index1, index2); + return null1 ? -1 : 1; + } + } + + sealed class BitDataContainer : DataContainer { + BitArray _values; + + protected internal override object GetValue (int index) + { + return _values [index]; + } + + protected override void ZeroOut (int index) + { + _values [index] = false; + } + + protected override void SetValue (int index, object value) + { + _values [index] = (bool) GetContainerData (value); + } + + protected override void SetValueFromSafeDataRecord (int index, ISafeDataRecord record, int field) + { + _values [index] = record.GetBooleanSafe (field); + } + + protected override void DoCopyValue (DataContainer from, int from_index, int to_index) + { + _values [to_index] = (bool) GetContainerData (from.GetValue (from_index)); + } + + protected override int DoCompareValues (int index1, int index2) + { + bool val1 = _values [index1]; + bool val2 = _values [index2]; + return val1 == val2 ? 0 : val1 ? 1 : -1; + } + + protected override void Resize (int size) + { + if (_values == null) + _values = new BitArray (size); + else + _values.Length = size; + } + + internal override long GetInt64 (int index) + { + return Convert.ToInt64 (_values [index]); + } + } + + sealed class CharDataContainer : DataContainer { + char [] _values; + + protected internal override object GetValue (int index) + { + return _values [index]; + } + + protected override void ZeroOut (int index) + { + _values [index] = '\0'; + } + + protected override void SetValue (int index, object value) + { + _values [index] = (char) GetContainerData (value); + } + + protected override void SetValueFromSafeDataRecord (int index, ISafeDataRecord record, int field) + { + _values [index] = record.GetCharSafe (field); + } + + protected override void DoCopyValue (DataContainer from, int from_index, int to_index) + { + _values [to_index] = (char) GetContainerData (from.GetValue (from_index)); + } + + protected override int DoCompareValues (int index1, int index2) + { + char val1 = _values [index1]; + char val2 = _values [index2]; + return val1 == val2 ? 0 : val1 < val2 ? -1 : 1; + } + + protected override void Resize (int size) + { + if (_values == null) { + _values = new char [size]; + return; + } + + char[] tmp = new char [size]; + Array.Copy (_values, 0, tmp, 0, _values.Length); + _values = tmp; + } + + internal override long GetInt64 (int index) + { + return Convert.ToInt64 (_values [index]); + } + } + + sealed class ByteDataContainer : DataContainer { + byte [] _values; + + protected internal override object GetValue (int index) + { + return _values [index]; + } + + protected override void ZeroOut (int index) + { + _values [index] = 0; + } + + protected override void SetValue (int index, object value) + { + _values [index] = (byte) GetContainerData (value); + } + + protected override void SetValueFromSafeDataRecord (int index, ISafeDataRecord record, int field) + { + _values [index] = record.GetByteSafe (field); + } + + protected override void DoCopyValue (DataContainer from, int from_index, int to_index) + { + _values [to_index] = (byte) GetContainerData (from.GetValue (from_index)); + } + + protected override int DoCompareValues (int index1, int index2) + { + int val1 = _values [index1]; + int val2 = _values [index2]; + return val1 - val2; + } + + protected override void Resize (int size) + { + if (_values == null) { + _values = new byte [size]; + return; + } + + byte[] tmp = new byte [size]; + Array.Copy (_values, 0, tmp, 0, _values.Length); + _values = tmp; + } + + internal override long GetInt64 (int index) + { + return _values [index]; + } + } + + sealed class SByteDataContainer : DataContainer { + sbyte [] _values; + + protected internal override object GetValue (int index) + { + return _values [index]; + } + + protected override void ZeroOut (int index) + { + _values [index] = 0; + } + + protected override void SetValue (int index, object value) + { + _values [index] = (sbyte) GetContainerData (value); + } + + protected override void SetValueFromSafeDataRecord (int index, ISafeDataRecord record, int field) + { + _values [index] = (sbyte) record.GetByteSafe (field); + } + + protected override void DoCopyValue (DataContainer from, int from_index, int to_index) + { + _values [to_index] = (sbyte) GetContainerData (from.GetValue (from_index)); + } + + protected override int DoCompareValues (int index1, int index2) + { + int val1 = _values [index1]; + int val2 = _values [index2]; + return val1 - val2; + } + + protected override void Resize (int size) + { + if (_values == null) { + _values = new sbyte [size]; + return; + } + + sbyte[] tmp = new sbyte [size]; + Array.Copy (_values, 0, tmp, 0, _values.Length); + _values = tmp; + } + + internal override long GetInt64 (int index) + { + return _values [index]; + } + } + + sealed class Int16DataContainer : DataContainer { + short [] _values; + + protected internal override object GetValue (int index) + { + return _values [index]; + } + + protected override void ZeroOut (int index) + { + _values [index] = 0; + } + + protected override void SetValue (int index, object value) + { + _values [index] = (short) GetContainerData (value); + } + + protected override void SetValueFromSafeDataRecord (int index, ISafeDataRecord record, int field) + { + _values [index] = record.GetInt16Safe (field); + } + + protected override void DoCopyValue (DataContainer from, int from_index, int to_index) + { + _values [to_index] = (short) GetContainerData (from.GetValue (from_index)); + } + + protected override int DoCompareValues (int index1, int index2) + { + int val1 = _values [index1]; + int val2 = _values [index2]; + return val1 - val2; + } + + protected override void Resize (int size) + { + if (_values == null) { + _values = new short [size]; + return; + } + + short[] tmp = new short [size]; + Array.Copy (_values, 0, tmp, 0, _values.Length); + _values = tmp; + } + + internal override long GetInt64 (int index) + { + return _values [index]; + } + } + + sealed class UInt16DataContainer : DataContainer { + ushort [] _values; + + protected internal override object GetValue (int index) + { + return _values [index]; + } + + protected override void ZeroOut (int index) + { + _values [index] = 0; + } + + protected override void SetValue (int index, object value) + { + _values [index] = (ushort) GetContainerData (value); + } + + protected override void SetValueFromSafeDataRecord (int index, ISafeDataRecord record, int field) + { + _values [index] = (ushort) record.GetInt16Safe (field); + } + + protected override void DoCopyValue (DataContainer from, int from_index, int to_index) + { + _values [to_index] = (ushort) GetContainerData (from.GetValue (from_index)); + } + + protected override int DoCompareValues (int index1, int index2) + { + int val1 = _values [index1]; + int val2 = _values [index2]; + return val1 - val2; + } + + protected override void Resize (int size) + { + if (_values == null) { + _values = new ushort [size]; + return; + } + + ushort[] tmp = new ushort [size]; + Array.Copy (_values, 0, tmp, 0, _values.Length); + _values = tmp; + } + + internal override long GetInt64 (int index) + { + return _values [index]; + } + } + + sealed class Int32DataContainer : DataContainer { + int [] _values; + + protected internal override object GetValue (int index) + { + return _values [index]; + } + + protected override void ZeroOut (int index) + { + _values [index] = 0; + } + + protected override void SetValue (int index, object value) + { + _values [index] = (int) GetContainerData (value); + } + + protected override void SetValueFromSafeDataRecord (int index, ISafeDataRecord record, int field) + { + _values [index] = record.GetInt32Safe (field); + } + + protected override void DoCopyValue (DataContainer from, int from_index, int to_index) + { + _values [to_index] = (int) GetContainerData (from.GetValue (from_index)); + } + + protected override int DoCompareValues (int index1, int index2) + { + int val1 = _values [index1]; + int val2 = _values [index2]; + return val1 == val2 ? 0 : val1 < val2 ? -1 : 1; + } + + protected override void Resize (int size) + { + if (_values == null) { + _values = new int [size]; + return; + } + + int[] tmp = new int [size]; + Array.Copy (_values, 0, tmp, 0, _values.Length); + _values = tmp; + } + + internal override long GetInt64 (int index) + { + return _values [index]; + } + } + + sealed class UInt32DataContainer : DataContainer { + uint [] _values; + + protected internal override object GetValue (int index) + { + return _values [index]; + } + + protected override void ZeroOut (int index) + { + _values [index] = 0; + } + + protected override void SetValue (int index, object value) + { + _values [index] = (uint) GetContainerData (value); + } + + protected override void SetValueFromSafeDataRecord (int index, ISafeDataRecord record, int field) + { + _values [index] = (uint) record.GetInt32Safe (field); + } + + protected override void DoCopyValue (DataContainer from, int from_index, int to_index) + { + _values [to_index] = (uint) GetContainerData (from.GetValue (from_index)); + } + + protected override int DoCompareValues (int index1, int index2) + { + uint val1 = _values [index1]; + uint val2 = _values [index2]; + return val1 == val2 ? 0 : val1 < val2 ? -1 : 1; + } + + protected override void Resize (int size) + { + if (_values == null) { + _values = new uint [size]; + return; + } + + uint[] tmp = new uint [size]; + Array.Copy (_values, 0, tmp, 0, _values.Length); + _values = tmp; + } + + internal override long GetInt64 (int index) + { + return _values [index]; + } + } + + sealed class Int64DataContainer : DataContainer { + long [] _values; + + protected internal override object GetValue (int index) + { + return _values [index]; + } + + protected override void ZeroOut (int index) + { + _values [index] = 0; + } + + protected override void SetValue (int index, object value) + { + _values [index] = (long) GetContainerData (value); + } + + protected override void SetValueFromSafeDataRecord (int index, ISafeDataRecord record, int field) + { + _values [index] = record.GetInt64Safe (field); + } + + protected override void DoCopyValue (DataContainer from, int from_index, int to_index) + { + _values [to_index] = (long) GetContainerData (from.GetValue (from_index)); + } + + protected override int DoCompareValues (int index1, int index2) + { + long val1 = _values [index1]; + long val2 = _values [index2]; + return val1 == val2 ? 0 : val1 < val2 ? -1 : 1; + } + + protected override void Resize (int size) + { + if (_values == null) { + _values = new long [size]; + return; + } + + long[] tmp = new long [size]; + Array.Copy (_values, 0, tmp, 0, _values.Length); + _values = tmp; + } + + internal override long GetInt64 (int index) + { + return _values [index]; + } + } + + sealed class UInt64DataContainer : DataContainer { + ulong [] _values; + + protected internal override object GetValue (int index) + { + return _values [index]; + } + + protected override void ZeroOut (int index) + { + _values [index] = 0; + } + + protected override void SetValue (int index, object value) + { + _values [index] = (ulong) GetContainerData (value); + } + + protected override void SetValueFromSafeDataRecord (int index, ISafeDataRecord record, int field) + { + _values [index] = (ulong) record.GetInt64Safe (field); + } + + protected override void DoCopyValue (DataContainer from, int from_index, int to_index) + { + _values [to_index] = (ulong) GetContainerData (from.GetValue (from_index)); + } + + protected override int DoCompareValues (int index1, int index2) + { + ulong val1 = _values [index1]; + ulong val2 = _values [index2]; + return val1 == val2 ? 0 : val1 < val2 ? -1 : 1; + } + + protected override void Resize (int size) + { + if (_values == null) { + _values = new ulong [size]; + return; + } + + ulong[] tmp = new ulong [size]; + Array.Copy (_values, 0, tmp, 0, _values.Length); + _values = tmp; + } + + internal override long GetInt64 (int index) + { + return Convert.ToInt64 (_values [index]); + } + } + + sealed class SingleDataContainer : DataContainer { + float [] _values; + + protected internal override object GetValue (int index) + { + return _values [index]; + } + + protected override void ZeroOut (int index) + { + _values [index] = 0; + } + + protected override void SetValue (int index, object value) + { + _values [index] = (float) GetContainerData (value); + } + + protected override void SetValueFromSafeDataRecord (int index, ISafeDataRecord record, int field) + { + _values [index] = record.GetFloatSafe (field); + } + + protected override void DoCopyValue (DataContainer from, int from_index, int to_index) + { + _values [to_index] = (float) GetContainerData (from.GetValue (from_index)); + } + + protected override int DoCompareValues (int index1, int index2) + { + float val1 = _values [index1]; + float val2 = _values [index2]; + return val1 == val2 ? 0 : val1 < val2 ? -1 : 1; + } + + protected override void Resize (int size) + { + if (_values == null) { + _values = new float [size]; + return; + } + + float[] tmp = new float [size]; + Array.Copy (_values, 0, tmp, 0, _values.Length); + _values = tmp; + } + + internal override long GetInt64 (int index) + { + return Convert.ToInt64 (_values [index]); + } + } + + sealed class DoubleDataContainer : DataContainer { + double [] _values; + + protected internal override object GetValue (int index) + { + return _values [index]; + } + + protected override void ZeroOut (int index) + { + _values [index] = 0; + } + + protected override void SetValue (int index, object value) + { + _values [index] = (double) GetContainerData (value); + } + + protected override void SetValueFromSafeDataRecord (int index, ISafeDataRecord record, int field) + { + _values [index] = record.GetDoubleSafe (field); + } + + protected override void DoCopyValue (DataContainer from, int from_index, int to_index) + { + _values [to_index] = (double) GetContainerData (from.GetValue (from_index)); + } + + protected override int DoCompareValues (int index1, int index2) + { + double val1 = _values [index1]; + double val2 = _values [index2]; + return val1 == val2 ? 0 : val1 < val2 ? -1 : 1; + } + + protected override void Resize (int size) + { + if (_values == null) { + _values = new double [size]; + return; + } + + double[] tmp = new double [size]; + Array.Copy (_values, 0, tmp, 0, _values.Length); + _values = tmp; + } + + internal override long GetInt64 (int index) + { + return Convert.ToInt64 (_values[index]); + } + } + + class ObjectDataContainer : DataContainer { + object [] _values; + + protected internal override object GetValue (int index) + { + return _values [index]; + } + + protected override void ZeroOut (int index) + { + _values [index] = null; + } + + protected override void SetValue (int index, object value) + { + _values [index] = value; + } + + protected override void SetValueFromSafeDataRecord (int index, ISafeDataRecord record, int field) + { + _values [index] = record.GetValue (field); + } + + protected override void DoCopyValue (DataContainer from, int from_index, int to_index) + { + _values [to_index] = GetContainerData (from.GetValue (from_index)); + } + + protected override int DoCompareValues (int index1, int index2) + { + object obj1 = _values [index1]; + object obj2 = _values [index2]; + + if (obj1 == obj2) + return 0; + + if (obj1 is IComparable) { + try { + return ((IComparable)obj1).CompareTo (obj2); + } catch { + if (obj2 is IComparable) { + obj2 = Convert.ChangeType (obj2, Type.GetTypeCode (obj1.GetType ())); + return ((IComparable)obj1).CompareTo (obj2); + } + } + } + + return String.Compare (obj1.ToString (), obj2.ToString ()); + } + + protected override void Resize (int size) + { + if (_values == null) { + _values = new object [size]; + return; + } + + object[] tmp = new object [size]; + Array.Copy (_values, 0, tmp, 0, _values.Length); + _values = tmp; + } + + internal override long GetInt64 (int index) + { + return Convert.ToInt64 (_values [index]); + } + } + + sealed class DateTimeDataContainer : ObjectDataContainer { + protected override void SetValueFromSafeDataRecord (int index, ISafeDataRecord record, int field) + { + base.SetValue (index, record.GetDateTimeSafe (field)); + } + + protected override void SetValue (int index, object value) + { + base.SetValue (index, GetContainerData (value)); + } + } + + sealed class DecimalDataContainer : ObjectDataContainer { + protected override void SetValueFromSafeDataRecord (int index, ISafeDataRecord record, int field) + { + base.SetValue (index, record.GetDecimalSafe (field)); + } + + protected override void SetValue (int index, object value) + { + base.SetValue (index, GetContainerData (value)); + } + } + + sealed class StringDataContainer : ObjectDataContainer { + private void SetValue (int index, string value) + { + if (value != null && Column.MaxLength >= 0 && Column.MaxLength < value.Length) + throw new ArgumentException ("Cannot set column '" + Column.ColumnName + "' to '" + value + "'. The value violates the MaxLength limit of this column."); + base.SetValue (index, value); + } + + protected override void SetValue (int index, object value) + { + SetValue (index, (string) GetContainerData (value)); + } + + protected override void SetValueFromSafeDataRecord (int index, ISafeDataRecord record, int field) + { + SetValue (index, record.GetStringSafe (field)); + } + + protected override int DoCompareValues (int index1, int index2) + { + DataTable table = Column.Table; + return String.Compare ((string) this [index1], (string) this [index2], !table.CaseSensitive, table.Locale); + } + } +}