@@ -551,6 +551,26 @@ def __exit__(self, type, value, traceback):
551551 self .container .add_named_type (self .name , self .type .immutable_copy ())
552552
553553
554+ class TypeBuilderAttributes (dict ):
555+ def __init__ (self , builder , * args ):
556+ super (TypeBuilderAttributes , self ).__init__ (* args )
557+ self ._builder = builder
558+
559+ def __setitem__ (self , key : str , value : str ):
560+ if not isinstance (key , str ):
561+ raise TypeError ("Type attribute key must be a string" )
562+ if not isinstance (value , str ):
563+ raise TypeError ("Type attribute value must be a string" )
564+ core .BNSetTypeBuilderAttribute (self ._builder ._handle , key , value )
565+ super (TypeBuilderAttributes , self ).__setitem__ (key , value )
566+
567+ def __delitem__ (self , key : str ):
568+ if not isinstance (key , str ):
569+ raise TypeError ("Type attribute key must be a string" )
570+ core .BNRemoveTypeBuilderAttribute (self ._builder ._handle , key )
571+ super (TypeBuilderAttributes , self ).__delitem__ (key )
572+
573+
554574class TypeBuilder :
555575 """
556576 All TypeBuilder objects should not be instantiated directly but created via ``.create`` APIs.
@@ -855,6 +875,34 @@ def signed(self, value: BoolWithConfidenceType) -> None:
855875 def children (self ) -> List ['TypeBuilder' ]:
856876 return []
857877
878+ @property
879+ def attributes (self ) -> Dict [str , str ]:
880+ """Attribute names and their values"""
881+ count = ctypes .c_ulonglong ()
882+ attributes = core .BNGetTypeBuilderAttributes (self ._handle , count )
883+ result = dict ()
884+ for i in range (count .value ):
885+ result [attributes [i ].name ] = attributes [i ].value
886+ core .BNFreeTypeAttributeList (attributes , count .value )
887+ return TypeBuilderAttributes (self , result )
888+
889+ @attributes .setter
890+ def attributes (self , values : Dict [str , str ]) -> None :
891+ if not isinstance (values , dict ):
892+ raise TypeError ("Attributes must be a dictionary" )
893+ attributes = (core .BNTypeAttribute * len (values ))()
894+ i = 0
895+ for name , value in values .items ():
896+ if not isinstance (name , str ):
897+ raise TypeError ("Attribute names must be strings" )
898+ if not isinstance (value , str ):
899+ raise TypeError ("Attribute values must be strings" )
900+ attributes [i ].name = name
901+ attributes [i ].value = value
902+ i += 1
903+ core .BNSetTypeBuilderAttributeList (self ._handle , attributes , len (values ))
904+
905+
858906class VoidBuilder (TypeBuilder ):
859907 @classmethod
860908 def create (cls , platform : Optional ['_platform.Platform' ] = None , confidence : int = core .max_confidence ) -> 'VoidBuilder' :
@@ -1940,6 +1988,17 @@ def altname(self) -> str:
19401988 """Alternative name for the type object"""
19411989 return core .BNGetTypeAlternateName (self ._handle )
19421990
1991+ @property
1992+ def attributes (self ) -> Dict [str , str ]:
1993+ """Attribute names and their values"""
1994+ count = ctypes .c_ulonglong ()
1995+ attributes = core .BNGetTypeAttributes (self ._handle , count )
1996+ result = dict ()
1997+ for i in range (count .value ):
1998+ result [attributes [i ].name ] = attributes [i ].value
1999+ core .BNFreeTypeAttributeList (attributes , count .value )
2000+ return result
2001+
19432002 def _to_core_struct (self ) -> core .BNTypeWithConfidence :
19442003 type_conf = core .BNTypeWithConfidence ()
19452004 type_conf .type = self ._handle
0 commit comments