@@ -22,6 +22,14 @@ static int GetInt(JToken token, string key)
2222 if ( v == null ) return 0 ;
2323 return v . ToObject < int > ( ) ;
2424 }
25+
26+ static int ? GetOptionalInt ( JToken token , string key )
27+ {
28+ var v = token [ key ] ;
29+ if ( v == null ) return null ;
30+ return v . ToObject < int > ( ) ;
31+ }
32+
2533 public void LoadFrom ( string directory )
2634 {
2735
@@ -93,7 +101,9 @@ public void LoadFrom(string directory)
93101 v [ "type" ] . ToString ( ) ,
94102 GetInt ( v , "size" ) ,
95103 v [ "template_type" ] ? . ToString ( ) ,
96- Enums ) ;
104+ Enums ,
105+ typeVariants : null ,
106+ GetOptionalInt ( v , "bitfield" ) ) ;
97107 } ) . Where ( tr => tr != null ) . ToArray ( ) ;
98108 return new TypeDefinition ( name , fields ) ;
99109 } ) . Where ( x => x != null ) . ToArray ( ) ;
@@ -336,12 +346,34 @@ class TypeDefinition
336346 {
337347 public string Name { get ; }
338348 public TypeReference [ ] Fields { get ; }
349+ public BitField [ ] BitFields { get ; }
339350
340351 public TypeDefinition ( string name , TypeReference [ ] fields )
341352 {
342353 Name = name ;
343354 Fields = fields ;
355+
356+ var bitFields = new List < BitField > ( ) ;
357+ int bitFieldStartI = - 1 ;
358+ for ( int i = 0 ; i < fields . Length ; i ++ )
359+ {
360+ if ( fields [ i ] . BitSize . HasValue && bitFieldStartI < 0 )
361+ bitFieldStartI = i ;
362+
363+ if ( ! fields [ i ] . BitSize . HasValue && bitFieldStartI >= 0 )
364+ {
365+ bitFields . Add ( new BitField ( bitFields . Count , fields [ bitFieldStartI ..i ] ) ) ;
366+ bitFieldStartI = - 1 ;
367+ }
368+ }
369+ if ( bitFieldStartI >= 0 )
370+ bitFields . Add ( new BitField ( bitFields . Count , fields [ bitFieldStartI ..] ) ) ;
371+ BitFields = bitFields . ToArray ( ) ;
344372 }
373+
374+ public BitField GetBitFieldContaining ( TypeReference field ) =>
375+ BitFields . FirstOrDefault ( bitField => bitField . Fields . Contains ( field ) )
376+ ?? throw new ArgumentException ( "Given is not part of any bit field" ) ;
345377 }
346378
347379 class TypeReference
@@ -353,17 +385,18 @@ class TypeReference
353385 public bool IsFunctionPointer { get ; }
354386 public string [ ] TypeVariants { get ; }
355387 public bool IsEnum { get ; }
388+ public int ? BitSize { get ; }
356389
357390 public TypeReference ( string name , string type , int asize , EnumDefinition [ ] enums )
358- : this ( name , type , asize , null , enums , null ) { }
391+ : this ( name , type , asize , null , enums , null , null ) { }
359392
360393 public TypeReference ( string name , string type , int asize , EnumDefinition [ ] enums , string [ ] typeVariants )
361- : this ( name , type , asize , null , enums , typeVariants ) { }
394+ : this ( name , type , asize , null , enums , typeVariants , null ) { }
362395
363396 public TypeReference ( string name , string type , int asize , string templateType , EnumDefinition [ ] enums )
364- : this ( name , type , asize , templateType , enums , null ) { }
397+ : this ( name , type , asize , templateType , enums , null , null ) { }
365398
366- public TypeReference ( string name , string type , int asize , string templateType , EnumDefinition [ ] enums , string [ ] typeVariants )
399+ public TypeReference ( string name , string type , int asize , string templateType , EnumDefinition [ ] enums , string [ ] typeVariants , int ? bitSize )
367400 {
368401 Name = name ;
369402 Type = type . Replace ( "const" , string . Empty ) . Trim ( ) ;
@@ -410,6 +443,8 @@ public TypeReference(string name, string type, int asize, string templateType, E
410443 TypeVariants = typeVariants ;
411444
412445 IsEnum = enums . Any ( t => t . Names . Contains ( type ) || t . FriendlyNames . Contains ( type ) || TypeInfo . WellKnownEnums . Contains ( type ) ) ;
446+
447+ BitSize = bitSize ;
413448 }
414449
415450 private int ParseSizeString ( string sizePart , EnumDefinition [ ] enums )
@@ -453,6 +488,28 @@ public TypeReference WithVariant(int variantIndex, EnumDefinition[] enums)
453488 }
454489 }
455490
491+ class BitField
492+ {
493+ public string Name { get ; }
494+ public string Type { get ; }
495+ public TypeReference [ ] Fields { get ; }
496+
497+ public BitField ( int index , IEnumerable < TypeReference > fields )
498+ {
499+ Name = $ "_bitField_{ index } ";
500+ Fields = fields . ToArray ( ) ;
501+ Type = TypeInfo . GetTypeForBitfield ( fields . Sum ( f => f . BitSize . Value ) ) ;
502+ }
503+
504+ public int OffsetOf ( TypeReference field )
505+ {
506+ var fieldIndex = Array . IndexOf ( Fields , field ) ;
507+ if ( fieldIndex < 0 )
508+ throw new ArgumentException ( "Given field is not part of the bit field" ) ;
509+ return Fields . Take ( fieldIndex ) . Sum ( f => f . BitSize . Value ) ;
510+ }
511+ }
512+
456513 class FunctionDefinition
457514 {
458515 public string Name { get ; }
0 commit comments