@@ -21,6 +21,14 @@ static int GetInt(JToken token, string key)
2121 if ( v == null ) return 0 ;
2222 return v . ToObject < int > ( ) ;
2323 }
24+
25+ static int ? GetOptionalInt ( JToken token , string key )
26+ {
27+ var v = token [ key ] ;
28+ if ( v == null ) return null ;
29+ return v . ToObject < int > ( ) ;
30+ }
31+
2432 public void LoadFrom ( string directory )
2533 {
2634
@@ -92,7 +100,9 @@ public void LoadFrom(string directory)
92100 v [ "type" ] . ToString ( ) ,
93101 GetInt ( v , "size" ) ,
94102 v [ "template_type" ] ? . ToString ( ) ,
95- Enums ) ;
103+ Enums ,
104+ typeVariants : null ,
105+ GetOptionalInt ( v , "bitfield" ) ) ;
96106 } ) . Where ( tr => tr != null ) . ToArray ( ) ;
97107 return new TypeDefinition ( name , fields ) ;
98108 } ) . Where ( x => x != null ) . ToArray ( ) ;
@@ -302,12 +312,34 @@ class TypeDefinition
302312 {
303313 public string Name { get ; }
304314 public TypeReference [ ] Fields { get ; }
315+ public BitField [ ] BitFields { get ; }
305316
306317 public TypeDefinition ( string name , TypeReference [ ] fields )
307318 {
308319 Name = name ;
309320 Fields = fields ;
321+
322+ var bitFields = new List < BitField > ( ) ;
323+ int bitFieldStartI = - 1 ;
324+ for ( int i = 0 ; i < fields . Length ; i ++ )
325+ {
326+ if ( fields [ i ] . BitSize . HasValue && bitFieldStartI < 0 )
327+ bitFieldStartI = i ;
328+
329+ if ( ! fields [ i ] . BitSize . HasValue && bitFieldStartI >= 0 )
330+ {
331+ bitFields . Add ( new BitField ( bitFields . Count , fields [ bitFieldStartI ..i ] ) ) ;
332+ bitFieldStartI = - 1 ;
333+ }
334+ }
335+ if ( bitFieldStartI >= 0 )
336+ bitFields . Add ( new BitField ( bitFields . Count , fields [ bitFieldStartI ..] ) ) ;
337+ BitFields = bitFields . ToArray ( ) ;
310338 }
339+
340+ public BitField GetBitFieldContaining ( TypeReference field ) =>
341+ BitFields . FirstOrDefault ( bitField => bitField . Fields . Contains ( field ) )
342+ ?? throw new ArgumentException ( "Given is not part of any bit field" ) ;
311343 }
312344
313345 class TypeReference
@@ -319,17 +351,18 @@ class TypeReference
319351 public bool IsFunctionPointer { get ; }
320352 public string [ ] TypeVariants { get ; }
321353 public bool IsEnum { get ; }
354+ public int ? BitSize { get ; }
322355
323356 public TypeReference ( string name , string type , int asize , EnumDefinition [ ] enums )
324- : this ( name , type , asize , null , enums , null ) { }
357+ : this ( name , type , asize , null , enums , null , null ) { }
325358
326359 public TypeReference ( string name , string type , int asize , EnumDefinition [ ] enums , string [ ] typeVariants )
327- : this ( name , type , asize , null , enums , typeVariants ) { }
360+ : this ( name , type , asize , null , enums , typeVariants , null ) { }
328361
329362 public TypeReference ( string name , string type , int asize , string templateType , EnumDefinition [ ] enums )
330- : this ( name , type , asize , templateType , enums , null ) { }
363+ : this ( name , type , asize , templateType , enums , null , null ) { }
331364
332- public TypeReference ( string name , string type , int asize , string templateType , EnumDefinition [ ] enums , string [ ] typeVariants )
365+ public TypeReference ( string name , string type , int asize , string templateType , EnumDefinition [ ] enums , string [ ] typeVariants , int ? bitSize )
333366 {
334367 Name = name ;
335368 Type = type . Replace ( "const" , string . Empty ) . Trim ( ) ;
@@ -376,6 +409,8 @@ public TypeReference(string name, string type, int asize, string templateType, E
376409 TypeVariants = typeVariants ;
377410
378411 IsEnum = enums . Any ( t => t . Name == type || t . FriendlyName == type || TypeInfo . WellKnownEnums . Contains ( type ) ) ;
412+
413+ BitSize = bitSize ;
379414 }
380415
381416 private int ParseSizeString ( string sizePart , EnumDefinition [ ] enums )
@@ -419,6 +454,28 @@ public TypeReference WithVariant(int variantIndex, EnumDefinition[] enums)
419454 }
420455 }
421456
457+ class BitField
458+ {
459+ public string Name { get ; }
460+ public string Type { get ; }
461+ public TypeReference [ ] Fields { get ; }
462+
463+ public BitField ( int index , IEnumerable < TypeReference > fields )
464+ {
465+ Name = $ "_bitField_{ index } ";
466+ Fields = fields . ToArray ( ) ;
467+ Type = TypeInfo . GetTypeForBitfield ( fields . Sum ( f => f . BitSize . Value ) ) ;
468+ }
469+
470+ public int OffsetOf ( TypeReference field )
471+ {
472+ var fieldIndex = Array . IndexOf ( Fields , field ) ;
473+ if ( fieldIndex < 0 )
474+ throw new ArgumentException ( "Given field is not part of the bit field" ) ;
475+ return Fields . Take ( fieldIndex ) . Sum ( f => f . BitSize . Value ) ;
476+ }
477+ }
478+
422479 class FunctionDefinition
423480 {
424481 public string Name { get ; }
0 commit comments