+
+ private int GetNativeSize ()
+ {
+ TextInfo ti = CultureInfo.InvariantCulture.TextInfo;
+ Encoding enc = Encoding.GetEncoding (ti.ANSICodePage);
+
+ switch (_typeMap.OdbcType) {
+ case OdbcType.Binary:
+ if (Value.GetType ().IsArray &&
+ Value.GetType ().GetElementType () == typeof (byte))
+ return ( (Array) Value).Length;
+ else
+ return Value.ToString ().Length;
+ case OdbcType.Bit:
+ return Marshal.SizeOf (typeof (byte));
+ case OdbcType.Double:
+ return Marshal.SizeOf (typeof (double));
+ case OdbcType.Real:
+ return Marshal.SizeOf (typeof (float));
+ case OdbcType.Int:
+ return Marshal.SizeOf (typeof (int));
+ case OdbcType.BigInt:
+ return Marshal.SizeOf (typeof (long));
+ case OdbcType.Decimal:
+ case OdbcType.Numeric:
+ return 19;
+ case OdbcType.SmallInt:
+ return Marshal.SizeOf (typeof (Int16));
+ case OdbcType.TinyInt:
+ return Marshal.SizeOf (typeof (byte));
+ case OdbcType.Char:
+ case OdbcType.Text:
+ case OdbcType.VarChar:
+ return enc.GetByteCount (Convert.ToString (Value)) + 1;
+ case OdbcType.NChar:
+ case OdbcType.NText:
+ case OdbcType.NVarChar:
+ // FIXME: Change to unicode
+ return enc.GetByteCount (Convert.ToString (Value)) + 1;
+ case OdbcType.VarBinary:
+ case OdbcType.Image:
+ if (Value.GetType ().IsArray &&
+ Value.GetType ().GetElementType () == typeof (byte))
+ return ( (Array) Value).Length;
+ throw new ArgumentException ("Unsupported Native Type!");
+ case OdbcType.Date:
+ case OdbcType.DateTime:
+ case OdbcType.SmallDateTime:
+ case OdbcType.Time:
+ case OdbcType.Timestamp:
+ return 18;
+ case OdbcType.UniqueIdentifier:
+ return Marshal.SizeOf (typeof (Guid));
+ }
+
+ if (Value.GetType ().IsArray &&
+ Value.GetType ().GetElementType () == typeof (byte))
+ return ( (Array) Value).Length;
+
+ return Value.ToString ().Length;
+ }
+
+ private void AllocateBuffer ()
+ {
+ int size = GetNativeSize ();
+
+ if (_nativeBuffer.Size == size)
+ return;
+
+ _nativeBuffer.AllocBuffer (size);
+ }
+
+ internal void CopyValue ()
+ {
+ if (_nativeBuffer.Handle == IntPtr.Zero)
+ return;
+
+ DateTime dt;
+ TextInfo ti = CultureInfo.InvariantCulture.TextInfo;
+ Encoding enc = Encoding.GetEncoding (ti.ANSICodePage);
+ byte [] nativeBytes, buffer;
+
+ switch (_typeMap.OdbcType) {
+ case OdbcType.Binary:
+ throw new NotImplementedException ();
+ case OdbcType.Bit:
+ Marshal.WriteByte (_nativeBuffer, Convert.ToByte (Value));
+ return;
+ case OdbcType.Double:
+ Marshal.StructureToPtr (Convert.ToDouble (Value), _nativeBuffer, false);
+ return;
+ case OdbcType.Real:
+ Marshal.StructureToPtr (Convert.ToSingle (Value), _nativeBuffer, false);
+ return;
+ case OdbcType.Int:
+ Marshal.WriteInt32 (_nativeBuffer, Convert.ToInt32 (Value));
+ return;
+ case OdbcType.BigInt:
+ Marshal.WriteInt64 (_nativeBuffer, Convert.ToInt64 (Value));
+ return;
+ case OdbcType.Decimal:
+ case OdbcType.Numeric:
+ // for numeric, the buffer is a packed decimal struct.
+ // ref http://www.it-faq.pl/mskb/181/254.HTM
+ int [] bits = Decimal.GetBits (Convert.ToDecimal (Value));
+ buffer = new byte [19]; // ref sqltypes.h
+ buffer [0] = Precision;
+ buffer [1] = (byte) ((bits [3] & 0x00FF0000) >> 16); // scale
+ buffer [2] = (byte) ((bits [3] & 0x80000000) > 0 ? 2 : 1); //sign
+ Buffer.BlockCopy (bits, 0, buffer, 3, 12); // copy data
+ for (int j = 16; j < 19; j++) // pad with 0
+ buffer [j] = 0;
+ Marshal.Copy (buffer, 0, _nativeBuffer, 19);
+ return;
+ case OdbcType.SmallInt:
+ Marshal.WriteInt16 (_nativeBuffer, Convert.ToInt16 (Value));
+ return;
+ case OdbcType.TinyInt:
+ Marshal.WriteByte (_nativeBuffer, Convert.ToByte (Value));
+ return;
+ case OdbcType.Char:
+ case OdbcType.Text:
+ case OdbcType.VarChar:
+ buffer = new byte [GetNativeSize ()];
+ nativeBytes = enc.GetBytes (Convert.ToString (Value));
+ Array.Copy (nativeBytes, 0, buffer, 0, nativeBytes.Length);
+ buffer [buffer.Length-1] = (byte) 0;
+ Marshal.Copy (buffer, 0, _nativeBuffer, buffer.Length);
+ Marshal.WriteInt32 (_cbLengthInd, -3);
+ return;
+ case OdbcType.NChar:
+ case OdbcType.NText:
+ case OdbcType.NVarChar:
+ // FIXME : change to unicode
+ buffer = new byte [GetNativeSize ()];
+ nativeBytes = enc.GetBytes (Convert.ToString (Value));
+ Array.Copy (nativeBytes, 0, buffer, 0, nativeBytes.Length);
+ buffer [buffer.Length-1] = (byte) 0;
+ Marshal.Copy (buffer, 0, _nativeBuffer, buffer.Length);
+ Marshal.WriteInt32 (_cbLengthInd, -3);
+ return;
+ case OdbcType.VarBinary:
+ case OdbcType.Image:
+ if (Value.GetType ().IsArray &&
+ Value.GetType ().GetElementType () == typeof (byte)) {
+ Marshal.Copy ( (byte []) Value, 0, _nativeBuffer, ((byte []) Value).Length);
+ }else
+ throw new ArgumentException ("Unsupported Native Type!");
+ return;
+ case OdbcType.Date:
+ dt = (DateTime) Value;
+ Marshal.WriteInt16 (_nativeBuffer, 0, (short) dt.Year);
+ Marshal.WriteInt16 (_nativeBuffer, 2, (short) dt.Month);
+ Marshal.WriteInt16 (_nativeBuffer, 4, (short) dt.Day);
+ return;
+ case OdbcType.Time:
+ dt = (DateTime) Value;
+ Marshal.WriteInt16 (_nativeBuffer, 0, (short) dt.Hour);
+ Marshal.WriteInt16 (_nativeBuffer, 2, (short) dt.Minute);
+ Marshal.WriteInt16 (_nativeBuffer, 4, (short) dt.Second);
+ return;
+ case OdbcType.SmallDateTime:
+ case OdbcType.Timestamp:
+ case OdbcType.DateTime:
+ dt = (DateTime) Value;
+ Marshal.WriteInt16 (_nativeBuffer, 0, (short) dt.Year);
+ Marshal.WriteInt16 (_nativeBuffer, 2, (short) dt.Month);
+ Marshal.WriteInt16 (_nativeBuffer, 4, (short) dt.Day);
+ Marshal.WriteInt16 (_nativeBuffer, 6, (short) dt.Hour);
+ Marshal.WriteInt16 (_nativeBuffer, 8, (short) dt.Minute);
+ Marshal.WriteInt16 (_nativeBuffer, 10, (short) dt.Second);
+ Marshal.WriteInt32 (_nativeBuffer, 12, (int) (dt.Ticks % 10000000) * 100);
+ return;
+ case OdbcType.UniqueIdentifier:
+ throw new NotImplementedException ();
+ }
+
+ if (Value.GetType ().IsArray &&
+ Value.GetType ().GetElementType () == typeof (byte)) {
+ Marshal.Copy ( (byte []) Value, 0, _nativeBuffer, ((byte []) Value).Length);
+ }else
+ throw new ArgumentException ("Unsupported Native Type!");
+ }
+
+#if NET_2_0
+ public override bool SourceColumnNullMapping {
+ get {return false;}
+ set {}
+ }
+
+ public override void ResetDbType ()
+ {
+ throw new NotImplementedException ();
+ }
+#endif
+