Fix warnings in mscorlib's Test suite + bring a couple more tests + fix thread rename...
[mono.git] / mcs / class / corlib / System.Runtime.InteropServices / Marshal.cs
index 863dcf3b0fb08614d19791d801840cd0f9a62e6a..e339f94955ad4463ee6de55a20d018c6b0157cd2 100644 (file)
@@ -187,6 +187,12 @@ namespace System.Runtime.InteropServices
                        throw new NotImplementedException ();
                }
 
+#if NET_4_5
+               public static IntPtr CreateAggregatedObject<T> (IntPtr pOuter, T o) {
+                       return CreateAggregatedObject (pOuter, (object)o);
+               }
+#endif
+
 #if !FULL_AOT_RUNTIME
                public static object CreateWrapperOfType (object o, Type t)
                {
@@ -204,12 +210,24 @@ namespace System.Runtime.InteropServices
 
                        return ComInteropProxy.GetProxy (co.IUnknown, t).GetTransparentProxy ();
                }
+
+#if NET_4_5
+               public static TWrapper CreateWrapperOfType<T, TWrapper> (T o) {
+                       return (TWrapper)CreateWrapperOfType ((object)o, typeof (TWrapper));
+               }
+#endif
 #endif
 
                [MethodImplAttribute(MethodImplOptions.InternalCall)]
                [ComVisible (true)]
                public extern static void DestroyStructure (IntPtr ptr, Type structuretype);
 
+#if NET_4_5
+               public static void DestroyStructure<T> (IntPtr ptr) {
+                       DestroyStructure (ptr, typeof (T));
+               }
+#endif                 
+
                [MethodImplAttribute(MethodImplOptions.InternalCall)]
                public extern static void FreeBSTR (IntPtr ptr);
 
@@ -329,6 +347,12 @@ namespace System.Runtime.InteropServices
 #endif
                }
 
+#if NET_4_5
+               public static IntPtr GetComInterfaceForObject<T, TInterface> (T o) {
+                       return GetComInterfaceForObject ((object)o, typeof (T));
+               }
+#endif                 
+
                [MonoTODO]
                public static IntPtr GetComInterfaceForObjectInContext (object o, Type t)
                {
@@ -463,6 +487,12 @@ namespace System.Runtime.InteropServices
                        Marshal.StructureToPtr(vt, pDstNativeVariant, false);
                }
 
+#if NET_4_5
+               public static void GetNativeVariantForObject<T> (T obj, IntPtr pDstNativeVariant) {
+                       GetNativeVariantForObject ((object)obj, pDstNativeVariant);
+               }
+#endif
+
 #if !MOBILE
                [MethodImplAttribute (MethodImplOptions.InternalCall)]
                private static extern object GetObjectForCCW (IntPtr pUnk);
@@ -489,6 +519,13 @@ namespace System.Runtime.InteropServices
                        return vt.GetValue();
                }
 
+#if NET_4_5
+               public static T GetObjectForNativeVariant<T> (IntPtr pSrcNativeVariant) {
+                       Variant vt = (Variant)Marshal.PtrToStructure(pSrcNativeVariant, typeof(Variant));
+                       return (T)vt.GetValue();
+               }
+#endif
+
                public static object[] GetObjectsForNativeVariants (IntPtr aSrcNativeVariant, int cVars)
                {
                        if (cVars < 0)
@@ -500,6 +537,18 @@ namespace System.Runtime.InteropServices
                        return objects;
                }
 
+#if NET_4_5
+               public static T[] GetObjectsForNativeVariants<T> (IntPtr aSrcNativeVariant, int cVars) {
+                       if (cVars < 0)
+                               throw new ArgumentOutOfRangeException ("cVars", "cVars cannot be a negative number.");
+                       T[] objects = new T[cVars];
+                       for (int i = 0; i < cVars; i++)
+                               objects[i] = GetObjectForNativeVariant<T> ((IntPtr)(aSrcNativeVariant.ToInt64 () +
+                                       i * SizeOf (typeof(Variant))));
+                       return objects;
+               }
+#endif
+
                [MonoTODO]
                public static int GetStartComSlot (Type t)
                {
@@ -532,6 +581,13 @@ namespace System.Runtime.InteropServices
                        throw new NotImplementedException ();
                }
 
