Merge pull request #5714 from alexischr/update_bockbuild
[mono.git] / mono / tests / pinvoke-utf8.cs
1 // Licensed to the .NET Foundation under one or more agreements.
2 // The .NET Foundation licenses this file to you under the MIT license.
3 // See the LICENSE file in the project root for more information.
4
5 using System;
6 using System.Runtime.InteropServices;
7 using System.Text;
8 using System.Collections.Generic;
9
10
11 // UTF8 
12 class UTF8StringTests
13 {
14         [DllImport("libtest", CallingConvention = CallingConvention.Cdecl)]
15         [return: MarshalAs(UnmanagedType.LPUTF8Str)]
16         public static extern string StringParameterInOut([In, Out][MarshalAs(UnmanagedType.LPUTF8Str)]string s, int index);
17         public static bool TestInOutStringParameter(string orgString, int index)
18         {
19                 string passedString = orgString;
20                 string expectedNativeString = passedString;
21                 
22                 string nativeString = StringParameterInOut(passedString, index);
23                 if (!(nativeString == expectedNativeString))
24                 {
25                         Console.WriteLine("StringParameterInOut: nativeString != expecedNativeString ");
26                         return false;
27                 }
28                 return true;
29         }
30
31         [DllImport("libtest", CallingConvention = CallingConvention.Cdecl)]
32         [return: MarshalAs(UnmanagedType.LPUTF8Str)]
33         public static extern string StringParameterOut([Out][MarshalAs(UnmanagedType.LPUTF8Str)]string s, int index);
34         public static bool TestOutStringParameter(string orgString, int index)
35         {
36                 string passedString = orgString;
37                 string expecedNativeString = passedString;
38                 string nativeString = StringParameterInOut(passedString, index);
39                 if (!(nativeString == expecedNativeString))
40                 {
41                         Console.WriteLine("StringParameterInOut: nativeString != expecedNativeString ");
42                         return false;
43                 }
44                 return true;
45         }
46
47         [DllImport("libtest", CallingConvention = CallingConvention.Cdecl)]
48         public static extern void StringParameterRefOut([MarshalAs(UnmanagedType.LPUTF8Str)]out string s, int index);
49         public static bool TestStringPassByOut(string orgString, int index)
50         {
51                 // out string 
52                 string expectedNative = string.Empty;
53                 StringParameterRefOut(out expectedNative, index);
54                 if (orgString != expectedNative)
55                 {
56                         Console.WriteLine ("TestStringPassByOut : expectedNative != outString");
57                         return false;
58                 }
59                 return true;
60         }
61
62         [DllImport("libtest", CallingConvention = CallingConvention.Cdecl)]
63         public static extern void StringParameterRef([MarshalAs(UnmanagedType.LPUTF8Str)]ref string s, int index);
64         public static bool TestStringPassByRef(string orgString, int index)
65         {
66                 string orgCopy = new string(orgString.ToCharArray());
67                 StringParameterRef(ref orgString, index);
68                 if (orgString != orgCopy)
69                 {
70                         Console.WriteLine("TestStringPassByOut : string mismatch");
71                         return false;
72                 }
73                 return true;
74         }
75
76         public static bool EmptyStringTest()
77         {
78                 StringParameterInOut(string.Empty, 0);
79                 StringParameterOut(string.Empty, 0);
80                 return true;
81         }
82 }
83
84 // UTF8 stringbuilder
85 class UTF8StringBuilderTests
86 {
87         [DllImport("libtest", CallingConvention = CallingConvention.Cdecl)]
88         public static extern void StringBuilderParameterInOut([In,Out][MarshalAs(UnmanagedType.LPUTF8Str)]StringBuilder s, int index);
89         public static bool TestInOutStringBuilderParameter(string expectedString, int index)
90         {
91                 StringBuilder nativeStrBuilder = new StringBuilder(expectedString);
92                 
93                 StringBuilderParameterInOut(nativeStrBuilder, index);
94                 
95                 if (!nativeStrBuilder.ToString().Equals(expectedString))
96                 {
97                         Console.WriteLine($"TestInOutStringBuilderParameter: nativeString != expecedNativeString index={index} got={nativeStrBuilder} and expected={expectedString} ");
98                         return false;
99                 }
100                 return true;
101         }
102         
103         [DllImport("libtest", CallingConvention = CallingConvention.Cdecl)]
104         public static extern void StringBuilderParameterOut([Out][MarshalAs(UnmanagedType.LPUTF8Str)]StringBuilder s, int index);
105         public static bool TestOutStringBuilderParameter(string expectedString, int index)
106         {
107                 // string builder capacity
108                 StringBuilder nativeStringBuilder = new StringBuilder(expectedString.Length);
109                 
110                 StringBuilderParameterOut(nativeStringBuilder, index);
111                 
112                 if (!nativeStringBuilder.ToString().Equals(expectedString))
113                 {
114                         Console.WriteLine("TestOutStringBuilderParameter: string != expecedString ");
115                         return false;
116                 }
117                 return true;
118         }
119         
120
121         [DllImport("libtest", CallingConvention = CallingConvention.Cdecl)]
122         [return: MarshalAs(UnmanagedType.LPUTF8Str,SizeConst = 512)]
123         public static extern StringBuilder StringBuilderParameterReturn(int index);
124         public static bool TestReturnStringBuilder(string expectedReturn, int index)
125         {
126                 StringBuilder nativeString = StringBuilderParameterReturn(index);
127                 if (!expectedReturn.Equals(nativeString.ToString()))
128                 {
129                         Console.WriteLine(string.Format( "TestReturnStringBuilder: nativeString {0} != expecedNativeString {1}",nativeString.ToString(),expectedReturn) );
130                         return false;
131                 }
132                 return true;
133         }
134 }
135
136 // UTF8 string as struct field
137 class UTF8StructMarshalling
138 {
139         public struct Utf8Struct
140         {
141                 [MarshalAs(UnmanagedType.LPUTF8Str)]
142                 public string FirstName;
143                 public int index;
144         }
145
146         [DllImport("libtest", CallingConvention = CallingConvention.Cdecl)]
147         public static extern void TestStructWithUtf8Field(Utf8Struct utfStruct);
148         public static bool  TestUTF8StructMarshalling(string[] utf8Strings)
149         {
150                 Utf8Struct utf8Struct = new Utf8Struct();
151                 for (int i = 0; i < utf8Strings.Length; i++)
152                 {
153                         utf8Struct.FirstName = utf8Strings[i];
154                         utf8Struct.index = i;
155                         TestStructWithUtf8Field(utf8Struct);
156                 }
157                 return true;
158         }
159 }
160
161 // UTF8 string as delegate parameter
162 class UTF8DelegateMarshalling
163 {
164         [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
165         public delegate void DelegateUTF8Parameter([MarshalAs(UnmanagedType.LPUTF8Str)]string utf8String, int index);
166
167         [DllImport("libtest", CallingConvention = CallingConvention.Cdecl)]
168         public static extern void Utf8DelegateAsParameter(DelegateUTF8Parameter param);
169         
170         static bool failed;
171         public static bool TestUTF8DelegateMarshalling()
172         {
173                 failed = false;
174                 Utf8DelegateAsParameter(new DelegateUTF8Parameter(Utf8StringCallback));
175                 
176                 return !failed;
177         }
178         
179         public static void Utf8StringCallback(string nativeString, int index)
180         {
181                 if (string.CompareOrdinal(nativeString, Test.utf8Strings[index]) != 0)
182                 {
183                         Console.WriteLine("Utf8StringCallback string do not match");
184                         failed = true;
185                 }
186         }
187 }
188
189 class Test
190 {
191         //test strings
192         public static string[] utf8Strings = {
193                 "Managed",
194                 "Sîne klâwen durh die wolken sint geslagen" ,
195                 "काचं शक्नोम्यत्तुम् । नोपहिनस्ति माम्",
196                 "我能吞下玻璃而不伤身体",
197                 "ღმერთსი შემვედრე,შემვედრე, ნუთუ კვლა დამხსნას შემვედრე,სოფლისა შემვედრე, შემვედრე,შემვედრე,შემვედრე,შრომასა, ცეცხლს, წყალსა და მიწასა, ჰაერთა თანა მრომასა; მომცნეს ფრთენი და აღვფრინდე, მივჰხვდე მას ჩემსა ნდომასა, დღისით და ღამით ვჰხედვიდე მზისა ელვათა კრთომაასაშემვედრე,შემვედრე,",
198                 "Τη γλώσσα μου έδωσαν ελληνική",
199                 null,
200         };
201         
202         public static int Main(string[] args)
203         {
204                 // Test string as [In,Out] parameter
205                 for (int i = 0; i < utf8Strings.Length; i++)
206                         if (!UTF8StringTests.TestInOutStringParameter(utf8Strings[i], i))
207                                 return i+1;
208                 
209                 // Test string as [Out] parameter
210                 for (int i = 0; i < utf8Strings.Length; i++)
211                         if (!UTF8StringTests.TestOutStringParameter(utf8Strings[i], i))
212                                 return i+100;
213                 
214                 for (int i = 0; i < utf8Strings.Length - 1; i++)
215                         if (!UTF8StringTests.TestStringPassByOut(utf8Strings[i], i))
216                                 return i+200;
217                 
218                 for (int i = 0; i < utf8Strings.Length - 1; i++)
219                         if (!UTF8StringTests.TestStringPassByRef(utf8Strings[i], i))
220                                 return i+300;
221                 
222                 
223                 // Test StringBuilder as [In,Out] parameter
224                 for (int i = 0; i < utf8Strings.Length - 1; i++)
225                         if (!UTF8StringBuilderTests.TestInOutStringBuilderParameter(utf8Strings[i], i))
226                                 return i+400;
227                 
228 #if NOT_YET
229                 // This requires support for [Out] in StringBuilder
230                 
231                 // Test StringBuilder as [Out] parameter
232                 for (int i = 0; i < utf8Strings.Length - 1; i++){
233                         if (!UTF8StringBuilderTests.TestOutStringBuilderParameter(utf8Strings[i], i))
234                                 return i+500;
235                 }
236
237 #endif
238         
239                 // utf8 string as struct fields
240                 if (!UTF8StructMarshalling.TestUTF8StructMarshalling(utf8Strings))
241                         return 600;
242
243                 // delegate
244                 try {
245                         UTF8DelegateMarshalling.TestUTF8DelegateMarshalling();
246                 } catch (ExecutionEngineException){
247                         // Known issue on AOT - we do not AOT this yet.
248                 }
249
250 #if NOT_YET
251                 // This requires special support for StringBuilder return values
252                 // Test StringBuilder as return value
253                 for (int i = 0; i < utf8Strings.Length - 1; i++)
254                         if (!UTF8StringBuilderTests.TestReturnStringBuilder(utf8Strings[i], i))
255                                 return 700+i;
256 #endif
257                 // String.Empty tests
258                 if (!UTF8StringTests.EmptyStringTest())
259                         return 800;
260
261                 return 0;
262         }
263 }