// // 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 } } }