+#if NET_4_5
+               public static Type GetTypeFromCLSID (Guid clsid)
+               {
+                       throw new NotImplementedException ();                   
+               }
+#endif
+
 #if !FULL_AOT_RUNTIME
                [Obsolete]
                [MonoTODO]
@@ -639,6 +695,12 @@ namespace System.Runtime.InteropServices
                [MethodImplAttribute(MethodImplOptions.InternalCall)]
                public extern static IntPtr OffsetOf (Type t, string fieldName);
 
+#if NET_4_5
+               public static IntPtr OffsetOf<T> (string fieldName) {
+                       return OffsetOf (typeof (T), fieldName);
+               }
+#endif
+
                [MethodImplAttribute(MethodImplOptions.InternalCall)]
                public extern static void Prelink (MethodInfo m);
 
@@ -687,6 +749,16 @@ namespace System.Runtime.InteropServices
                [ComVisible (true)]
                public extern static object PtrToStructure (IntPtr ptr, Type structureType);
 
+#if NET_4_5
+               public static void PtrToStructure<T> (IntPtr ptr, T structure) {
+                       PtrToStructure (ptr, (object)structure);
+               }
+
+               public static T PtrToStructure<T> (IntPtr ptr) {
+                       return (T) PtrToStructure (ptr, typeof (T));
+               }
+#endif
+
 #if !MOBILE
                [MethodImplAttribute (MethodImplOptions.InternalCall)]
                private extern static int QueryInterfaceInternal (IntPtr pUnk, ref Guid iid, out IntPtr ppv);
@@ -712,7 +784,7 @@ namespace System.Runtime.InteropServices
 
                public static byte ReadByte (IntPtr ptr, int ofs) {
                        unsafe {
-                               return *(byte*)(ptr + ofs);
+                               return *((byte*)ptr + ofs);
                        }
                }
 
@@ -723,35 +795,31 @@ namespace System.Runtime.InteropServices
                        throw new NotImplementedException ();
                }
 
-               public static short ReadInt16 (IntPtr ptr)
+               public unsafe static short ReadInt16 (IntPtr ptr)
                {
+                       byte *addr = (byte *) ptr;
+                       
                        // The mono JIT can't inline this due to the hight number of calls
                        // return ReadInt16 (ptr, 0);
-                       if (ptr.ToInt32 () % 2 == 0) {
-                               unsafe {
-                                       return *(short*)ptr;
-                               }
-                       } else {
-                               unsafe {
-                                       short s;
-                                       String.memcpy ((byte*)&s, (byte*)ptr, 2);
-                                       return s;
-                               }
-                       }
+                       
+                       if (((uint)addr & 1) == 0) 
+                               return *(short*)addr;
+
+                       short s;
+                       String.memcpy ((byte*)&s, (byte*)ptr, 2);
+                       return s;
                }
 
-               public static short ReadInt16 (IntPtr ptr, int ofs) {
-                       if ((ptr + ofs).ToInt32 () % 2 == 0) {
-                               unsafe {
-                                       return *(short*)(ptr + ofs);
-                               }
-                       } else {
-                               unsafe {
-                                       short s;
-                                       String.memcpy ((byte*)&s, (byte*)(ptr + ofs), 2);
-                                       return s;
-                               }
-                       }
+               public unsafe static short ReadInt16 (IntPtr ptr, int ofs)
+               {
+                       byte *addr = ((byte *) ptr) + ofs;
+
+                       if (((uint) addr & 1) == 0)
+                               return *(short*)addr;
+
+                       short s;
+                       String.memcpy ((byte*)&s, addr, 2);
+                       return s;
                }
 
                [MonoTODO]
@@ -761,33 +829,30 @@ namespace System.Runtime.InteropServices
                        throw new NotImplementedException ();
                }
 
-               public static int ReadInt32 (IntPtr ptr)
+               [ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.Success)]
+               public unsafe static int ReadInt32 (IntPtr ptr)
                {
-                       if (ptr.ToInt32 () % 4 == 0) {
-                               unsafe {
-                                       return *(int*)ptr;
-                               }
-                       } else {
-                               unsafe {
-                                       int s;
-                                       String.memcpy ((byte*)&s, (byte*)ptr, 4);
-                                       return s;
-                               }
-                       }
+                       byte *addr = (byte *) ptr;
+                       
+                       if (((uint)addr & 3) == 0) 
+                               return *(int*)addr;
+
+                       int s;
+                       String.memcpy ((byte*)&s, addr, 4);
+                       return s;
                }
 
                [ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.Success)]
