Ejemplo n.º 1
0
        /// <summary>
        /// Creates a variable list of arguments in unmanaged memory.
        /// </summary>
        /// <param name="args">The list of arguments.</param>
        public va_list(params object[] args)
        {
            va_args = new va_arg[args.Length];

            for (int j = 0; j < args.Length; j++)
            {
                string name = args[j].GetType().Name;
                if (name == "ptr`1")
                {
                    name = name.Replace("`1", "<" + args[j].GetType().GetGenericArguments()[0].Name + ">");
                }

                va_args[j].arg_offset  = args_size;
                va_args[j].data_offset = data_size;

                switch (name)
                {
                case "Char":
                    args_size       += 1;
                    va_args[j].write = (i) => Marshal.WriteByte(arguments, va_args[i].arg_offset, System.Text.Encoding.ASCII.GetBytes(new Char[] { (Char)args[i] })[0]);
                    break;

                case "Byte":
                case "SByte":
                    args_size       += 1;
                    va_args[j].write = (i) => Marshal.WriteByte(arguments, va_args[i].arg_offset, (Byte)args[i]);
                    break;

                case "Int16":
                case "UInt16":
                    args_size       += 2;
                    va_args[j].write = (i) => Marshal.WriteInt16(arguments, va_args[i].arg_offset, (Int16)args[i]);
                    break;

                case "Int32":
                case "UInt32":
                    args_size       += 4;
                    va_args[j].write = (i) => Marshal.WriteInt32(arguments, va_args[i].arg_offset, (Int32)args[i]);
                    break;

                case "Single":
                    args_size       += 8;
                    va_args[j].write = (i) => Marshal.Copy(BitConverter.GetBytes((Double)(Single)args[i]), 0, (IntPtr)(arguments.ToInt64() + va_args[i].arg_offset), 8);
                    break;

                case "mp_bitcnt_t":
                    args_size       += 4;
                    va_args[j].write = (i) => Marshal.WriteInt32(arguments, va_args[i].arg_offset, (Int32)(mp_bitcnt_t)args[i]);
                    break;

                case "mp_size_t":
                    args_size       += 4;
                    va_args[j].write = (i) => Marshal.WriteInt32(arguments, va_args[i].arg_offset, (Int32)(mp_size_t)args[i]);
                    break;

                case "mp_exp_t":
                    args_size       += 4;
                    va_args[j].write = (i) => Marshal.WriteInt32(arguments, va_args[i].arg_offset, (Int32)(mp_exp_t)args[i]);
                    break;

                case "Int64":
                case "UInt64":
                    args_size       += 8;
                    va_args[j].write = (i) => Marshal.WriteInt64(arguments, va_args[i].arg_offset, (Int64)args[i]);
                    break;

                case "Double":
                    args_size       += 8;
                    va_args[j].write = (i) => Marshal.Copy(BitConverter.GetBytes((Double)args[i]), 0, (IntPtr)(arguments.ToInt64() + va_args[i].arg_offset), 8);
                    break;

                case "IntPtr":
                case "UIntPtr":
                    args_size       += IntPtr.Size;
                    va_args[j].write = (i) => Marshal.WriteIntPtr(arguments, va_args[i].arg_offset, (IntPtr)args[i]);
                    break;

                case "mpz_t":
                    args_size       += IntPtr.Size;
                    va_args[j].write = (i) => Marshal.WriteIntPtr(arguments, va_args[i].arg_offset, ((mpz_t)args[i]).ToIntPtr());
                    break;

                case "mpq_t":
                    args_size       += IntPtr.Size;
                    va_args[j].write = (i) => Marshal.WriteIntPtr(arguments, va_args[i].arg_offset, ((mpq_t)args[i]).ToIntPtr());
                    break;

                case "mpf_t":
                    args_size       += IntPtr.Size;
                    va_args[j].write = (i) => Marshal.WriteIntPtr(arguments, va_args[i].arg_offset, ((mpf_t)args[i]).ToIntPtr());
                    break;

                case "mp_ptr":
                    args_size       += IntPtr.Size;
                    va_args[j].write = (i) => Marshal.WriteIntPtr(arguments, va_args[i].arg_offset, ((mp_ptr)args[i]).ToIntPtr());
                    break;

                case "mp_limb_t":
                    args_size       += IntPtr.Size;
                    va_args[j].write = (i) =>
                    {
                        if (IntPtr.Size == 4)
                        {
                            Marshal.WriteInt32(arguments, va_args[i].arg_offset, (Int32)(mp_limb_t)args[i]);
                        }
                        else
                        {
                            Marshal.WriteInt64(arguments, va_args[i].arg_offset, (Int64)(mp_limb_t)args[i]);
                        }
                    };
                    break;

                case "char_ptr":
                    args_size       += IntPtr.Size;
                    va_args[j].write = (i) => Marshal.WriteIntPtr(arguments, va_args[i].arg_offset, ((char_ptr)args[i]).ToIntPtr());
                    break;

                case "size_t":
                    args_size       += IntPtr.Size;
                    va_args[j].write = (i) =>
                    {
                        if (IntPtr.Size == 4)
                        {
                            Marshal.WriteInt32(arguments, va_args[i].arg_offset, (Int32)(size_t)args[i]);
                        }
                        else
                        {
                            Marshal.WriteInt64(arguments, va_args[i].arg_offset, (Int64)(size_t)args[i]);
                        }
                    };
                    break;

                case "String":
                    args_size       += IntPtr.Size;
                    data_size       += ((string)args[j]).Length + 1;
                    va_args[j].write = (i) =>
                    {
                        IntPtr data_ptr = (IntPtr)(arguments.ToInt64() + args_size + va_args[i].data_offset);
                        Marshal.WriteIntPtr(arguments, va_args[i].arg_offset, data_ptr);
                        string data = (string)args[i];
                        Marshal.Copy(Encoding.ASCII.GetBytes(data), 0, data_ptr, data.Length);
                        data_ptr = (IntPtr)((Int64)data_ptr + data.Length);
                        Marshal.Copy(new Byte[] { 0 }, 0, data_ptr, 1);
                    };
                    break;

                case "StringBuilder":
                    args_size       += IntPtr.Size;
                    data_size       += ((StringBuilder)args[j]).Capacity + 1;
                    va_args[j].write = (i) =>
                    {
                        IntPtr data_ptr = (IntPtr)(arguments.ToInt64() + args_size + va_args[i].data_offset);
                        Marshal.WriteIntPtr(arguments, va_args[i].arg_offset, data_ptr);
                        StringBuilder data = (StringBuilder)args[i];
                        Marshal.Copy(Encoding.ASCII.GetBytes(data.ToString()), 0, data_ptr, data.Length);
                        Marshal.Copy(new Byte[] { 0 }, 0, (IntPtr)((Int64)data_ptr + data.Length), 1);
                        data_ptr = (IntPtr)((Int64)data_ptr + data.Capacity + 1);
                    };
                    va_args[j].read = (i) =>
                    {
                        StringBuilder data     = (StringBuilder)args[i];
                        IntPtr        data_ptr = (IntPtr)(arguments.ToInt64() + args_size + va_args[i].data_offset);
                        data.Remove(0, data.Length);
                        data.Append(Marshal.PtrToStringAnsi(data_ptr));
                    };
                    readables.Push(j);
                    break;

                case "ptr<Char>":
                    args_size       += IntPtr.Size;
                    data_size       += 1;
                    va_args[j].write = (i) =>
                    {
                        IntPtr data_ptr = (IntPtr)(arguments.ToInt64() + args_size + va_args[i].data_offset);
                        Marshal.WriteIntPtr(arguments, va_args[i].arg_offset, data_ptr);
                        Char data = ((ptr <Char>)args[i]).Value;
                        Marshal.WriteByte(data_ptr, 0, Encoding.ASCII.GetBytes(new Char[] { data })[0]);
                    };
                    va_args[j].read = (i) =>
                    {
                        ptr <Char> data     = (ptr <Char>)args[i];
                        IntPtr     data_ptr = (IntPtr)(arguments.ToInt64() + args_size + va_args[i].data_offset);
                        data.Value = Encoding.ASCII.GetChars(new byte[] { Marshal.ReadByte(data_ptr) })[0];
                    };
                    readables.Push(j);
                    break;

                case "ptr<Byte>":
                    args_size       += IntPtr.Size;
                    data_size       += 1;
                    va_args[j].write = (i) =>
                    {
                        IntPtr data_ptr = (IntPtr)(arguments.ToInt64() + args_size + va_args[i].data_offset);
                        Marshal.WriteIntPtr(arguments, va_args[i].arg_offset, data_ptr);
                        Byte data = ((ptr <Byte>)args[i]).Value;
                        Marshal.WriteByte(data_ptr, 0, data);
                    };
                    va_args[j].read = (i) =>
                    {
                        ptr <Byte> data     = (ptr <Byte>)args[i];
                        IntPtr     data_ptr = (IntPtr)(arguments.ToInt64() + args_size + va_args[i].data_offset);
                        data.Value = (Byte)Marshal.ReadByte(data_ptr);
                    };
                    readables.Push(j);
                    break;

                case "ptr<SByte>":
                    args_size       += IntPtr.Size;
                    data_size       += 1;
                    va_args[j].write = (i) =>
                    {
                        IntPtr data_ptr = (IntPtr)(arguments.ToInt64() + args_size + va_args[i].data_offset);
                        Marshal.WriteIntPtr(arguments, va_args[i].arg_offset, data_ptr);
                        SByte data = ((ptr <SByte>)args[i]).Value;
                        Marshal.WriteByte(data_ptr, 0, (Byte)data);
                    };
                    va_args[j].read = (i) =>
                    {
                        ptr <SByte> data     = (ptr <SByte>)args[i];
                        IntPtr      data_ptr = (IntPtr)(arguments.ToInt64() + args_size + va_args[i].data_offset);
                        data.Value = (SByte)Marshal.ReadByte(data_ptr);
                    };
                    readables.Push(j);
                    break;

                case "ptr<Int16>":
                    args_size       += IntPtr.Size;
                    data_size       += 2;
                    va_args[j].write = (i) =>
                    {
                        IntPtr data_ptr = (IntPtr)(arguments.ToInt64() + args_size + va_args[i].data_offset);
                        Marshal.WriteIntPtr(arguments, va_args[i].arg_offset, data_ptr);
                        Int16 data = ((ptr <Int16>)args[i]).Value;
                        Marshal.WriteInt16(data_ptr, 0, data);
                    };
                    va_args[j].read = (i) =>
                    {
                        ptr <Int16> data     = (ptr <Int16>)args[i];
                        IntPtr      data_ptr = (IntPtr)(arguments.ToInt64() + args_size + va_args[i].data_offset);
                        data.Value = (Int16)Marshal.ReadInt16(data_ptr);
                    };
                    readables.Push(j);
                    break;

                case "ptr<UInt16>":
                    args_size       += IntPtr.Size;
                    data_size       += 2;
                    va_args[j].write = (i) =>
                    {
                        IntPtr data_ptr = (IntPtr)(arguments.ToInt64() + args_size + va_args[i].data_offset);
                        Marshal.WriteIntPtr(arguments, va_args[i].arg_offset, data_ptr);
                        UInt16 data = ((ptr <UInt16>)args[i]).Value;
                        Marshal.WriteInt16(data_ptr, 0, (Int16)data);
                    };
                    va_args[j].read = (i) =>
                    {
                        ptr <UInt16> data     = (ptr <UInt16>)args[i];
                        IntPtr       data_ptr = (IntPtr)(arguments.ToInt64() + args_size + va_args[i].data_offset);
                        data.Value = (UInt16)Marshal.ReadInt16(data_ptr);
                    };
                    readables.Push(j);
                    break;

                case "ptr<Int32>":
                    args_size       += IntPtr.Size;
                    data_size       += 4;
                    va_args[j].write = (i) =>
                    {
                        IntPtr data_ptr = (IntPtr)(arguments.ToInt64() + args_size + va_args[i].data_offset);
                        Marshal.WriteIntPtr(arguments, va_args[i].arg_offset, data_ptr);
                        Int32 data = ((ptr <Int32>)args[i]).Value;
                        Marshal.WriteInt32(data_ptr, 0, data);
                    };
                    va_args[j].read = (i) =>
                    {
                        ptr <Int32> data     = (ptr <Int32>)args[i];
                        IntPtr      data_ptr = (IntPtr)(arguments.ToInt64() + args_size + va_args[i].data_offset);
                        data.Value = (Int32)Marshal.ReadInt32(data_ptr);
                    };
                    readables.Push(j);
                    break;

                case "ptr<UInt32>":
                    args_size       += IntPtr.Size;
                    data_size       += 4;
                    va_args[j].write = (i) =>
                    {
                        IntPtr data_ptr = (IntPtr)(arguments.ToInt64() + args_size + va_args[i].data_offset);
                        Marshal.WriteIntPtr(arguments, va_args[i].arg_offset, data_ptr);
                        UInt32 data = ((ptr <UInt32>)args[i]).Value;
                        Marshal.WriteInt32(data_ptr, 0, (Int32)data);
                    };
                    va_args[j].read = (i) =>
                    {
                        ptr <UInt32> data     = (ptr <UInt32>)args[i];
                        IntPtr       data_ptr = (IntPtr)(arguments.ToInt64() + args_size + va_args[i].data_offset);
                        data.Value = (UInt32)Marshal.ReadInt32(data_ptr);
                    };
                    readables.Push(j);
                    break;

                case "ptr<Single>":
                    args_size       += IntPtr.Size;
                    data_size       += 4;
                    va_args[j].write = (i) =>
                    {
                        IntPtr data_ptr = (IntPtr)(arguments.ToInt64() + args_size + va_args[i].data_offset);
                        Marshal.WriteIntPtr(arguments, va_args[i].arg_offset, data_ptr);
                        Single data = ((ptr <Single>)args[i]).Value;
                        Marshal.Copy(BitConverter.GetBytes((Single)data), 0, data_ptr, 4);
                    };
                    va_args[j].read = (i) =>
                    {
                        ptr <Single> data     = (ptr <Single>)args[i];
                        IntPtr       data_ptr = (IntPtr)(arguments.ToInt64() + args_size + va_args[i].data_offset);
                        Byte[]       bytes    = new Byte[4];
                        Marshal.Copy(data_ptr, bytes, 0, 4);
                        data.Value = BitConverter.ToSingle(bytes, 0);
                    };
                    readables.Push(j);
                    break;

                case "ptr<mp_bitcnt_t>":
                    args_size       += IntPtr.Size;
                    data_size       += 4;
                    va_args[j].write = (i) =>
                    {
                        IntPtr data_ptr = (IntPtr)(arguments.ToInt64() + args_size + va_args[i].data_offset);
                        Marshal.WriteIntPtr(arguments, va_args[i].arg_offset, data_ptr);
                        mp_bitcnt_t data = ((ptr <mp_bitcnt_t>)args[i]).Value;
                        Marshal.WriteInt32(data_ptr, 0, (Int32)data.Value);
                    };
                    va_args[j].read = (i) =>
                    {
                        ptr <mp_bitcnt_t> data     = (ptr <mp_bitcnt_t>)args[i];
                        IntPtr            data_ptr = (IntPtr)(arguments.ToInt64() + args_size + va_args[i].data_offset);
                        data.Value.Value = (uint)Marshal.ReadInt32(data_ptr);
                    };
                    readables.Push(j);
                    break;

                case "ptr<mp_size_t>":
                    args_size       += IntPtr.Size;
                    data_size       += 4;
                    va_args[j].write = (i) =>
                    {
                        IntPtr data_ptr = (IntPtr)(arguments.ToInt64() + args_size + va_args[i].data_offset);
                        Marshal.WriteIntPtr(arguments, va_args[i].arg_offset, data_ptr);
                        mp_size_t data = ((ptr <mp_size_t>)args[i]).Value;
                        Marshal.WriteInt32(data_ptr, 0, data.Value);
                    };
                    va_args[j].read = (i) =>
                    {
                        ptr <mp_size_t> data     = (ptr <mp_size_t>)args[i];
                        IntPtr          data_ptr = (IntPtr)(arguments.ToInt64() + args_size + va_args[i].data_offset);
                        data.Value.Value = Marshal.ReadInt32(data_ptr);
                    };
                    readables.Push(j);
                    break;

                case "ptr<mp_exp_t>":
                    args_size       += IntPtr.Size;
                    data_size       += 4;
                    va_args[j].write = (i) =>
                    {
                        IntPtr data_ptr = (IntPtr)(arguments.ToInt64() + args_size + va_args[i].data_offset);
                        Marshal.WriteIntPtr(arguments, va_args[i].arg_offset, data_ptr);
                        mp_exp_t data = ((ptr <mp_exp_t>)args[i]).Value;
                        Marshal.WriteInt32(data_ptr, 0, data.Value);
                    };
                    va_args[j].read = (i) =>
                    {
                        ptr <mp_exp_t> data     = (ptr <mp_exp_t>)args[i];
                        IntPtr         data_ptr = (IntPtr)(arguments.ToInt64() + args_size + va_args[i].data_offset);
                        data.Value.Value = Marshal.ReadInt32(data_ptr);
                    };
                    readables.Push(j);
                    break;

                case "ptr<Int64>":
                    args_size       += IntPtr.Size;
                    data_size       += 8;
                    va_args[j].write = (i) =>
                    {
                        IntPtr data_ptr = (IntPtr)(arguments.ToInt64() + args_size + va_args[i].data_offset);
                        Marshal.WriteIntPtr(arguments, va_args[i].arg_offset, data_ptr);
                        Int64 data = ((ptr <Int64>)args[i]).Value;
                        Marshal.WriteInt64(data_ptr, 0, data);
                    };
                    va_args[j].read = (i) =>
                    {
                        ptr <Int64> data     = (ptr <Int64>)args[i];
                        IntPtr      data_ptr = (IntPtr)(arguments.ToInt64() + args_size + va_args[i].data_offset);
                        data.Value = (Int64)Marshal.ReadInt64(data_ptr);
                    };
                    readables.Push(j);
                    break;

                case "ptr<UInt64>":
                    args_size       += IntPtr.Size;
                    data_size       += 8;
                    va_args[j].write = (i) =>
                    {
                        IntPtr data_ptr = (IntPtr)(arguments.ToInt64() + args_size + va_args[i].data_offset);
                        Marshal.WriteIntPtr(arguments, va_args[i].arg_offset, data_ptr);
                        UInt64 data = ((ptr <UInt64>)args[i]).Value;
                        Marshal.WriteInt64(data_ptr, 0, (Int64)data);
                    };
                    va_args[j].read = (i) =>
                    {
                        ptr <UInt64> data     = (ptr <UInt64>)args[i];
                        IntPtr       data_ptr = (IntPtr)(arguments.ToInt64() + args_size + va_args[i].data_offset);
                        data.Value = (UInt64)Marshal.ReadInt64(data_ptr);
                    };
                    readables.Push(j);
                    break;

                case "ptr<Double>":
                    args_size       += IntPtr.Size;
                    data_size       += 8;
                    va_args[j].write = (i) =>
                    {
                        IntPtr data_ptr = (IntPtr)(arguments.ToInt64() + args_size + va_args[i].data_offset);
                        Marshal.WriteIntPtr(arguments, va_args[i].arg_offset, data_ptr);
                        Double data = ((ptr <Double>)args[i]).Value;
                        Marshal.Copy(BitConverter.GetBytes(data), 0, data_ptr, 8);
                    };
                    va_args[j].read = (i) =>
                    {
                        ptr <Double> data     = (ptr <Double>)args[i];
                        IntPtr       data_ptr = (IntPtr)(arguments.ToInt64() + args_size + va_args[i].data_offset);
                        Byte[]       bytes    = new Byte[8];
                        Marshal.Copy(data_ptr, bytes, 0, 8);
                        data.Value = BitConverter.ToDouble(bytes, 0);
                    };
                    readables.Push(j);
                    break;

                case "ptr<mp_limb_t>":
                    args_size       += IntPtr.Size;
                    data_size       += IntPtr.Size;
                    va_args[j].write = (i) =>
                    {
                        IntPtr data_ptr = (IntPtr)(arguments.ToInt64() + args_size + va_args[i].data_offset);
                        Marshal.WriteIntPtr(arguments, va_args[i].arg_offset, data_ptr);
                        mp_limb_t data = ((ptr <mp_limb_t>)args[i]).Value;
                        if (IntPtr.Size == 4)
                        {
                            Marshal.WriteInt32(data_ptr, 0, (Int32)data.Value);
                        }
                        else
                        {
                            Marshal.WriteInt64(data_ptr, 0, (Int64)data.Value);
                        }
                    };
                    va_args[j].read = (i) =>
                    {
                        ptr <mp_limb_t> data     = (ptr <mp_limb_t>)args[i];
                        IntPtr          data_ptr = (IntPtr)(arguments.ToInt64() + args_size + va_args[i].data_offset);
                        if (IntPtr.Size == 4)
                        {
                            data.Value.Value = (UInt32)Marshal.ReadInt32(data_ptr);
                        }
                        else
                        {
                            data.Value.Value = (UInt64)Marshal.ReadInt64(data_ptr);
                        }
                    };
                    readables.Push(j);
                    break;

                case "ptr<size_t>":
                    args_size       += IntPtr.Size;
                    data_size       += IntPtr.Size;
                    va_args[j].write = (i) =>
                    {
                        IntPtr data_ptr = (IntPtr)(arguments.ToInt64() + args_size + va_args[i].data_offset);
                        Marshal.WriteIntPtr(arguments, va_args[i].arg_offset, data_ptr);
                        size_t data = ((ptr <size_t>)args[i]).Value;
                        if (IntPtr.Size == 4)
                        {
                            Marshal.WriteInt32(data_ptr, 0, (Int32)data.Value);
                        }
                        else
                        {
                            Marshal.WriteInt64(data_ptr, 0, (Int64)data.Value);
                        }
                    };
                    va_args[j].read = (i) =>
                    {
                        ptr <size_t> data     = (ptr <size_t>)args[i];
                        IntPtr       data_ptr = (IntPtr)(arguments.ToInt64() + args_size + va_args[i].data_offset);
                        if (IntPtr.Size == 4)
                        {
                            data.Value.Value = (UInt32)Marshal.ReadInt32(data_ptr);
                        }
                        else
                        {
                            data.Value.Value = (UInt64)Marshal.ReadInt64(data_ptr);
                        }
                    };
                    readables.Push(j);
                    break;

                case "ptr<IntPtr>":
                    args_size       += IntPtr.Size;
                    data_size       += IntPtr.Size;
                    va_args[j].write = (i) =>
                    {
                        IntPtr data_ptr = (IntPtr)(arguments.ToInt64() + args_size + va_args[i].data_offset);
                        Marshal.WriteIntPtr(arguments, va_args[i].arg_offset, data_ptr);
                        IntPtr data = ((ptr <IntPtr>)args[i]).Value;
                        Marshal.WriteIntPtr(data_ptr, 0, data);
                    };
                    va_args[j].read = (i) =>
                    {
                        ptr <IntPtr> data     = (ptr <IntPtr>)args[i];
                        IntPtr       data_ptr = (IntPtr)(arguments.ToInt64() + args_size + va_args[i].data_offset);
                        data.Value = Marshal.ReadIntPtr(data_ptr);
                    };
                    readables.Push(j);
                    break;

                default:
                    throw new System.InvalidOperationException("Unsupported variable argument type '" + name + "'");
                }
            }

            // Write arguments to unmanaged memory.
            arguments = gmp_lib.allocate((size_t)(args_size + data_size)).ToIntPtr();
            for (int i = 0; i < args.Length; i++)
            {
                va_args[i].write(i);
            }
        }
Ejemplo n.º 2
0
 /// <summary>
 /// Returns a value indicating whether this instance is equal to a specified <see cref="size_t">size_t</see> value.
 /// </summary>
 /// <param name="other">A <see cref="size_t">size_t</see> value to compare to this instance.</param>
 /// <returns><c>True</c> if <paramref name="other"/> has the same value as this instance; otherwise, <c>False</c>.</returns>
 public bool Equals(size_t other)
 {
     return(Value == other.Value);
 }