public static void CleanUpNativeData(ref IntPtr pNativeData)
        {
            if (pNativeData != IntPtr.Zero)
            {
                XSQLDA xsqlda = Marshal.PtrToStructure <XSQLDA>(pNativeData);

                Marshal.DestroyStructure <XSQLDA>(pNativeData);

                for (var i = 0; i < xsqlda.sqln; i++)
                {
                    IntPtr 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)
        {
            // Set up XSQLDA structure
            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++)
            {
                // Create a	new	XSQLVAR	structure and fill it
                xsqlvar[i] = new XSQLVAR
                {
                    sqltype    = descriptor[i].DataType,
                    sqlscale   = descriptor[i].NumericScale,
                    sqlsubtype = descriptor[i].SubType,
                    sqllen     = descriptor[i].Length
                };


                // Create a	new	pointer	for	the	xsqlvar	data
                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);
                }

                // Create a	new	pointer	for	the	sqlind value
                xsqlvar[i].sqlind = Marshal.AllocHGlobal(Marshal2.SizeOf <short>());
                Marshal.WriteInt16(xsqlvar[i].sqlind, descriptor[i].NullFlag);

                // Name
                xsqlvar[i].sqlname        = GetStringBuffer(charset, descriptor[i].Name);
                xsqlvar[i].sqlname_length = (short)descriptor[i].Name.Length;

                // Relation	Name
                xsqlvar[i].relname        = GetStringBuffer(charset, descriptor[i].Relation);
                xsqlvar[i].relname_length = (short)descriptor[i].Relation.Length;

                // Owner name
                xsqlvar[i].ownername        = GetStringBuffer(charset, descriptor[i].Owner);
                xsqlvar[i].ownername_length = (short)descriptor[i].Owner.Length;

                // Alias name
                xsqlvar[i].aliasname        = GetStringBuffer(charset, descriptor[i].Alias);
                xsqlvar[i].aliasname_length = (short)descriptor[i].Alias.Length;
            }

            return(MarshalManagedToNative(xsqlda, xsqlvar));
        }
        public static async ValueTask <IntPtr> MarshalManagedToNative(Charset charset, Descriptor descriptor, AsyncWrappingCommonArgs async)
        {
            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 = await descriptor[i].DbValue.GetBytes(async).ConfigureAwait(false);
                    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));
        }
示例#4
0
        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)
        {
            // Obtain XSQLDA information
            var xsqlda = Marshal2.PtrToStructure <XSQLDA>(pNativeData);

            // Create a	new	Descriptor
            var descriptor = new Descriptor(xsqlda.sqln)
            {
                ActualCount = xsqlda.sqld
            };

            // Obtain XSQLVAR members information
            var xsqlvar = new XSQLVAR();

            for (var i = 0; i < xsqlda.sqln; i++)
            {
                var ptr = GetIntPtr(pNativeData, ComputeLength(i));
                MarshalXSQLVARNativeToManaged(ptr, xsqlvar);

                // Map XSQLVAR information to Descriptor
                descriptor[i].DataType     = xsqlvar.sqltype;
                descriptor[i].NumericScale = xsqlvar.sqlscale;
                descriptor[i].SubType      = xsqlvar.sqlsubtype;
                descriptor[i].Length       = xsqlvar.sqllen;

                // Decode sqlind value
                descriptor[i].NullFlag = xsqlvar.sqlind == IntPtr.Zero
                                        ? (short)0
                                        : Marshal.ReadInt16(xsqlvar.sqlind);

                // Set value
                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);
        }
        public static void CleanUpNativeData(ref IntPtr pNativeData)
        {
            if (pNativeData != IntPtr.Zero)
            {
                // Obtain XSQLDA information
                XSQLDA xsqlda = Marshal2.PtrToStructure <XSQLDA>(pNativeData);

                // Destroy XSQLDA structure
                Marshal2.DestroyStructure <XSQLDA>(pNativeData);

                // Destroy XSQLVAR structures
                for (var i = 0; i < xsqlda.sqln; i++)
                {
                    IntPtr ptr = GetIntPtr(pNativeData, ComputeLength(i));

                    // Free	sqldata	and	sqlind pointers	if needed
                    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;
                    }

                    Marshal2.DestroyStructure <XSQLVAR>(ptr);
                }

                // Free	pointer	memory
                Marshal.FreeHGlobal(pNativeData);

                pNativeData = IntPtr.Zero;
            }
        }
 private static void MarshalXSQLVARNativeToManaged(IntPtr ptr, XSQLVAR xsqlvar, bool onlyPointers = false)
 {
     unsafe
     {
         using (BinaryReader 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;
             }
         }
     }
 }