-               public static int ReadInt32 (IntPtr ptr, int ofs) {
-                       if ((ptr + ofs).ToInt32 () % 4 == 0) {
-                               unsafe {
-                                       return *(int*)(ptr + ofs);
-                               }
-                       } else {
-                               unsafe {
-                                       int s;
-                                       String.memcpy ((byte*)&s, (byte*)(ptr + ofs), 4);
-                                       return s;
-                               }
+               public unsafe static int ReadInt32 (IntPtr ptr, int ofs)
+               {
+                       byte *addr = ((byte *) ptr) + ofs;
+                       
+                       if ((((int) addr) & 3) == 0)
+                               return *(int*)addr;
+                       else {
+                               int s;
+                               String.memcpy ((byte*)&s, addr, 4);
+                               return s;
                        }
                }
 
@@ -800,35 +865,30 @@ namespace System.Runtime.InteropServices
                }
 
                [ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.Success)]
-               public static long ReadInt64 (IntPtr ptr)
+               public unsafe static long ReadInt64 (IntPtr ptr)
                {
+                       byte *addr = (byte *) ptr;
+                               
                        // The real alignment might be 4 on some platforms, but this is just an optimization,
                        // so it doesn't matter.
-                       if (ptr.ToInt32 () % 8 == 0) {
-                               unsafe {
-                                       return *(long*)ptr;
-                               }
-                       } else {
-                               unsafe {
-                                       long s;
-                                       String.memcpy ((byte*)&s, (byte*)ptr, 8);
-                                       return s;
-                               }
-                       }
+                       if (((uint) addr & 7) == 0)
+                               return *(long*)ptr;
+
+                       long s;
+                       String.memcpy ((byte*)&s, addr, 8);
+                       return s;
                }
 
-               public static long ReadInt64 (IntPtr ptr, int ofs) {
-                       if ((ptr + ofs).ToInt32 () % 8 == 0) {
-                               unsafe {
-                                       return *(long*)(ptr + ofs);
-                               }
-                       } else {
-                               unsafe {
-                                       long s;
-                                       String.memcpy ((byte*)&s, (byte*)(ptr + ofs), 8);
-                                       return s;
-                               }
-                       }
+               public unsafe static long ReadInt64 (IntPtr ptr, int ofs)
+               {
+                       byte *addr = ((byte *) ptr) + ofs;
+
+                       if (((uint) addr & 7) == 0)
+                               return *(long*)addr;
+                       
+                       long s;
+                       String.memcpy ((byte*)&s, addr, 8);
+                       return s;
                }
 
                [ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.Success)]
@@ -842,11 +902,15 @@ namespace System.Runtime.InteropServices
                [ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.Success)]
                public static IntPtr ReadIntPtr (IntPtr ptr)
                {
-                       return ReadIntPtr (ptr, 0);
+                       if (IntPtr.Size == 4)
+                               return (IntPtr)ReadInt32 (ptr);
+                       else
+                               return (IntPtr)ReadInt64 (ptr);
                }
                
                [ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.Success)]
