public static void CleanUpNativeData(ref IntPtr pNativeData) { if (pNativeData != IntPtr.Zero) { var xsqlda = Marshal.PtrToStructure <XSQLDA>(pNativeData); Marshal.DestroyStructure <XSQLDA>(pNativeData); for (var i = 0; i < xsqlda.sqln; i++) { var ptr = GetIntPtr(pNativeData, ComputeLength(i)); var sqlvar = new XSQLVAR(); MarshalXSQLVARNativeToManaged(ptr, sqlvar, true); if (sqlvar.sqldata != IntPtr.Zero) { Marshal.FreeHGlobal(sqlvar.sqldata); sqlvar.sqldata = IntPtr.Zero; } if (sqlvar.sqlind != IntPtr.Zero) { Marshal.FreeHGlobal(sqlvar.sqlind); sqlvar.sqlind = IntPtr.Zero; } Marshal.DestroyStructure <XSQLVAR>(ptr); } Marshal.FreeHGlobal(pNativeData); pNativeData = IntPtr.Zero; } }
public static IntPtr MarshalManagedToNative(Charset charset, Descriptor descriptor) { var xsqlda = new XSQLDA { version = descriptor.Version, sqln = descriptor.Count, sqld = descriptor.ActualCount }; var xsqlvar = new XSQLVAR[descriptor.Count]; for (var i = 0; i < xsqlvar.Length; i++) { xsqlvar[i] = new XSQLVAR { sqltype = descriptor[i].DataType, sqlscale = descriptor[i].NumericScale, sqlsubtype = descriptor[i].SubType, sqllen = descriptor[i].Length }; if (descriptor[i].HasDataType() && descriptor[i].DbDataType != DbDataType.Null) { var buffer = descriptor[i].DbValue.GetBytes(); xsqlvar[i].sqldata = Marshal.AllocHGlobal(buffer.Length); Marshal.Copy(buffer, 0, xsqlvar[i].sqldata, buffer.Length); } else { xsqlvar[i].sqldata = Marshal.AllocHGlobal(0); } xsqlvar[i].sqlind = Marshal.AllocHGlobal(Marshal.SizeOf <short>()); Marshal.WriteInt16(xsqlvar[i].sqlind, descriptor[i].NullFlag); xsqlvar[i].sqlname = GetStringBuffer(charset, descriptor[i].Name); xsqlvar[i].sqlname_length = (short)descriptor[i].Name.Length; xsqlvar[i].relname = GetStringBuffer(charset, descriptor[i].Relation); xsqlvar[i].relname_length = (short)descriptor[i].Relation.Length; xsqlvar[i].ownername = GetStringBuffer(charset, descriptor[i].Owner); xsqlvar[i].ownername_length = (short)descriptor[i].Owner.Length; xsqlvar[i].aliasname = GetStringBuffer(charset, descriptor[i].Alias); xsqlvar[i].aliasname_length = (short)descriptor[i].Alias.Length; } return(MarshalManagedToNative(xsqlda, xsqlvar)); }
private static byte[] GetBytes(XSQLVAR xsqlvar) { if (xsqlvar.sqllen == 0 || xsqlvar.sqldata == IntPtr.Zero) { return(null); } var type = xsqlvar.sqltype & ~1; switch (type) { case IscCodes.SQL_VARYING: { var buffer = new byte[Marshal.ReadInt16(xsqlvar.sqldata)]; var tmp = GetIntPtr(xsqlvar.sqldata, 2); Marshal.Copy(tmp, buffer, 0, buffer.Length); return(buffer); } case IscCodes.SQL_TEXT: case IscCodes.SQL_SHORT: case IscCodes.SQL_LONG: case IscCodes.SQL_FLOAT: case IscCodes.SQL_DOUBLE: case IscCodes.SQL_D_FLOAT: case IscCodes.SQL_QUAD: case IscCodes.SQL_INT64: case IscCodes.SQL_BLOB: case IscCodes.SQL_ARRAY: case IscCodes.SQL_TIMESTAMP: case IscCodes.SQL_TYPE_TIME: case IscCodes.SQL_TYPE_DATE: case IscCodes.SQL_BOOLEAN: case IscCodes.SQL_TIMESTAMP_TZ: case IscCodes.SQL_TIMESTAMP_TZ_EX: case IscCodes.SQL_TIME_TZ: case IscCodes.SQL_TIME_TZ_EX: case IscCodes.SQL_DEC16: case IscCodes.SQL_DEC34: case IscCodes.SQL_INT128: { var buffer = new byte[xsqlvar.sqllen]; Marshal.Copy(xsqlvar.sqldata, buffer, 0, buffer.Length); return(buffer); } default: throw TypeHelper.InvalidDataType(type); } }
public static Descriptor MarshalNativeToManaged(Charset charset, IntPtr pNativeData, bool fetching) { var xsqlda = Marshal.PtrToStructure <XSQLDA>(pNativeData); var descriptor = new Descriptor(xsqlda.sqln) { ActualCount = xsqlda.sqld }; var xsqlvar = new XSQLVAR(); for (var i = 0; i < xsqlda.sqln; i++) { var ptr = GetIntPtr(pNativeData, ComputeLength(i)); MarshalXSQLVARNativeToManaged(ptr, xsqlvar); descriptor[i].DataType = xsqlvar.sqltype; descriptor[i].NumericScale = xsqlvar.sqlscale; descriptor[i].SubType = xsqlvar.sqlsubtype; descriptor[i].Length = xsqlvar.sqllen; descriptor[i].NullFlag = xsqlvar.sqlind == IntPtr.Zero ? (short)0 : Marshal.ReadInt16(xsqlvar.sqlind); if (fetching) { if (descriptor[i].NullFlag != -1) { descriptor[i].SetValue(GetBytes(xsqlvar)); } } descriptor[i].Name = GetString(charset, xsqlvar.sqlname, xsqlvar.sqlname_length); descriptor[i].Relation = GetString(charset, xsqlvar.relname, xsqlvar.relname_length); descriptor[i].Owner = GetString(charset, xsqlvar.ownername, xsqlvar.ownername_length); descriptor[i].Alias = GetString(charset, xsqlvar.aliasname, xsqlvar.aliasname_length); } return(descriptor); }
private static void MarshalXSQLVARNativeToManaged(IntPtr ptr, XSQLVAR xsqlvar, bool onlyPointers = false) { unsafe { using (var reader = new BinaryReader(new UnmanagedMemoryStream((byte *)ptr.ToPointer(), SizeOfXSQLVAR))) { if (!onlyPointers) { xsqlvar.sqltype = reader.ReadInt16(); } else { reader.BaseStream.Position += sizeof(short); } if (!onlyPointers) { xsqlvar.sqlscale = reader.ReadInt16(); } else { reader.BaseStream.Position += sizeof(short); } if (!onlyPointers) { xsqlvar.sqlsubtype = reader.ReadInt16(); } else { reader.BaseStream.Position += sizeof(short); } if (!onlyPointers) { xsqlvar.sqllen = reader.ReadInt16(); } else { reader.BaseStream.Position += sizeof(short); } xsqlvar.sqldata = reader.ReadIntPtr(); xsqlvar.sqlind = reader.ReadIntPtr(); if (!onlyPointers) { xsqlvar.sqlname_length = reader.ReadInt16(); } else { reader.BaseStream.Position += sizeof(short); } if (!onlyPointers) { xsqlvar.sqlname = reader.ReadBytes(32); } else { reader.BaseStream.Position += 32; } if (!onlyPointers) { xsqlvar.relname_length = reader.ReadInt16(); } else { reader.BaseStream.Position += sizeof(short); } if (!onlyPointers) { xsqlvar.relname = reader.ReadBytes(32); } else { reader.BaseStream.Position += 32; } if (!onlyPointers) { xsqlvar.ownername_length = reader.ReadInt16(); } else { reader.BaseStream.Position += sizeof(short); } if (!onlyPointers) { xsqlvar.ownername = reader.ReadBytes(32); } else { reader.BaseStream.Position += 32; } if (!onlyPointers) { xsqlvar.aliasname_length = reader.ReadInt16(); } else { reader.BaseStream.Position += sizeof(short); } if (!onlyPointers) { xsqlvar.aliasname = reader.ReadBytes(32); } else { reader.BaseStream.Position += 32; } } } }