11using Microsoft . CodeAnalysis ;
22using System ;
33using System . Collections . Generic ;
4- using System . Linq ;
54using System . Text ;
65
76namespace StackMemoryCollections
@@ -26,36 +25,39 @@ in StringBuilder builder
2625 }
2726
2827 GenerateStart ( in builder , in currentType ) ;
29- GenerateSize ( in builder , in typeInfo ) ;
28+ GenerateOffsetsAndSize ( in builder , in typeInfo ) ;
3029 GenerateIsNullable ( in builder , in typeInfo ) ;
3130
32-
3331 for ( int j = 0 ; j < typeInfo . Members . Count ; j ++ )
3432 {
3533 MemberInfo memberInfo = typeInfo . Members [ j ] ;
36- GenerateGetPtr ( in builder , in memberInfo ) ;
34+ var offsetStr = memberInfo . IsRuntimeOffsetCalculated ? $ "{ currentType . Name } Helper.{ memberInfo . MemberName } Offset" : $ "{ memberInfo . Offset } ";
35+ GenerateGetPtr ( in builder , in memberInfo , in offsetStr ) ;
3736
3837 if ( memberInfo . IsPrimitive )
3938 {
40- GenerateGetPrimitiveValue ( in builder , in memberInfo ) ;
41- GenerateGetPrimitiveValueRef ( in builder , in memberInfo ) ;
42- GenerateGetPrimitiveValueOut ( in builder , in memberInfo ) ;
39+ GenerateGetPrimitiveValue ( in builder , in memberInfo , in offsetStr ) ;
40+ GenerateGetPrimitiveValueRef ( in builder , in memberInfo , in offsetStr ) ;
41+ GenerateGetPrimitiveValueOut ( in builder , in memberInfo , in offsetStr ) ;
4342
44- GenerateSetPrimitiveValue ( in builder , in memberInfo ) ;
45- GenerateSetPrimitiveValueFromPtr ( in builder , in memberInfo ) ;
46- GenerateSetPrimitiveValueFrom ( in builder , in memberInfo , in currentType ) ;
43+ GenerateSetPrimitiveValue ( in builder , in memberInfo , in offsetStr ) ;
44+ GenerateSetPrimitiveValueFromPtr ( in builder , in memberInfo , in offsetStr ) ;
45+ GenerateSetPrimitiveValueFrom ( in builder , in memberInfo , in currentType , in offsetStr ) ;
4746 }
4847 else
4948 {
50- GenerateGetСompositeValue ( in builder , in memberInfo , in currentType ) ;
51- GenerateSetСompositeValueFrom ( in builder , in memberInfo , in currentType ) ;
49+ GenerateGetСompositeValue ( in builder , in memberInfo , in currentType , in offsetStr ) ;
50+ GenerateSetСompositeValueFrom ( in builder , in memberInfo , in currentType , in offsetStr ) ;
5251 }
5352 }
5453
5554 GenerateCopyToPtr ( in builder , in typeInfo , in currentType ) ;
5655 GenerateCopyToValue ( in builder , in typeInfo , in currentType ) ;
5756 GenerateCopyToValueOut ( in builder , in typeInfo , in currentType ) ;
58- GenerateCopy ( in builder , in typeInfo ) ;
57+
58+ var sizeOfStr = typeInfo . IsRuntimeCalculatedSize ? $ "{ currentType . Name } Helper.SizeOf" : $ "{ typeInfo . Size } ";
59+ GenerateCopy ( in builder , in typeInfo , in sizeOfStr ) ;
60+
5961 GenerateEnd ( in builder ) ;
6062
6163 context . AddSource ( $ "{ currentType . Name } Helper.g.cs", builder . ToString ( ) ) ;
@@ -83,18 +85,24 @@ public unsafe static class {currentType.Name}Helper
8385" ) ;
8486 }
8587
86- private void GenerateSize (
88+ private void GenerateOffsetsAndSize (
8789 in StringBuilder builder ,
8890 in TypeInfo typeInfo
8991 )
9092 {
9193 builder . Append ( $@ "
92- public static nuint GetSize()
93- {{
94- return { typeInfo . Members . Sum ( s => s . Size ) + ( typeInfo . IsValueType ? 0 : 1 ) } ;
95- }}
94+ public static readonly nuint SizeOf = { typeInfo . SizeOf } ;
95+ " ) ;
9696
97+ foreach ( var memberInfo in typeInfo . Members )
98+ {
99+ if ( memberInfo . IsRuntimeOffsetCalculated )
100+ {
101+ builder . Append ( $@ "
102+ public static readonly nuint { memberInfo . MemberName } Offset = { memberInfo . OffsetStr } ;
97103" ) ;
104+ }
105+ }
98106 }
99107
100108 private void GenerateIsNullable (
@@ -113,66 +121,71 @@ public static bool IsNullable()
113121
114122 private void GenerateGetPtr (
115123 in StringBuilder builder ,
116- in MemberInfo memberInfo
124+ in MemberInfo memberInfo ,
125+ in string offsetStr
117126 )
118127 {
119128 builder . Append ( $@ "
120129 public static void* Get{ memberInfo . MemberName } Ptr(in void* ptr)
121130 {{
122- return (byte*)ptr + { memberInfo . Offset } ;
131+ return (byte*)ptr + { offsetStr } ;
123132 }}
124133
125134" ) ;
126135 }
127136
128137 private void GenerateGetPrimitiveValue (
129138 in StringBuilder builder ,
130- in MemberInfo memberInfo
139+ in MemberInfo memberInfo ,
140+ in string offsetStr
131141 )
132142 {
133143 builder . Append ( $@ "
134144 public static { memberInfo . TypeName } Get{ memberInfo . MemberName } Value(in void* ptr)
135145 {{
136- return *({ memberInfo . TypeName } *)((byte*)ptr + { memberInfo . Offset } );
146+ return *({ memberInfo . TypeName } *)((byte*)ptr + { offsetStr } );
137147 }}
138148" ) ;
139149 }
140150
141151 private void GenerateGetPrimitiveValueRef (
142152 in StringBuilder builder ,
143- in MemberInfo memberInfo
153+ in MemberInfo memberInfo ,
154+ in string offsetStr
144155 )
145156 {
146157 builder . Append ( $@ "
147158 public static void GetRef{ memberInfo . MemberName } Value(in void* ptr, ref { memberInfo . TypeName } item)
148159 {{
149- item = *({ memberInfo . TypeName } *)((byte*)ptr + { memberInfo . Offset } );
160+ item = *({ memberInfo . TypeName } *)((byte*)ptr + { offsetStr } );
150161 }}
151162" ) ;
152163 }
153164
154165 private void GenerateGetPrimitiveValueOut (
155166 in StringBuilder builder ,
156- in MemberInfo memberInfo
167+ in MemberInfo memberInfo ,
168+ in string offsetStr
157169 )
158170 {
159171 builder . Append ( $@ "
160172 public static void GetOut{ memberInfo . MemberName } Value(in void* ptr, out { memberInfo . TypeName } item)
161173 {{
162- item = *({ memberInfo . TypeName } *)((byte*)ptr + { memberInfo . Offset } );
174+ item = *({ memberInfo . TypeName } *)((byte*)ptr + { offsetStr } );
163175 }}
164176" ) ;
165177 }
166178
167179 private void GenerateSetPrimitiveValue (
168180 in StringBuilder builder ,
169- in MemberInfo memberInfo
181+ in MemberInfo memberInfo ,
182+ in string offsetStr
170183 )
171184 {
172185 builder . Append ( $@ "
173186 public static void Set{ memberInfo . MemberName } Value(in void* ptr, in { memberInfo . TypeName } value)
174187 {{
175- *({ memberInfo . TypeName } *)((byte*)ptr + { memberInfo . Offset } ) = value;
188+ *({ memberInfo . TypeName } *)((byte*)ptr + { offsetStr } ) = value;
176189 }}
177190
178191" ) ;
@@ -181,27 +194,29 @@ in MemberInfo memberInfo
181194 private void GenerateSetPrimitiveValueFrom (
182195 in StringBuilder builder ,
183196 in MemberInfo memberInfo ,
184- in INamedTypeSymbol currentType
197+ in INamedTypeSymbol currentType ,
198+ in string offsetStr
185199 )
186200 {
187201 builder . Append ( $@ "
188202 public static void Set{ memberInfo . MemberName } Value(in void* ptr, in { currentType . Name } value)
189203 {{
190- *({ memberInfo . TypeName } *)((byte*)ptr + { memberInfo . Offset } ) = value.{ memberInfo . MemberName } ;
204+ *({ memberInfo . TypeName } *)((byte*)ptr + { offsetStr } ) = value.{ memberInfo . MemberName } ;
191205 }}
192206
193207" ) ;
194208 }
195209
196210 private void GenerateSetPrimitiveValueFromPtr (
197211 in StringBuilder builder ,
198- in MemberInfo memberInfo
212+ in MemberInfo memberInfo ,
213+ in string offsetStr
199214 )
200215 {
201216 builder . Append ( $@ "
202217 public static void Set{ memberInfo . MemberName } Value(in void* ptr, in { memberInfo . TypeName } * valuePtr)
203218 {{
204- *({ memberInfo . TypeName } *)((byte*)ptr + { memberInfo . Offset } ) = *valuePtr;
219+ *({ memberInfo . TypeName } *)((byte*)ptr + { offsetStr } ) = *valuePtr;
205220 }}
206221
207222" ) ;
@@ -211,7 +226,8 @@ in MemberInfo memberInfo
211226 private void GenerateGetСompositeValue (
212227 in StringBuilder builder ,
213228 in MemberInfo memberInfo ,
214- in INamedTypeSymbol currentType
229+ in INamedTypeSymbol currentType ,
230+ in string offsetStr
215231 )
216232 {
217233 if ( memberInfo . IsValueType )
@@ -234,7 +250,7 @@ in INamedTypeSymbol currentType
234250 builder . Append ( $@ "
235251 { memberInfo . TypeName } result;
236252 Unsafe.SkipInit(out result);
237- { memberInfo . TypeName } Helper.CopyToValue((byte*)ptr + { memberInfo . Offset } , ref result);
253+ { memberInfo . TypeName } Helper.CopyToValue((byte*)ptr + { offsetStr } , ref result);
238254
239255 return result;
240256 }}
@@ -258,13 +274,13 @@ in INamedTypeSymbol currentType
258274 }
259275
260276 builder . Append ( $@ "
261- if(*((byte*)ptr + { memberInfo . Offset } ) == 0)
277+ if(*((byte*)ptr + { offsetStr } ) == 0)
262278 {{
263279 return null;
264280 }}
265281
266282 { memberInfo . TypeName } result = new { memberInfo . TypeName } ();
267- { memberInfo . TypeName } Helper.CopyToValue((byte*)ptr + { memberInfo . Offset } , ref result);
283+ { memberInfo . TypeName } Helper.CopyToValue((byte*)ptr + { offsetStr } , ref result);
268284 return result;
269285 }}
270286" ) ;
@@ -274,7 +290,8 @@ in INamedTypeSymbol currentType
274290 private void GenerateSetСompositeValueFrom (
275291 in StringBuilder builder ,
276292 in MemberInfo memberInfo ,
277- in INamedTypeSymbol currentType
293+ in INamedTypeSymbol currentType ,
294+ in string offsetStr
278295 )
279296 {
280297 if ( memberInfo . IsValueType )
@@ -294,7 +311,7 @@ in INamedTypeSymbol currentType
294311 }
295312
296313 builder . Append ( $@ "
297- { memberInfo . TypeName } Helper.CopyToPtr(value.{ memberInfo . MemberName } , (byte*)ptr + { memberInfo . Offset } );
314+ { memberInfo . TypeName } Helper.CopyToPtr(value.{ memberInfo . MemberName } , (byte*)ptr + { offsetStr } );
298315 }}
299316" ) ;
300317 }
@@ -317,11 +334,11 @@ in INamedTypeSymbol currentType
317334 builder . Append ( $@ "
318335 if(value.{ memberInfo . MemberName } == null)
319336 {{
320- *((byte*)ptr + { memberInfo . Offset } ) = 0;
337+ *((byte*)ptr + { currentType . Name } Helper. { memberInfo . MemberName } ) = 0;
321338 return;
322339 }}
323340
324- { memberInfo . TypeName } Helper.CopyToPtr(value.{ memberInfo . MemberName } , (byte*)ptr + { memberInfo . Offset } );
341+ { memberInfo . TypeName } Helper.CopyToPtr(value.{ memberInfo . MemberName } , (byte*)ptr + { offsetStr } );
325342 }}
326343" ) ;
327344 }
@@ -459,7 +476,8 @@ public static void CopyToValueOut(in void* ptr, out {currentType.Name} value)
459476
460477 private void GenerateCopy (
461478 in StringBuilder builder ,
462- in TypeInfo typeInfo
479+ in TypeInfo typeInfo ,
480+ in string sizeOfStr
463481 )
464482 {
465483 if ( typeInfo . IsValueType )
@@ -470,8 +488,8 @@ public static void Copy(in void* ptrSource, in void* ptrDest)
470488 Buffer.MemoryCopy(
471489 ptrSource,
472490 ptrDest,
473- { typeInfo . Members . Sum ( s => s . Size ) + ( typeInfo . IsValueType ? 0 : 1 ) } ,
474- { typeInfo . Members . Sum ( s => s . Size ) + ( typeInfo . IsValueType ? 0 : 1 ) }
491+ { sizeOfStr } ,
492+ { sizeOfStr }
475493 );
476494 }}
477495" ) ;
@@ -490,8 +508,8 @@ public static void Copy(in void* ptrSource, in void* ptrDest)
490508 Buffer.MemoryCopy(
491509 ptrSource,
492510 ptrDest,
493- { typeInfo . Members . Sum ( s => s . Size ) + ( typeInfo . IsValueType ? 0 : 1 ) } ,
494- { typeInfo . Members . Sum ( s => s . Size ) + ( typeInfo . IsValueType ? 0 : 1 ) }
511+ { sizeOfStr } ,
512+ { sizeOfStr }
495513 );
496514 }}
497515" ) ;
0 commit comments