-               public static IntPtr ReadIntPtr (IntPtr ptr, int ofs) {
+               public static IntPtr ReadIntPtr (IntPtr ptr, int ofs)
+               {
                        if (IntPtr.Size == 4)
                                return (IntPtr)ReadInt32 (ptr, ofs);
                        else
@@ -921,6 +985,16 @@ namespace System.Runtime.InteropServices
                [MethodImplAttribute(MethodImplOptions.InternalCall)]
                public extern static int SizeOf (Type t);
 
+#if NET_4_5
+               public static int SizeOf<T> () {
+                       return SizeOf (typeof (T));
+               }
+
+               public static int SizeOf<T> (T structure) {
+                       return SizeOf (structure.GetType ());
+               }
+#endif
+
                [MethodImplAttribute(MethodImplOptions.InternalCall)]
                public extern static IntPtr StringToBSTR (string s);
 
@@ -1067,6 +1141,12 @@ namespace System.Runtime.InteropServices
                [MethodImplAttribute(MethodImplOptions.InternalCall)]
                public extern static void StructureToPtr (object structure, IntPtr ptr, bool fDeleteOld);
 
+#if NET_4_5
+               public static void StructureToPtr<T> (T structure, IntPtr ptr, bool fDeleteOld) {
+                       StructureToPtr ((object)structure, ptr, fDeleteOld);
+               }
+#endif
+
                public static void ThrowExceptionForHR (int errorCode) {
                        Exception ex = GetExceptionForHR (errorCode);
                        if (ex != null)
@@ -1082,6 +1162,12 @@ namespace System.Runtime.InteropServices
                [MethodImplAttribute(MethodImplOptions.InternalCall)]
                public extern static IntPtr UnsafeAddrOfPinnedArrayElement (Array arr, int index);
 
+#if NET_4_5
+               public static IntPtr UnsafeAddrOfPinnedArrayElement<T> (T[] arr, int index) {
+                       return UnsafeAddrOfPinnedArrayElement ((Array)arr, index);
+               }
+#endif
+
                public static void WriteByte (IntPtr ptr, byte val)
                {
                        unsafe {
@@ -1091,7 +1177,7 @@ namespace System.Runtime.InteropServices
 
                public static void WriteByte (IntPtr ptr, int ofs, byte val) {
                        unsafe {
-                               *(byte*)(ptr + ofs) = val;
+                               *(byte*)(IntPtr.Add (ptr, ofs)) = val;
                        }
                }
 
@@ -1102,28 +1188,24 @@ namespace System.Runtime.InteropServices
                        throw new NotImplementedException ();
                }
 
-               public static void WriteInt16 (IntPtr ptr, short val)
+               public static unsafe void WriteInt16 (IntPtr ptr, short val)
                {
-                       if (ptr.ToInt32 () % 2 == 0) {
-                               unsafe {
-                                       *(short*)ptr = val;
-                               }
-                       } else {
-                               unsafe {
-                                       String.memcpy ((byte*)ptr, (byte*)&val, 2);
-                               }
-                       }
+                       byte *addr = (byte *) ptr;
+                       
+                       if (((uint)addr & 1) == 0)
+                               *(short*)addr = val;
+                       else
+                               String.memcpy (addr, (byte*)&val, 2);
                }
 
-               public static void WriteInt16 (IntPtr ptr, int ofs, short val) {
-                       if ((ptr + ofs).ToInt32 () % 2 == 0) {
-                               unsafe {
-                                       *(short*)(ptr + ofs) = val;
-                               }
-                       } else {
-                               unsafe {
-                                       String.memcpy ((byte*)(ptr + ofs), (byte*)&val, 2);
-                               }
+               public static unsafe void WriteInt16 (IntPtr ptr, int ofs, short val)
+               {
+                       byte *addr = ((byte *) ptr) + ofs;
+
+                       if (((uint)addr & 1) == 0)
+                               *(short*)addr = val;
+                       else {
+                               String.memcpy (addr, (byte*)&val, 2);
                        }
                }
 
@@ -1139,7 +1221,8 @@ namespace System.Runtime.InteropServices
                        WriteInt16 (ptr, 0, (short)val);
                }
 
-               public static void WriteInt16 (IntPtr ptr, int ofs, char val) {
+               public static void WriteInt16 (IntPtr ptr, int ofs, char val)
+               {
                        WriteInt16 (ptr, ofs, (short)val);
                }
 
@@ -1149,28 +1232,25 @@ namespace System.Runtime.InteropServices
                        throw new NotImplementedException ();
                }
 
-               public static void WriteInt32 (IntPtr ptr, int val)
+               public static unsafe void WriteInt32 (IntPtr ptr, int val)
                {
-                       if (ptr.ToInt32 () % 4 == 0) {
-                               unsafe {
-                                       *(int*)ptr = val;
-                               }
-                       } else {
-                               unsafe {
-                                       String.memcpy ((byte*)ptr, (byte*)&val, 4);
-                               }
+                       byte *addr = (byte *) ptr;
+                       
+                       if (((uint)addr & 3) == 0) 
+                               *(int*)addr = val;
+                       else {
+                               String.memcpy (addr, (byte*)&val, 4);
                        }
                }
 
-               public static void WriteInt32 (IntPtr ptr, int ofs, int val) {
-                       if ((ptr + ofs).ToInt32 () % 4 == 0) {
-                               unsafe {
-                                       *(int*)(ptr + ofs) = val;
-                               }
-                       } else {
-                               unsafe {
-                                       String.memcpy ((byte*)(ptr + ofs), (byte*)&val, 4);
-                               }
+               public unsafe static void WriteInt32 (IntPtr ptr, int ofs, int val)
+               {
+                       byte *addr = ((byte *) ptr) + ofs;
+
+                       if (((uint)addr & 3) == 0) 
+                               *(int*)addr = val;
+                       else {
+                               String.memcpy (addr, (byte*)&val, 4);
                        }
                }
 
@@ -1181,30 +1261,28 @@ namespace System.Runtime.InteropServices
                        throw new NotImplementedException ();
                }
 
-               public static void WriteInt64 (IntPtr ptr, long val)
+               public static unsafe void WriteInt64 (IntPtr ptr, long val)
                {
-                       // See ReadInt64 ()
-                       if (ptr.ToInt32 () % 8 == 0) {
-                               unsafe {
-                                       *(long*)ptr = val;
-                               }
-                       } else {
-                               unsafe {
-                                       String.memcpy ((byte*)ptr, (byte*)&val, 8);
-                               }
-                       }
+                       byte *addr = (byte *) ptr;
+                       
+                       // The real alignment might be 4 on some platforms, but this is just an optimization,
+                       // so it doesn't matter.
+                       if (((uint)addr & 7) == 0) 
+                               *(long*)addr = val;
+                       else 
+                               String.memcpy (addr, (byte*)&val, 8);
                }
 
-               public static void WriteInt64 (IntPtr ptr, int ofs, long val) {
-                       if ((ptr + ofs).ToInt32 () % 8 == 0) {
-                               unsafe {
-                                       *(long*)(ptr + ofs) = val;
-                               }
-                       } else {
-                               unsafe {
-                                       String.memcpy ((byte*)(ptr + ofs), (byte*)&val, 8);
-                               }
-                       }
+               public static unsafe void WriteInt64 (IntPtr ptr, int ofs, long val)
+               {
+                       byte *addr = ((byte *) ptr) + ofs;
+
+                       // The real alignment might be 4 on some platforms, but this is just an optimization,
+                       // so it doesn't matter.
+                       if (((uint)addr & 7) == 0) 
+                               *(long*)addr = val;
+                       else 
+                               String.memcpy (addr, (byte*)&val, 8);
                }
 
                [MonoTODO]
@@ -1216,10 +1294,14 @@ namespace System.Runtime.InteropServices
 
                public static void WriteIntPtr (IntPtr ptr, IntPtr val)
                {
-                       WriteIntPtr (ptr, 0, val);
+                       if (IntPtr.Size == 4)
+                               WriteInt32 (ptr, (int)val);
+                       else
+                               WriteInt64 (ptr, (long)val);
                }
 
-               public static void WriteIntPtr (IntPtr ptr, int ofs, IntPtr val) {
+               public static void WriteIntPtr (IntPtr ptr, int ofs, IntPtr val)
+               {
                        if (IntPtr.Size == 4)
                                WriteInt32 (ptr, ofs, (int)val);
                        else
@@ -1278,6 +1360,12 @@ namespace System.Runtime.InteropServices
                        return GetDelegateForFunctionPointerInternal (ptr, t);
                }
 
+#if NET_4_5
+               public static TDelegate GetDelegateForFunctionPointer<TDelegate> (IntPtr ptr) {
+                       return (TDelegate) (object) GetDelegateForFunctionPointer (ptr, typeof (TDelegate));
+               }
+#endif
+
                [MethodImplAttribute(MethodImplOptions.InternalCall)]
                private static extern IntPtr GetFunctionPointerForDelegateInternal (Delegate d);
                
@@ -1288,5 +1376,14 @@ namespace System.Runtime.InteropServices
                        
                        return GetFunctionPointerForDelegateInternal (d);
                }
+
+#if NET_4_5
+               public static IntPtr GetFunctionPointerForDelegate<TDelegate> (TDelegate d) {
+                       if (d == null)
+                               throw new ArgumentNullException ("d");
+                       
+                       return GetFunctionPointerForDelegateInternal ((Delegate)(object)d);
+               }
+#endif
        }
 }