@@ -37,7 +37,7 @@ public class CSharpCodeGenerator : ICodeGenerator
37
37
[ typeof ( Vector2Node ) ] = "Vector2" ,
38
38
[ typeof ( Vector3Node ) ] = "Vector3" ,
39
39
[ typeof ( Vector4Node ) ] = "Vector4"
40
- } ;
40
+ } ;
41
41
42
42
public Language Language => Language . CSharp ;
43
43
@@ -77,21 +77,42 @@ public string GenerateCode(IReadOnlyList<ClassNode> classes, IReadOnlyList<EnumD
77
77
. Where ( c => c . Nodes . None ( n => n is FunctionNode ) ) // Skip class which contains FunctionNodes because these are not data classes.
78
78
. Distinct ( ) ;
79
79
80
+ var unicodeStringClassLengthsToGenerate = new HashSet < int > ( ) ;
81
+
80
82
using ( var en = classesToWrite . GetEnumerator ( ) )
81
83
{
82
84
if ( en . MoveNext ( ) )
83
85
{
86
+ void FindUnicodeStringClasses ( IEnumerable < BaseNode > nodes )
87
+ {
88
+ unicodeStringClassLengthsToGenerate . UnionWith ( nodes . OfType < Utf16TextNode > ( ) . Select ( n => n . Length ) ) ;
89
+ }
90
+
91
+ FindUnicodeStringClasses ( en . Current ! . Nodes ) ;
92
+
84
93
WriteClass ( iw , en . Current , logger ) ;
85
94
86
95
while ( en . MoveNext ( ) )
87
96
{
88
97
iw . WriteLine ( ) ;
89
98
99
+ FindUnicodeStringClasses ( en . Current ! . Nodes ) ;
100
+
90
101
WriteClass ( iw , en . Current , logger ) ;
91
102
}
92
103
}
93
104
}
94
105
106
+ if ( unicodeStringClassLengthsToGenerate . Any ( ) )
107
+ {
108
+ foreach ( var length in unicodeStringClassLengthsToGenerate )
109
+ {
110
+ iw . WriteLine ( ) ;
111
+
112
+ WriteUnicodeStringClass ( iw , length ) ;
113
+ }
114
+ }
115
+
95
116
return sw . ToString ( ) ;
96
117
}
97
118
@@ -152,7 +173,7 @@ private static void WriteClass(IndentedTextWriter writer, ClassNode @class, ILog
152
173
Contract . Requires ( @class != null ) ;
153
174
Contract . Requires ( logger != null ) ;
154
175
155
- writer . WriteLine ( "[StructLayout(LayoutKind.Explicit)]" ) ;
176
+ writer . WriteLine ( "[StructLayout(LayoutKind.Explicit, CharSet = CharSet.Ansi )]" ) ;
156
177
writer . Write ( "public struct " ) ;
157
178
writer . Write ( @class . Name ) ;
158
179
@@ -199,10 +220,10 @@ private static void WriteClass(IndentedTextWriter writer, ClassNode @class, ILog
199
220
}
200
221
201
222
/// <summary>
202
- /// Gets the type definition for the given node. If the node is not a simple node <c>null</c> is returned.
223
+ /// Gets the type definition for the given node. If the node is not expressible <c>null</c> as typename is returned.
203
224
/// </summary>
204
225
/// <param name="node">The target node.</param>
205
- /// <returns>The type definition for the node or null if no simple type is available .</returns>
226
+ /// <returns>The type definition for the node or null as typename if the node is not expressible .</returns>
206
227
private static ( string typeName , string attribute ) GetTypeDefinition ( BaseNode node )
207
228
{
208
229
Contract . Requires ( node != null ) ;
@@ -219,17 +240,36 @@ private static (string typeName, string attribute) GetTypeDefinition(BaseNode no
219
240
return ( type , null ) ;
220
241
}
221
242
222
- if ( node is EnumNode enumNode )
243
+ return node switch
223
244
{
224
- return ( enumNode . Enum . Name , null ) ;
225
- }
245
+ EnumNode enumNode => ( enumNode . Enum . Name , null ) ,
246
+ Utf8TextNode utf8TextNode => ( "string" , $ "[MarshalAs(UnmanagedType.ByValTStr, SizeConst = { utf8TextNode . Length } )]") ,
247
+ Utf16TextNode utf16TextNode => ( GetUnicodeStringClassName ( utf16TextNode . Length ) , "[MarshalAs(UnmanagedType.Struct)]" ) ,
248
+ _ => ( null , null )
249
+ } ;
250
+ }
226
251
227
- if ( node is Utf8TextNode utf8TextNode )
228
- {
229
- return ( "string" , $ "[MarshalAs(UnmanagedType.ByValTStr, SizeConst = { utf8TextNode . Length } )]") ;
230
- }
252
+ private static string GetUnicodeStringClassName ( int length ) => $ "__UnicodeString{ length } ";
231
253
232
- return ( null , null ) ;
254
+ /// <summary>
255
+ /// Writes a helper class for unicode strings with the specific length.
256
+ /// </summary>
257
+ /// <param name="writer">The writer to output to.</param>
258
+ /// <param name="length">The string length for this class.</param>
259
+ private static void WriteUnicodeStringClass ( IndentedTextWriter writer , int length )
260
+ {
261
+ var className = GetUnicodeStringClassName ( length ) ;
262
+
263
+ writer . WriteLine ( "[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Unicode)]" ) ;
264
+ writer . WriteLine ( $ "public struct { className } ") ;
265
+ writer . WriteLine ( "{" ) ;
266
+ writer . Indent ++ ;
267
+ writer . WriteLine ( $ "[MarshalAs(UnmanagedType.ByValTStr, SizeConst = { length } )]") ;
268
+ writer . WriteLine ( "public string Value;" ) ;
269
+ writer . WriteLine ( ) ;
270
+ writer . WriteLine ( $ "public static implicit operator string({ className } value) => value.Value;") ;
271
+ writer . Indent -- ;
272
+ writer . WriteLine ( "}" ) ;
233
273
}
234
274
}
235
275
}
0 commit comments