Throw exception when trying to unlock unowned lock.
[mono.git] / mono / tests / marshal2.cs
index 9ba085f63f09f8bdc0f71ecb5d13c8752b25cac9..8a0d43f3a3660255097fa2cb59e9e21a2f399697 100644 (file)
@@ -1,7 +1,12 @@
+//
+// Tests for Marshal.StructureToPtr and PtrToStructure
+//
+
 using System;
+using System.Text;
 using System.Runtime.InteropServices;
 
-public class Test {
+public class Tests {
 
 
        [StructLayout (LayoutKind.Sequential)]
@@ -30,13 +35,42 @@ public class Test {
                public SimpleObj emb2;
                public string s2;
                public double x;
+               [MarshalAs (UnmanagedType.ByValArray, SizeConst=2)] public char[] a2;
+       }
+
+       [StructLayout (LayoutKind.Sequential, CharSet=CharSet.Ansi)]
+       public struct ByValTStrStruct {
+               [MarshalAs (UnmanagedType.ByValTStr, SizeConst=4)] public string s1;
+               public int i;
+       }
+
+       [StructLayout (LayoutKind.Sequential, CharSet=CharSet.Unicode)]
+       public struct ByValWStrStruct {
+               [MarshalAs (UnmanagedType.ByValTStr, SizeConst=4)] public string s1;
+               public int i;
+       }
+
+       [StructLayout (LayoutKind.Sequential, Pack=1)]
+       public struct PackStruct1 {
+               float f;
+       }
+
+       [StructLayout (LayoutKind.Sequential)]
+       public struct PackStruct2 {
+               byte b;
+               PackStruct1 s;
        }
        
-       public unsafe static int Main () {
+       public unsafe static int Main (String[] args) {
+               if (TestDriver.RunTests (typeof (Tests), args) != 0)
+                       return 34;
+               return 0;
+       }
+
+       public static int test_0_structure_to_ptr () {
                SimpleStruct ss = new SimpleStruct ();
                int size = Marshal.SizeOf (typeof (SimpleStruct));
                
-               Console.WriteLine ("SimpleStruct:" + size);
                //if (size != 52)
                //return 1;
                
@@ -57,6 +91,9 @@ public class Test {
                ss.emb2.b = 11;
                ss.s2 = "just a test";
                ss.x = 1.5;
+               ss.a2 = new char [2];
+               ss.a2 [0] = 'a';
+               ss.a2 [1] = 'b';
                
                Marshal.StructureToPtr (ss, p, false);
                Type t = ss.GetType ();
@@ -89,8 +126,10 @@ public class Test {
                        return 13;
                if (Marshal.ReadInt32 (p, 36) != 11)
                        return 14;
-               if (Marshal.ReadInt32 (p, (int)Marshal.OffsetOf (t, "s2")) == 0)
+               if (Marshal.ReadByte (p, (int)Marshal.OffsetOf (t, "a2")) != 97)
                        return 15;
+               if (Marshal.ReadByte (p, (int)Marshal.OffsetOf (t, "a2") + 1) != 98)
+                       return 16;
 
                SimpleStruct cp = (SimpleStruct)Marshal.PtrToStructure (p, ss.GetType ());
 
@@ -132,8 +171,110 @@ public class Test {
 
                if (cp.x != 1.5)
                        return 28;
-               
+
+               if (cp.a2 [0] != 'a')
+                       return 29;
+
+               if (cp.a2 [1] != 'b')
+                       return 30;
                return 0;
        }
-}
 
+       [StructLayout(LayoutKind.Sequential, Pack = 1, CharSet = CharSet.Unicode)]
+       public struct Struct1
+       {
+               [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 8)]
+        public string Field1;
+               [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 10)]
+        public string Field2;
+               [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 14)]
+        public string Field3;
+       }
+
+       public static int test_0_byvaltstr () {
+               ByValTStrStruct s = new ByValTStrStruct ();
+
+               IntPtr p2 = Marshal.AllocHGlobal (Marshal.SizeOf (typeof (ByValTStrStruct)));
+               Marshal.StructureToPtr(s, p2, false);
+
+               /* Check that the ByValTStr is initialized correctly */
+               for (int i = 0; i < 4; ++i)
+                       if (Marshal.ReadByte (p2, i) != 0)
+                               return 31;
+
+               s.s1 = "ABCD";
+               s.i = 55;
+
+               Marshal.StructureToPtr(s, p2, false);
+
+               ByValTStrStruct s2 = (ByValTStrStruct)Marshal.PtrToStructure (p2, typeof (ByValTStrStruct));
+
+               /* The fourth char is lost because of null-termination */
+               if (s2.s1 != "ABC")
+                       return 32;
+
+               if (s2.i != 55)
+                       return 33;
+
+               // Check that decoding also respects the size, even when there is no null terminator
+               byte[] data = Encoding.ASCII.GetBytes ("ABCDXXXX");
+               int size = Marshal.SizeOf (typeof (ByValTStrStruct));
+               IntPtr buffer = Marshal.AllocHGlobal (size);
+               Marshal.Copy (data, 0, buffer, size);
+
+               s2 = (ByValTStrStruct)Marshal.PtrToStructure (buffer, typeof (ByValTStrStruct));
+               if (s2.s1 != "ABC")
+                       return 34;
+
+               return 0;
+       }
+
+       public static int test_0_byvaltstr_unicode () {
+               ByValWStrStruct s = new ByValWStrStruct ();
+
+               IntPtr p2 = Marshal.AllocHGlobal (Marshal.SizeOf (typeof (ByValWStrStruct)));
+               Marshal.StructureToPtr(s, p2, false);
+
+               /* Check that the ByValWStr is initialized correctly */
+               for (int i = 0; i < 8; ++i)
+                       if (Marshal.ReadByte (p2, i) != 0)
+                               return 31;
+
+               s.s1 = "ABCD";
+               s.i = 55;
+
+               Marshal.StructureToPtr(s, p2, false);
+
+               ByValWStrStruct s2 = (ByValWStrStruct)Marshal.PtrToStructure (p2, typeof (ByValWStrStruct));
+
+               /* The fourth char is lost because of null-termination */
+               if (s2.s1 != "ABC")
+                       return 32;
+
+               if (s2.i != 55)
+                       return 33;
+               return 0;
+       }
+
+       public static int test_0_byvaltstr_max_size () {
+               string buffer = "12345678123456789012345678901234";
+
+               IntPtr ptr = Marshal.StringToBSTR (buffer);
+
+               Struct1 data = (Struct1)Marshal.PtrToStructure (ptr, typeof (Struct1));
+               if (data.Field1 != "12345678")
+                       return 1;
+               if (data.Field2 != "1234567890")
+                       return 2;
+               if (data.Field3 != "12345678901234")
+                       return 3;
+               return 0;
+       }
+
+       // Check that the 'Pack' directive on a struct changes the min alignment of the struct as well (#12110)
+       public static int test_0_struct_pack () {
+               if (Marshal.OffsetOf (typeof (PackStruct2), "s") != new IntPtr (1))
+                       return 1;
+               return 0;
+       }
+}