o
    Žõ±j‘Ø  ã                   @   sÈ  d dl Z d dlZd dlZd dlZd dlZd dlZd dlZd dlm	Z	 d dl
mZ zd dlmZ W n ey;   eZY nw ejdkZerGeZeZdZdZdZd	Zd
ZdZdZdZdZdZdZ dZ!dZ"dZ#dZ$dZ%ej&ej' ej( d Z)dZ*G dd„ de+ƒZ,G dd„ de,ƒZ-G dd„ de,ƒZ.G dd„ de,ƒZ/G d d!„ d!e,ƒZ0d"d#„ Z1G d$d%„ d%e2ƒZ3G d&d'„ d'e2ƒZ4G d(d)„ d)e4ƒZ5G d*d+„ d+e2ƒZ6G d,d-„ d-e2ƒZ7G d.d/„ d/e2ƒZ8G d0d1„ d1e2ƒZ9G d2d3„ d3e9ƒZ:G d4d5„ d5e9ƒZ;G d6d7„ d7e2ƒZ<G d8d9„ d9e2ƒZ=G d:d;„ d;e9ƒZ>G d<d=„ d=e:ƒZ?G d>d?„ d?e:ƒZ@G d@dA„ dAe:ƒZAG dBdC„ dCe:ƒZBG dDdE„ dEe:ƒZCG dFdG„ dGe2ƒZDG dHdI„ dIe:ƒZEG dJdK„ dKe:ƒZFG dLdM„ dMe:ƒZGdNdO„ ZdPdQ„ ZHG dRdS„ dSe2ƒZIdYdUdV„ZJdZdWdX„ZKdS )[é    N)ÚBytesIO)ÚOrderedDict)Úbytes)é   Fz[1;31mz[1;32mz[1;33mz[1;34mz[1;35mz[1;36mz[1;37mz[1;0mz[1;41m[1;37mz[1;42m[1;37mz[1;43m[1;37mz[1;44m[1;37mz[1;45m[1;37mz[1;46m[1;37mz[1;47m[1;30mú ak  
class {name}(Structure):
    def __init__(self, cstruct, structure, source=None):
        self.structure = structure
        self.source = source
        super({name}, self).__init__(cstruct, structure.name, structure.fields)

    def _read(self, stream):
        r = OrderedDict()
        sizes = {{}}
        bitreader = BitBuffer(stream, self.cstruct.endian)

{read_code}

        return Instance(self, r, sizes)

    def add_fields(self, name, type_, offset=None):
        raise NotImplementedError("Can't add fields to a compiled structure")

    def __repr__(self):
        return '<Structure {name} +compiled>'
c                   @   ó   e Zd ZdS )ÚErrorN©Ú__name__Ú
__module__Ú__qualname__© r   r   ú›/root/aizidognhua/tmp/workspace/projects/ec89d86c-575f-41c9-af57-ac45cbdbf775/venv/lib/python3.10/site-packages/msldap/external/bloodhoundpy/lib/cstruct.pyr   [   ó    r   c                   @   r   )ÚParserErrorNr	   r   r   r   r   r   _   r   r   c                   @   r   )ÚCompilerErrorNr	   r   r   r   r   r   c   r   r   c                   @   r   )ÚResolveErrorNr	   r   r   r   r   r   g   r   r   c                   @   r   )ÚNullPointerDereferenceNr	   r   r   r   r   r   k   r   r   c                 O   s&   t sd S t| j|i |¤Žtjd� d S )N)Úfile)ÚDEBUGÚprintÚformatÚsysÚstderr)ÚlineÚargsÚkwargsr   r   r   Úlogo   s   r   c                   @   sT   e Zd ZdZdZddd„Zddd	„Zddd„Zddd„Zdd„ Z	dd„ Z
dd„ Zd
S )Úcstructz³Main class of cstruct. All types are registered in here.

    Args:
        endian: The endianness to use when parsing.
        pointer: The pointer type to use for Pointers.
    é   ú<Úuint64c                 C   s–  || _ i | _i | _i dd“dd“dd“dd“dd	“d
d“dd“dd“dd“dd	“dd“dd“dd	“dd“dd“dd“dd“i dd“dt| dddƒ“dt| dddƒ“dt| dddƒ“d	t| d	dd ƒ“dt| dd!d"ƒ“dt| dd!d#ƒ“dt| dd$d%ƒ“dt| dd$d&ƒ“d't| d'd!d(ƒ“d)t| d)d$d*ƒ“d+t| ƒ“d,t| ƒ“d-t| d-d.d/ƒ“d0t| d0d.d1ƒ“d2t| d2d3d/ƒ“d4t| d4d3d1ƒ“¥d5tƒ i¥| _|  	|¡| _
d S )6NÚbyteÚint8ÚubyteÚuint8ÚucharÚshortÚint16ÚushortÚuint16ÚlongÚint32ÚulongÚuint32Úulong64r!   Úu1Úu2Úu4Úu8ÚwordÚdwordÚlonglongÚint64Ú	ulonglongÚintzunsigned intr   ÚbÚBé   ÚhÚHé   ÚiÚIé   ÚqÚQÚfloatÚfÚdoubleÚdÚcharÚwcharÚint24r   TÚuint24FÚint48é   Úuint48Úvoid)ÚendianÚconstsÚlookupsÚ
PackedTypeÚCharTypeÚ	WcharTypeÚBytesIntegerÚVoidTypeÚtypedefsÚresolveÚpointer)ÚselfrQ   r[   r   r   r   Ú__init__€   s–   ÿþýüûúùø
öõôóñðîíëêèçæåäãâá à!ß"Þ#Ý%Û&Ú'Ù(Ø*Ö-zcstruct.__init__Fc                 C   s4   |  ¡ }|s|  ¡ | jv rtd| ƒ‚|| j|< dS )a"  Add a type or type reference.

        Args:
            name: Name of the type to be added.
            t: The type to be added. Can be a str reference to another type
                or a compatible type class.

        Raises:
            ValueError: If the type already exists.
        zDuplicate type: %sN)ÚlowerrY   Ú
ValueError)r\   ÚnameÚtÚreplacer   r   r   Úaddtype´   s   zcstruct.addtypeNc                 K   s2   |pt j}|t jkrt| fi |¤Ž}| |¡ dS )a  Parse structures from the given definitions using the given definition type.

        Definitions can be parsed using different parsers. Currently, there's
        only one supported parser - DEF_CSTYLE. Parsers can add types and
        modify this cstruct instance. Arguments can be passed to parsers
        using kwargs.

        Args:
            s: The definition to parse.
            deftype: The definition type to parse the definitions with.
            **kwargs: Keyword arguments for parsers.
        N)r   Ú
DEF_CSTYLEÚCStyleParserÚparse)r\   ÚsÚdeftyper   Úparserr   r   r   ÚloadÅ   s   

zcstruct.loadc                 K   sH   t |dƒ�}| j| ¡ |fi |¤Ž W d  ƒ dS 1 sw   Y  dS )a:  Load structure definitions from a file.

        The given path will be read and parsed using the .load() function.

        Args:
            s: The path to load definitions from.
            deftype: The definition type to parse the definitions with.
            **kwargs: Keyword arguments for parsers.
        ÚrN)Úopenrj   Úread)r\   rg   rh   r   Úfhr   r   r   ÚloadfileÙ   s   
"ÿzcstruct.loadfilec                 C   s   |   |¡ |¡S )zÃParse data using a given type.

        Args:
            name: Type name to read.
            s: File-like object or byte string to parse.

        Returns:
            The parsed data.
        )rZ   rm   )r\   r`   rg   r   r   r   rm   æ   s   
zcstruct.readc                 C   sf   |}t |tƒs	|S tdƒD ]}| ¡ | jvrtd| ƒ‚| j| ¡  }t |tƒs,|  S qtd| ƒ‚)a~  Resolve a type name to get the actual type object.

        Types can be referenced using different names. When we want
        the actual type object, we need to resolve these references.

        Args:
            name: Type name to resolve.

        Returns:
            The resolved type object.

        Raises:
            ResolveError: If the type can't be resolved.
        é
   zUnknown type %sz0Recursion limit exceeded while resolving type %s)Ú
isinstanceÚstrÚxranger^   rY   r   )r\   r`   ra   r@   r   r   r   rZ   ò   s   

ÿzcstruct.resolvec                 C   s<   |  ¡ | jv r| j|  ¡  S || jv r| j| S td| ƒ‚)NzInvalid Attribute: %s)r^   rY   rR   ÚAttributeError©r\   Úattrr   r   r   Ú__getattr__  s
   

zcstruct.__getattr__)r    r!   )F©N)r
   r   r   Ú__doc__rd   r]   rc   rj   ro   rm   rZ   rw   r   r   r   r   r   v   s    

4

r   c                   @   s    e Zd ZdZdd„ Zdd„ ZdS )ÚParserz[Base class for definition parsers.

    Args:
        cstruct: An instance of cstruct.
    c                 C   ó
   || _ d S rx   ©r   ©r\   r   r   r   r   r]   !  ó   
zParser.__init__c                 C   ó   t ƒ ‚)z”This function should parse definitions to cstruct types.

        Args:
            data: Data to parse definitions from, usually a string.
        ©ÚNotImplementedError©r\   Údatar   r   r   rf   $  s   zParser.parseN)r
   r   r   ry   r]   rf   r   r   r   r   rz     s    rz   c                       sR   e Zd ZdZd‡ fdd„	Zdd„ Zdd„ Zd	d
„ Zdd„ Zdd„ Z	dd„ Z
‡  ZS )re   z£Definition parser for C-like structure syntax.

    Args:
        cstruct: An instance of cstruct
        compiled: Whether structs should be compiled or not.
    Tc                    s   || _ tt| ƒ |¡ d S rx   )ÚcompiledÚsuperre   r]   )r\   r   r„   ©Ú	__class__r   r   r]   5  ó   zCStyleParser.__init__c                 C   s2   |   |¡ |  |¡ |  |¡ |  || jj¡ d S rx   )Ú
_constantsÚ_enumsÚ_structsÚ_lookupsr   rR   r‚   r   r   r   rf   :  s   


zCStyleParser.parsec              
   C   sj   t  d|¡}|D ]*}| ¡ }|d  d¡d }zt |¡}W n ttfy)   Y nw || jj	|d < qd S )Nz5#define\s+(?P<name>[^\s]+)\s+(?P<value>[^\r\n]+)\s*\nÚvalueú//r   r`   )
ÚreÚfinditerÚ	groupdictÚrsplitÚastÚliteral_evalr_   ÚSyntaxErrorr   rR   )r\   rƒ   rk   ra   rH   Úvr   r   r   r‰   @  s   ÿ÷zCStyleParser._constantsc                 C   sð   t  d|¡}|D ]m}| ¡ }d}i }|d  d¡D ];}| d¡\}}}	| d¡D ]+}
|
 d¡\}}}| ¡ }| ¡ }|s=q(|sB|}n	t| j|ƒ i ¡}|d }|||< q(q|d	 s]d
|d	< t	| j|d | j 
|d	 ¡|ƒ}| j |j|¡ qd S )NzOenum\s+(?P<name>[^\s:{]+)\s*(:\s*(?P<type>[^\s]+)\s*)?\{(?P<values>[^}]+)\}\s*;r   ÚvaluesÚ
rŽ   ú,ú=r   Útyper.   r`   )r�   r�   r‘   ÚsplitÚ	partitionÚstripÚ
Expressionr   ÚevaluateÚEnumrZ   rc   r`   )r\   rƒ   rk   ra   rH   Únextvalr—   r   ÚsepÚcommentr–   ÚkeyÚvalÚenumr   r   r   rŠ   M  s:   þ
óÿäzCStyleParser._enumsc           	      C   s$  t | jƒ}t d|¡}|D ]‚}| ¡ }|d r|d }n|d r.|d  ¡  d¡d  ¡ }ntdƒ‚|d dkr[|  |d	 d
d…  ¡ ¡}t	| j||ƒ}|d dksU| j
rZ| |¡}n|d dkrf|d }nq|d rt| j |d |¡ |d r�|d  ¡  d¡D ]}| ¡ }| j ||¡ q�qd S )Nz�(#(?P<flags>(?:compile))\s+)?((?P<typedef>typedef)\s+)?(?P<type>[^\s]+)\s+(?P<name>[^\s]+)?(?P<fields>\s*\{[^}]+\}(?P<defs>\s+[^;\n]+)?)?\s*;r`   Údefsr™   r   zNo name for structr›   ÚstructÚfieldsr   éÿÿÿÿÚflagsÚcompileÚtypedef)ÚCompilerr   r�   r�   r‘   rž   rœ   r   Ú_parse_fieldsÚ	Structurer„   r­   rc   )	r\   rƒ   Úcompilerrk   ra   rH   r`   ÚstÚtdr   r   r   r‹   p  s:   
þ

€
€æzCStyleParser._structsc           	   	   C   s  t  d|¡}g }|D ]€}| ¡ }|d  d¡rq
| j |d ¡}|d  dd¡ dd¡|d< |d d ur\|d dkr=d }nt| j|d ƒ}z| ¡ }W n	 t	yT   Y nw t
| j||ƒ}|d  d	¡rs|d d
d … |d< t| j|ƒ}t|d ||d r‚t|d ƒnd ƒ}| |¡ q
|S )NzW(?P<type>[^\s]+)\s+(?P<name>[^\s\[:]+)(\s*:\s*(?P<bits>\d+))?(\[(?P<count>[^;\n]*)\])?;r›   rŽ   r`   ú(Ú ú)ÚcountÚ*r   Úbits)r�   r�   r‘   Ú
startswithr   rZ   rb   rŸ   r    Ú	ExceptionÚArrayÚPointerÚFieldr9   Úappend)	r\   rg   rª   rk   rF   rH   Útype_r¸   Úfieldr   r   r   r°   ’  s6   þÿ$zCStyleParser._parse_fieldsc                    sR   t  d|¡}|D ]}t | d¡¡}t‡ fdd„| ¡ D ƒƒˆ jj| d¡< qd S )Nz#\$(?P<name>[^\s]+) = ({[^}]+})\w*\nr<   c                    s    g | ]\}}ˆ j j| |f‘qS r   )r   rR   ©Ú.0Úkr–   ©r\   r   r   Ú
<listcomp>¾  ó     z)CStyleParser._lookups.<locals>.<listcomp>r   )	r�   r�   r“   r”   ÚgroupÚdictÚitemsr   rS   )r\   rƒ   rR   rk   ra   rH   r   rÆ   r   rŒ   ¸  s   ÿþzCStyleParser._lookups)T)r
   r   r   ry   r]   rf   r‰   rŠ   r‹   r°   rŒ   Ú__classcell__r   r   r†   r   re   -  s    #"&re   c                   @   sb   e Zd ZdZddd„Zdd„ Zdd„ Zd	d
„ Zdd„ Zdd„ Z	dd„ Z
dd„ Zdd„ Zdd„ ZdS )ÚInstancezHolds parsed structure data.Nc                 C   s.   t  | d|¡ t  | d|¡ t  | d|¡ d S )NÚ_typeÚ_valuesÚ_sizes)ÚobjectÚ__setattr__)r\   rÁ   r—   Úsizesr   r   r   r]   Å  s   zInstance.__init__c                 C   s   | j d  || ¡S )zÀWrite this structure to a writable file-like object.

        Args:
            fh: File-like objects that supports writing.

        Returns:
            The amount of bytes written.
        rÎ   )Ú__dict__Úwrite)r\   rn   r   r   r   rÕ   Ê  s   	zInstance.writec                 C   s   t ƒ }|  |¡ | ¡ S )zmDump this structure to a byte string.

        Returns:
            The raw bytes of this structure.
        )r   rÕ   Úgetvalue)r\   rg   r   r   r   ÚdumpsÕ  s   
zInstance.dumpsc                 C   s*   || j d jvrtd| ƒ‚| j d | S ©NrÎ   zInvalid attribute: %rrÏ   ©rÔ   Úlookuprt   ru   r   r   r   rw   ß  s   zInstance.__getattr__c                 C   s.   || j d jvrtd| ƒ‚|| j d |< d S rØ   rÙ   )r\   rv   r�   r   r   r   rÒ   å  s   zInstance.__setattr__c                 C   ó   | j d | S ©NrÏ   ©rÔ   )r\   Úitemr   r   r   Ú__getitem__ë  ó   zInstance.__getitem__c                 C   s   || j d v S rÜ   rÝ   ru   r   r   r   Ú__contains__î  rà   zInstance.__contains__c                 C   s.   d| j d jd dd„ | j d  ¡ D ƒ¡f S )Nz<%s %s>rÎ   z, c                 S   s6   g | ]\}}d |t |ttfƒrt|ƒnt|ƒf ‘qS )z%s=%s)rq   r9   r+   ÚhexÚreprrÃ   r   r   r   rÇ   õ  s    $ÿÿz%Instance.__repr__.<locals>.<listcomp>rÏ   )rÔ   r`   ÚjoinrË   rÆ   r   r   r   Ú__repr__ñ  s   
þÿþzInstance.__repr__c                 C   ó   t |  ¡ ƒS rx   )Úlenr×   rÆ   r   r   r   Ú__len__ü  ó   zInstance.__len__c                 C   rÛ   )NrÐ   rÝ   )r\   rÂ   r   r   r   Ú_sizeÿ  rà   zInstance._sizerx   )r
   r   r   ry   r]   rÕ   r×   rw   rÒ   rß   rá   rå   rè   rê   r   r   r   r   rÍ   Â  s    

rÍ   c                   @   s@   e Zd ZdZdd„ Zdd„ Zdd„ Zdd	„ Zd
d„ Zdd„ Z	dS )ÚPointerInstancezDLike the Instance class, but for structures referenced by a pointer.c                 C   s"   || _ || _|| _|| _d | _d S rx   )Ú_streamrÎ   Ú_addrÚ_ctxÚ_value)r\   ra   ÚstreamÚaddrÚctxr   r   r   r]     s
   
zPointerInstance.__init__c                 C   sˆ   t d| j| jƒ | jdkrtƒ ‚| jd u rA| j ¡ }| j | j¡ t| jt	ƒr1| j 
| j| j¡}n| j 
| j¡}| j |¡ || _| jS )Nz)Dereferencing pointer -> 0x{:016x} [{!r}]r   )r   rí   rì   r   rï   ÚtellÚseekrq   rÎ   r½   Ú_readrî   )r\   Úposrk   r   r   r   Ú_get  s   


zPointerInstance._getc                 C   s   t |  ¡ |ƒS rx   )Úgetattrr÷   ru   r   r   r   rw     rà   zPointerInstance.__getattr__c                 C   ræ   rx   )rr   r÷   rÆ   r   r   r   Ú__str__!  ré   zPointerInstance.__str__c                 C   s
   | j dkS ©Nr   )rí   rÆ   r   r   r   Ú__nonzero__$  r~   zPointerInstance.__nonzero__c                 C   ó   d  | j| j¡S )Nz<Pointer {!r} @ 0x{:x}>)r   rÎ   rí   rÆ   r   r   r   rå   '  ó   zPointerInstance.__repr__N)
r
   r   r   ry   r]   r÷   rw   rù   rû   rå   r   r   r   r   rë     s    rë   c                
   @   s†   e Zd ZdZddd„ fddd„ fddd„ fd	d
d„ fddd„ fddd„ fddd„ fddd„ fgZdd„ Zddd„Zdd„ Zdd„ ZdS )rŸ   z9Expression parser for simple calculations in definitions.ú+c                 C   s   | | S rx   r   ©Úar:   r   r   r   Ú<lambda>/  ó    zExpression.<lambda>ú-c                 C   s   | | S rx   r   rÿ   r   r   r   r  0  r  r¹   c                 C   s   | | S rx   r   rÿ   r   r   r   r  1  r  ú/c                 C   s   | | S rx   r   rÿ   r   r   r   r  2  r  ú&c                 C   s   | |@ S rx   r   rÿ   r   r   r   r  3  r  ú|c                 C   s   | |B S rx   r   rÿ   r   r   r   r  4  r  z>>c                 C   s   | |? S rx   r   rÿ   r   r   r   r  5  r  z<<c                 C   s   | |> S rx   r   rÿ   r   r   r   r  6  r  c                 C   ó   || _ || _d S rx   )r   Úexpr)r\   r   r  r   r   r   r]   9  ó   
zExpression.__init__Nc                 C   s¤   |r|ni }d}g }d}t t| jƒƒD ]8}| j| dkr(|d7 }| |¡ d}q| j| dkrD|d8 }|  ||¡}| ¡ }|t|ƒ7 }q|| j| 7 }q|  ||¡S )Nr   r¶   rµ   r   r·   )rs   rç   r  rÀ   Úevaluate_partÚpoprr   )r\   ÚcontextÚlevelÚlevelsÚbufr@   r¦   r   r   r   r    =  s$   
zExpression.evaluatec                 C   sš   |  ¡ }| jD ]#}|d |v r*| |d d¡\}}|d |  ||¡|  ||¡ƒ  S q||v r3|| S | d¡r=t|dƒS || jjv rI| jj| S t|ƒS )Nr   r   Ú0xé   )rž   Ú	operatorsr’   r
  r»   r9   r   rR   )r\   Úer–   Úor   r:   r   r   r   r
  U  s   
"þ

zExpression.evaluate_partc                 C   ó   | j S rx   ©r  rÆ   r   r   r   rå   h  ó   zExpression.__repr__rx   )	r
   r   r   ry   r  r]   r    r
  rå   r   r   r   r   rŸ   +  s    







ø
rŸ   c                   @   sˆ   e Zd ZdZdd„ Zdd„ Zdd„ Zdd	„ Zd
d„ Zdd„ Z	dd„ Z
dd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zd S )!ÚBaseTypez$Base class for cstruct type classes.c                 C   r{   rx   r|   r}   r   r   r   r]   o  r~   zBaseType.__init__c                 C   s   t |ƒ}|  |¡S )zÃParse the given data according to the type that implements this class.

        Args:
            data: Byte string to parse.

        Returns:
            The parsed value of this type.
        )r   rõ   r‚   r   r   r   Úreadsr  s   	
zBaseType.readsc                 C   s   t ƒ }|  ||¡ | ¡ S )z°Dump the given data according to the type that implements this class.

        Args:
            data: Data to dump.

        Returns:
            The resulting bytes.
        )r   Ú_writerÖ   )r\   rƒ   Úoutr   r   r   r×   ~  s   	zBaseType.dumpsc                 O   s$   t |tttfƒr|  |¡S |  |¡S )zéParse the given data according to the type that implements this class.

        Args:
            obj: Data to parse. Can be a (byte) string or a file-like object.

        Returns:
            The parsed value of this type.
        )rq   rr   r   Únewbytesr  rõ   )r\   Úobjr   r   r   r   r   rm   ‹  s   	

zBaseType.readc                 C   ó   |   ||¡S )a  Write the given data to a writable file-like object according to the
        type that implements this class.

        Args:
            stream: Writable file-like object to write to.
            data: Data to write.

        Returns:
            The amount of bytes written.
        ©r  ©r\   rð   rƒ   r   r   r   rÕ   ™  s   zBaseType.writec                 C   r   rx   r€   ©r\   rð   r   r   r   rõ   ¦  r  zBaseType._readc                    s   ‡ ‡fdd„t |ƒD ƒS )Nc                    s   g | ]}ˆ   ˆ¡‘qS r   )rõ   ©rÄ   r@   r!  r   r   rÇ   ª  ó    z(BaseType._read_array.<locals>.<listcomp>)rs   ©r\   rð   r¸   r   r!  r   Ú_read_array©  ó   zBaseType._read_arrayc                 C   r   rx   r€   r!  r   r   r   Ú_read_0¬  r  zBaseType._read_0c                 C   r   rx   r€   r   r   r   r   r  ¯  r  zBaseType._writec                 C   s"   d}|D ]
}||   ||¡7 }q|S rú   r  )r\   rð   rƒ   Únumr@   r   r   r   Ú_write_array²  s   zBaseType._write_arrayc                 C   r   rx   r€   r   r   r   r   Ú_write_0¸  r  zBaseType._write_0c                 C   r   )z$Return a default value of this type.r€   rÆ   r   r   r   Údefault»  ó   zBaseType.defaultc                 C   r   )z$Return a default array of this type.r€   rÆ   r   r   r   Údefault_array¿  r,  zBaseType.default_arrayc                 C   s   t | j| |ƒS rx   )r½   r   ©r\   r¸   r   r   r   rß   Ã  rà   zBaseType.__getitem__c                 O   sJ   t |ƒdkr| j|i |¤ŽS |  ¡ }|r#| ¡ D ]
\}}t|||ƒ q|S rú   )rç   rm   r+  rË   Úsetattr)r\   r   r   rk   rÅ   r–   r   r   r   Ú__call__Æ  s   zBaseType.__call__N)r
   r   r   ry   r]   r  r×   rm   rÕ   rõ   r%  r'  r  r)  r*  r+  r-  rß   r0  r   r   r   r   r  l  s"    r  c                       s2   e Zd ZdZd
‡ fdd„	Zdd„ Zdd	„ Z‡  ZS )ÚRawTypez3Base class for raw types that have a name and size.Nr   c                    s    || _ || _tt| ƒ |¡ d S rx   )r`   Úsizer…   r1  r]   )r\   r   r`   r2  r†   r   r   r]   Õ  ó   zRawType.__init__c                 C   r  rx   ©r2  rÆ   r   r   r   rè   Ú  r  zRawType.__len__c                 C   s   | j r| j S t | ¡S rx   )r`   r  rå   rÆ   r   r   r   rå   Ý  s   
zRawType.__repr__rú   )r
   r   r   ry   r]   rè   rå   rÌ   r   r   r†   r   r1  Ò  s
    r1  c                       sn   e Zd ZdZd‡ fdd„	Zdd„ Zdd„ Zd	d
„ Zdd„ Zddd„Z	dd„ Z
dd„ Zdd„ Zddd„Z‡  ZS )r±   zType class for structures.Nc                    sV   || _ d | _tƒ | _|r|ng | _| jD ]}|| j|j < q|  ¡  tt| ƒ |¡ d S rx   )	r`   r2  r   rÚ   rª   Ú_calc_offsetsr…   r±   r]   )r\   r   r`   rª   rF   r†   r   r   r]   ç  s   
zStructure.__init__c              	   C   s¨   d}d }d}| j D ]H}|jr5|dks|j|kr,|j}|jd }|d ur+||_||j7 }nd |_||j8 }q	||_|d urQz	|t|jƒ7 }W q	 tyP   d }Y q	w q	d S ©Nr   rB   )rª   rº   r›   r2  Úoffsetrç   Ú	TypeError)r\   r7  ÚbitstypeÚbitsremainingrÂ   r   r   r   r5  ó  s0   


€
ÿýñzStructure._calc_offsetsc                 C   s†   d}d }d}| j D ]7}|jr*|dks|j|kr$|j}|jd }||j7 }||j8 }q	t|jƒ}||7 }|jd ur@t||j| ƒ}q	|S r6  )rª   rº   r›   r2  rç   r7  Úmax)r\   r2  r9  r:  rÂ   Úfieldlenr   r   r   Ú
_calc_size  s"   





€zStructure._calc_sizec                 O   s  t d| j| jƒ t|| jjƒ}| ¡ }tƒ }i }| jD ]b}| ¡ }	| j 	|j
¡}
|jrJ|	||j krJt d ||j|j¡ƒ | ||j ¡ ||j }	|jrX| |
|j¡||j< q| ¡  t|
ttfƒrj|
 ||¡}n|
 |¡}| ¡ |	 ||j< |||j< qt| ||ƒS )Nz[Structure::read] {} {}z!+ seeking to 0x{:x}+0x{:x} for {})r   r`   r2  Ú	BitBufferr   rQ   ró   r   rª   rZ   r›   r7  r   rô   rº   rm   Úresetrq   r½   r¾   rõ   rÍ   )r\   rð   r   r   Ú	bitbufferÚstruct_startrk   rÓ   rÂ   ÚstartÚftr–   r   r   r   rõ   $  s6   

ÿÿ

zStructure._readc                 C   sz   t || jjƒ}d}| jD ]'}|jr| |jt||jƒ|j¡ q|j	r&| 
¡  ||j |t||jƒ¡7 }q|j	r;| 
¡  |S rú   )r>  r   rQ   rª   rº   rÕ   r›   rø   r`   rÎ   Úflushr  )r\   rð   rƒ   r@  r(  rÂ   r   r   r   r  J  s   
zStructure._writec                 C   s:   t |||d�}| j |¡ || j|< d| _t| ||ƒ dS )z¡Add a field to this structure.

        Args:
            name: The field name.
            type_: The field type.
            offset: The field offset.
        ©r7  N)r¿   rª   rÀ   rÚ   r2  r/  )r\   r`   rÁ   r7  rÂ   r   r   r   Ú	add_field^  s
   
zStructure.add_fieldc                 C   s,   t ƒ }| jD ]
}|j ¡ ||j< qt| |ƒS )z†Create and return an empty Instance from this structure.

        Returns:
            An empty Instance from this structure.
        )r   rª   r›   r+  r`   rÍ   )r\   rk   rÂ   r   r   r   r+  l  s   

zStructure.defaultc                 C   s   | j d u r
|  ¡ | _ | j S rx   )r2  r=  rÆ   r   r   r   rè   x  s   

zStructure.__len__c                 C   ó   d  | j¡S )Nz<Structure {}>)r   r`   rÆ   r   r   r   rå   ~  ré   zStructure.__repr__r   c                 C   s|   |dkrt d | j¡ƒ | jD ],}|jdu rd}nd |j¡}t d d| ||j|j¡ƒ t|jtƒr;|j |d ¡ qdS )	zPretty print this structure.r   ú	struct {}Nz0x??z0x{:02x}z{}+{} {} {}r   r   )	r   r   r`   rª   r7  r›   rq   r±   Úshow)r\   ÚindentrÂ   r7  r   r   r   rI  �  s   

€÷zStructure.showrx   )r   )r
   r   r   ry   r]   r5  r=  rõ   r  rF  r+  rè   rå   rI  rÌ   r   r   r†   r   r±   ä  s    &
r±   c                   @   ó8   e Zd ZdZdd„ Zdd„ Zdd„ Zdd	„ Zd
d„ ZdS )r>  z;Implements a bit buffer that can read and write bit fields.c                 C   s"   || _ || _d | _d| _d| _d S rú   )rð   rQ   rÎ   Ú_bufferÚ
_remaining)r\   rð   rQ   r   r   r   r]   •  s
   
zBitBuffer.__init__c                 C   s¶   | j dk s
| j|kr|| _|jd | _ | | j¡| _| jdkr8| jd|> d @ }|  j|L  _|  j |8  _ |S | jd| j | > d d| j > d A @ }|| j | L }|  j |8  _ |S )Nr   rB   ú>)rM  rÎ   r2  rõ   rð   rL  rQ   )r\   Ú
field_typerº   r–   r   r   r   rm   �  s   
úÿzBitBuffer.readc                 C   sr   | j dkr|jd | _ || _| jdkr$|  j|| jjd | j  > O  _n|  j|| j | > O  _|  j |8  _ d S )Nr   rB   rN  )rM  r2  rÎ   rQ   rL  )r\   rO  rƒ   rº   r   r   r   rÕ   °  s   

"zBitBuffer.writec                 C   s(   | j  | j| j¡ d | _ d| _d| _d S rú   )rÎ   r  rð   rL  rM  rÆ   r   r   r   rD  ¼  s   
zBitBuffer.flushc                 C   s   d | _ d| _d| _d S rú   )rÎ   rL  rM  rÆ   r   r   r   r?  Â  s   
zBitBuffer.resetN)	r
   r   r   ry   r]   rm   rÕ   rD  r?  r   r   r   r   r>  ’  s    r>  c                   @   s"   e Zd ZdZddd„Zdd„ ZdS )r¿   zHolds a structure field.Nc                 C   s   || _ || _|| _|| _d S rx   )r`   r›   rº   r7  )r\   r`   rÁ   rº   r7  r   r   r   r]   Ë  s   
zField.__init__c                 C   rü   )Nz<Field {} {}>)r   r`   r›   rÆ   r   r   r   rå   Ñ  rý   zField.__repr__)NN)r
   r   r   ry   r]   rå   r   r   r   r   r¿   È  s    
r¿   c                       sJ   e Zd ZdZ‡ fdd„Zddd„Zdd„ Zd	d
„ Zdd„ Zdd„ Z	‡  Z
S )r½   a  Implements a fixed or dynamically sized array type.

    Example:
        When using the default C-style parser, the following syntax is supported:

            x[3] -> 3 -> static length.
            x[] -> None -> null-terminated.
            x[expr] -> expr -> dynamic length.
    c                    s8   || _ || _t| jtƒp| jd u | _tt| ƒ |¡ d S rx   )r›   r¸   rq   rŸ   Údynamicr…   r½   r]   )r\   r   rÁ   r¸   r†   r   r   r]   à  s   zArray.__init__Nc                 C   sD   | j d u r| j |¡S | jr| j  |¡}n| j }| j |td|ƒ¡S rú   )r¸   r›   r'  rP  r    r%  r;  )r\   rð   r  r¸   r   r   r   rõ   ç  s   
zArray._readc                 C   s&   | j d u r| j ||¡S | j ||¡S rx   )r¸   r›   r*  r)  )r\   rF   rƒ   r   r   r   r  ò  s   
zArray._writec                    s,   ˆ j sˆ jd u r
g S ‡ fdd„tˆ jƒD ƒS )Nc                    s   g | ]}ˆ j  ¡ ‘qS r   )r›   r+  r"  rÆ   r   r   rÇ   ü  r#  z!Array.default.<locals>.<listcomp>)rP  r¸   rs   rÆ   r   rÆ   r   r+  ø  s   zArray.defaultc                 C   s&   | j d u rd | j¡S d | j| j ¡S )Nz{0!r}[]z
{0!r}[{1}])r¸   r   r›   rÆ   r   r   r   rå   þ  s   
zArray.__repr__c                 C   s   | j rtdƒ‚t| jƒ| j S )NzDynamic size)rP  r8  rç   r›   r¸   rÆ   r   r   r   rè     s   zArray.__len__rx   )r
   r   r   ry   r]   rõ   r  r+  rå   rè   rÌ   r   r   r†   r   r½   Õ  s    

r½   c                       ó`   e Zd ZdZ‡ fdd„Zdd„ Zdd„ Zdd	„ Zd
d„ Zdd„ Z	dd„ Z
dd„ Zdd„ Z‡  ZS )rT   zDImplements a packed type that uses Python struct packing characters.c                    ó   || _ tt| ƒ |||¡ d S rx   )Úpackcharr…   rT   r]   )r\   r   r`   r2  rS  r†   r   r   r]     ó   zPackedType.__init__c                 C   s   |   |d¡d S ©Nr   r   )r%  r!  r   r   r   rõ     rý   zPackedType._readc                 C   sZ   | j | }| |¡}| jjt|ƒ | j }t|ƒ|kr%tdt|ƒ|f ƒ‚tt	 
||¡ƒS )NzRead %d bytes, but expected %d)r2  rm   r   rQ   rr   rS  rç   ÚEOFErrorÚlistr©   Úunpack)r\   rð   r¸   Úlengthrƒ   Úfmtr   r   r   r%    s   

zPackedType._read_arrayc                 C   sF   g }	 |  | j¡}t | jj| j |¡d }|dkr	 |S | |¡ q©NTr   )rm   r2  r©   rX  r   rQ   rS  rÀ   )r\   rð   rk   rH   r–   r   r   r   r'    s   
þùzPackedType._read_0c                 C   s   |   ||g¡S rx   ©r)  r   r   r   r   r  +  rà   zPackedType._writec                 C   s2   | j jtt|ƒƒ | j }| tj|g|¢R Ž ¡S rx   )r   rQ   rr   rç   rS  rÕ   r©   Úpack)r\   rð   rƒ   rZ  r   r   r   r)  .  s   zPackedType._write_arrayc                 C   ó   |   ||dg ¡S rú   r\  r   r   r   r   r*  2  ó   zPackedType._write_0c                 C   ó   dS rú   r   rÆ   r   r   r   r+  5  ó   zPackedType.defaultc                 C   ó
   dg| S rú   r   r.  r   r   r   r-  8  r~   zPackedType.default_array©r
   r   r   ry   r]   rõ   r%  r'  r  r)  r*  r+  r-  rÌ   r   r   r†   r   rT     s    	rT   c                       rQ  )rU   z=Implements a character type that can properly handle strings.c                    ó   t t| ƒ |dd¡ d S )NrI   r   )r…   rU   r]   r}   r†   r   r   r]   ?  r&  zCharType.__init__c                 C   s
   |  d¡S )Nr   ©rm   r!  r   r   r   rõ   B  r~   zCharType._readc                 C   s   |dkrdS |  |¡S )Nr   ó    re  r$  r   r   r   r%  E  s   
zCharType._read_arrayc                 C   s>   g }	 |  d¡}|dkrtƒ ‚|dkrn| |¡ qd |¡S )NTr   rf  ó    )rm   rV  rÀ   rä   ©r\   rð   rk   Úcr   r   r   r'  K  s   

ø

zCharType._read_0c                 C   s4   t |tƒr	t|ƒ}trt |tƒr| d¡}| |¡S )Nzlatin-1)rq   r9   ÚchrÚPY3rr   ÚencoderÕ   r   r   r   r   r  Y  s
   


zCharType._writec                 C   r  rx   r  r   r   r   r   r)  b  ré   zCharType._write_arrayc                 C   ó   |   ||d ¡S ©Nrg  r  r   r   r   r   r*  e  rý   zCharType._write_0c                 C   r`  rn  r   rÆ   r   r   r   r+  h  ra  zCharType.defaultc                 C   ó   d| S rn  r   r.  r   r   r   r-  k  ó   zCharType.default_arrayrc  r   r   r†   r   rU   <  s    	rU   c                       sl   e Zd ZdZ‡ fdd„Zedd„ ƒZdd„ Zdd	„ Zd
d„ Z	dd„ Z
dd„ Zdd„ Zdd„ Zdd„ Z‡  ZS )rV   z!Implements a wide-character type.c                    rd  )NrJ   r<   )r…   rV   r]   r}   r†   r   r   r]   r  r&  zWcharType.__init__c                 C   s$   | j jdkrdS | j jdkrdS d S )Nr    z	utf-16-lerN  z	utf-16-be)r   rQ   rÆ   r   r   r   Úencodingu  s
   ÿzWcharType.encodingc                 C   s   |  d¡ | j¡S )Nr<   ©rm   Údecoderq  r!  r   r   r   rõ   |  r_  zWcharType._readc                 C   s&   |dkrdS |  d| ¡}| | j¡S )Nr   r¶   r<   rr  )r\   rð   r¸   rƒ   r   r   r   r%    s   zWcharType._read_arrayc                 C   sB   d}	 |  d¡}t|ƒdkrtƒ ‚|dkrn||7 }q| | j¡S )Nrf  Tr<   s     )rm   rç   rV  rs  rq  rh  r   r   r   r'  †  s   
÷zWcharType._read_0c                 C   s   |  | | j¡¡S rx   )rÕ   rl  rq  r   r   r   r   r  •  r_  zWcharType._writec                 C   r  rx   r  r   r   r   r   r)  ˜  ré   zWcharType._write_arrayc                 C   rm  ©Nú r  r   r   r   r   r*  ›  rý   zWcharType._write_0c                 C   r`  rt  r   rÆ   r   r   r   r+  ž  ra  zWcharType.defaultc                 C   ro  rt  r   r.  r   r   r   r-  ¡  rp  zWcharType.default_array)r
   r   r   ry   r]   Úpropertyrq  rõ   r%  r'  r  r)  r*  r+  r-  rÌ   r   r   r†   r   rV   o  s    
rV   c                       sx   e Zd ZdZ‡ fdd„Zedd„ ƒZedd„ ƒZdd	„ Zd
d„ Z	dd„ Z
dd„ Zdd„ Zdd„ Zdd„ Zdd„ Z‡  ZS )rW   zFImplements an integer type that can span an arbitrary amount of bytes.c                    rR  rx   )Úsignedr…   rW   r]   )r\   r   r`   r2  rw  r†   r   r   r]   ¨  rT  zBytesInteger.__init__c                    sÈ   g }t |ƒD ][}d}| || |d | … ‰ |dkr,d ‡ fdd„tt tˆ ƒƒƒD ƒ¡‰ tr2tˆ ƒnttˆ ƒ}|D ]}	|d> |	B }q9|r\|d|d d > @ r\d|d d > }
||
d 8 }| |¡ q|S )	Nr   r   r    rf  c                 3   s    � | ]}ˆ ||d  … V  qdS )r   Nr   r"  ©rƒ   r   r   Ú	<genexpr>´  s   € z%BytesInteger.parse.<locals>.<genexpr>rB   r<   )	rs   rä   Úreversedrç   rk  rW  ÚmapÚordrÀ   )r  r2  r¸   rw  rQ   Únumsri  r(  Úintsr@   Úbiasr   rx  r   rf   ¬  s   $zBytesInteger.parsec                    sÎ   g }| D ]]}t |ƒ}|dk r|d|d > 7 }dg| ‰ |d }|dkr@|d@ }tr.t|fƒnt|ƒˆ |< |dL }|d8 }|dks#|dkrWd ‡ fdd	„tttˆ ƒƒƒD ƒ¡‰ nd ˆ ¡‰ | ˆ ¡ qd |¡S )
Nr   r   rB   rg  éÿ   r    rf  c                 3   s$   � | ]}ˆ ||d  … d V  qdS )r   r   Nr   r"  ©rH   r   r   ry  Ô  s   €" z$BytesInteger.pack.<locals>.<genexpr>)	r9   rk  r   rj  rä   rz  rs   rç   rÀ   )rƒ   r2  rQ   r  r@   r(  r:   r   r�  r   r]  Â  s$   
ü&

zBytesInteger.packc                 C   s*   |   | | jd ¡| jd| j| jj¡d S rU  ©rf   rm   r2  rw  r   rQ   r!  r   r   r   rõ   Ü  s   *zBytesInteger._readc                 C   s&   |   | | j| ¡| j|| j| jj¡S rx   r‚  r$  r   r   r   r%  ß  s   &zBytesInteger._read_arrayc                 C   s*   g }	 |   |¡}|dkr	 |S | |¡ qr[  )rõ   rÀ   )r\   rð   rk   r–   r   r   r   r'  â  s   

þüzBytesInteger._read_0c                 C   s   |  |  |g| j| jj¡¡S rx   ©rÕ   r]  r2  r   rQ   r   r   r   r   r  ì  s   zBytesInteger._writec                 C   s   |  |  || j| jj¡¡S rx   rƒ  r   r   r   r   r)  ï  s   zBytesInteger._write_arrayc                 C   r^  rú   r\  r   r   r   r   r*  ò  r_  zBytesInteger._write_0c                 C   r`  rú   r   rÆ   r   r   r   r+  õ  ra  zBytesInteger.defaultc                 C   rb  rú   r   r.  r   r   r   r-  ø  r~   zBytesInteger.default_array)r
   r   r   ry   r]   Ústaticmethodrf   r]  rõ   r%  r'  r  r)  r*  r+  r-  rÌ   r   r   r†   r   rW   ¥  s    


rW   c                       sx   e Zd ZdZ‡ fdd„Zdd„ Zdd„ Zdd	„ Zd
d„ Zdd„ Z	dd„ Z
dd„ Zdd„ Zdd„ Zdd„ Zdd„ Z‡  ZS )r¡   aê  Implements an Enum type.

    Enums can be made using any type. The API for accessing enums and their
    values is very similar to Python 3 native enums.

    Example:
        When using the default C-style parser, the following syntax is supported:

            enum <name> [: <type>] {
                <values>
            };

        For example, an enum that has A=1, B=5 and C=6 could be written like so:

            enum Test : uint16 {
                A, B=5, C
            };
    c                    sL   || _ || _i | _| ¡ D ]	\}}|| j|< qtt| ƒ ||t| j ƒ¡ d S rx   )r›   r—   ÚreverserË   r…   r¡   r]   rç   )r\   r   r`   rÁ   r—   rÅ   r–   r†   r   r   r]     s   zEnum.__init__c                 C   s
   t | |ƒS rx   )ÚEnumInstance©r\   r�   r   r   r   r0    r~   zEnum.__call__c                 C   s   | j  |¡}| |ƒS rx   )r›   rõ   )r\   rð   r–   r   r   r   rõ     s   z
Enum._readc                 C   s   t t| | j ||¡ƒƒS rx   )rW  r{  r›   r%  r$  r   r   r   r%  !  r&  zEnum._read_arrayc                 C   s   t t| | j |¡ƒƒS rx   )rW  r{  r›   r'  r!  r   r   r   r'  $  ó   zEnum._read_0c                 C   s"   t |tƒr|jn|}| j ||¡S rx   )rq   r†  r�   r›   r  r   r   r   r   r  '  s   zEnum._writec                 C   ó   dd„ |D ƒ}| j  ||¡S )Nc                 S   ó    g | ]}t |tƒr|jn|‘qS r   ©rq   r†  r�   ©rÄ   rH   r   r   r   rÇ   ,  rÈ   z%Enum._write_array.<locals>.<listcomp>)r›   r)  r   r   r   r   r)  +  ó   zEnum._write_arrayc                 C   r‰  )Nc                 S   rŠ  r   r‹  rŒ  r   r   r   rÇ   0  rÈ   z!Enum._write_0.<locals>.<listcomp>)r›   r*  r   r   r   r   r*  /  r�  zEnum._write_0c                 C   s   | dƒS rú   r   rÆ   r   r   r   r+  3  rp  zEnum.defaultc                 C   ó    || j v r| | j | ƒS t|ƒ‚rx   )r—   ÚKeyErrorru   r   r   r   rß   6  ó   
zEnum.__getitem__c                 C   rŽ  rx   )r—   rt   ru   r   r   r   rw   <  r�  zEnum.__getattr__c                 C   s
   || j v S rx   )r—   ru   r   r   r   rá   B  r~   zEnum.__contains__)r
   r   r   ry   r]   r0  rõ   r%  r'  r  r)  r*  r+  rß   rw   rá   rÌ   r   r   r†   r   r¡   ü  s    
r¡   c                   @   sL   e Zd ZdZdd„ Zedd„ ƒZdd„ Zdd	„ Zd
d„ Z	dd„ Z
dd„ ZdS )r†  z&Implements a value instance of an Enumc                 C   r  rx   )r§   r�   )r\   r§   r�   r   r   r   r]   I  r	  zEnumInstance.__init__c                 C   s.   | j | jjvrd | jj| j ¡S | jj| j  S )Nz{}_{})r�   r§   r…  r   r`   rÆ   r   r   r   r`   M  s   zEnumInstance.namec                 C   s4   t |tƒr|j| jurdS t|dƒr|j}| j|kS )NFr�   )rq   r†  r§   Úhasattrr�   r‡  r   r   r   Ú__eq__S  s
   

zEnumInstance.__eq__c                 C   s   |   |¡du S )NF)r’  r‡  r   r   r   Ú__ne__\  rà   zEnumInstance.__ne__c                 C   s   t | j| jfƒS rx   )Úhashr§   r�   rÆ   r   r   r   Ú__hash___  rý   zEnumInstance.__hash__c                 C   s   d  | jj| j¡S )Nz{}.{})r   r§   r`   rÆ   r   r   r   rù   b  r_  zEnumInstance.__str__c                 C   s   d  | jj| j| j¡S )Nz<{}.{}: {}>)r   r§   r`   r�   rÆ   r   r   r   rå   e  rˆ  zEnumInstance.__repr__N)r
   r   r   ry   r]   rv  r`   r’  r“  r•  rù   rå   r   r   r   r   r†  F  s    
	r†  c                       s$   e Zd Z‡ fdd„Zdd„ Z‡  ZS )ÚUnionc                    s   || _ tt| ƒ |¡ d S rx   )r   r…   r–  r]   r}   r†   r   r   r]   j  rˆ   zUnion.__init__c                 C   r   rx   r€   r!  r   r   r   rõ   n  r  zUnion._read)r
   r   r   r]   rõ   rÌ   r   r   r†   r   r–  i  s    r–  c                       s8   e Zd ZdZ‡ fdd„Zdd„ Zdd„ Zdd	„ Z‡  ZS )
r¾   z(Implements a pointer to some other type.c                    s    || _ || _tt| ƒ |¡ d S rx   )r   r›   r…   r¾   r]   )r\   r   Útargetr†   r   r   r]   u  r3  zPointer.__init__c                 C   s   | j  |¡}t| j|||ƒS rx   )r   r[   rë   r›   )r\   rð   rò   rñ   r   r   r   rõ   z  s   zPointer._readc                 C   s   t | jjƒS rx   )rç   r   r[   rÆ   r   r   r   rè   ~  ré   zPointer.__len__c                 C   rG  )Nz<Pointer {!r}>)r   r›   rÆ   r   r   r   rå   �  ré   zPointer.__repr__)	r
   r   r   ry   r]   rõ   rè   rå   rÌ   r   r   r†   r   r¾   r  s    r¾   c                       s(   e Zd ZdZ‡ fdd„Zdd„ Z‡  ZS )rX   zImplements a void type.c                    s   t t| ƒ d dd¡ d S )NrP   r   )r…   rX   r]   rÆ   r†   r   r   r]   ˆ  r&  zVoidType.__init__c                 C   s   d S rx   r   r!  r   r   r   rõ   ‹  ra  zVoidType._read)r
   r   r   ry   r]   rõ   rÌ   r   r   r†   r   rX   …  s    rX   c                 C   sD   g }| j D ]}t|jƒ}| |j|f¡ qt| jtjfd|iƒ}|S )z1Create ctypes structures from cstruct structures.Ú_fields_)rª   Úctypes_typer›   rÀ   r`   Ú_ctypesr±   )Ú	structurerª   rÂ   ra   Úttr   r   r   Úctypes�  s   

r�  c                 C   s‚   t jt jt jdœ}t| tƒr|| j S t| tƒrt jS t| t	ƒr*t
| jƒ}|| j S t| tƒr9t
| jƒ}t |¡S td| jj ƒ‚)N)rA   r@   r:   zType not implemented: %s)rš  Úc_ulongÚc_longÚc_int8rq   rT   rS  rU   Úc_charr½   r™  rÎ   r¸   r¾   Ú_targetr�  ÚPOINTERr�   r‡   r
   )ra   ÚmappingÚsubtyper   r   r   r™  š  s   ý








r™  c                   @   rK  )r¯   zICompiler for cstruct structures. Creates somewhat optimized parsing code.c                 C   r{   rx   r|   r}   r   r   r   r]   µ  r~   zCompiler.__init__c                 C   sR   |   |¡}t|ddƒ}tttttttt	t
tdœ
}t||ƒ ||j | j||ƒ}|S )Nz
<compiled>Úexec)
r   r±   rÍ   rŸ   r†  rë   rW   r>  r©   rs   )Úgen_struct_classr­   r   r±   rÍ   rŸ   r†  rë   rW   r>  r©   rs   r¦  r`   r   )r\   r›  Úsourceri  ÚenvÚscr   r   r   r­   ¸  s    
ö
zCompiler.compilec                 C   s&  g }g }g }d}d}|j D ]Ö}| j |j¡}t|ttttt	t
ttfƒs*td |¡ƒ‚t|tƒs:t|tƒr‡t|jtƒr‡|rE| |  ||¡¡ d}	t|tƒri|j}
t|
tƒr[dj|
jd�}
|	dj|j|
|jjd�7 }	n|	d	j|j|jd
�7 }	|	dj|jd�7 }	| |	¡ d}g }q|jr«|r•| |  ||¡¡ | dj|j|jj|jd�¡ d}g }d}q|r´| d¡ d}zt|ƒ}||7 }| |¡ W q tyã   |rÕ| |  ||¡¡ | |  |¡¡ d}g }Y qw t|ƒrñ| |  ||¡¡ d |¡}d dd„ | d¡D ƒ¡}| tj|j|d�¡ d |¡S )Nr   Fz!Unsupported type for compiler: {}zs = stream.tell()
z6max(0, Expression(self.cstruct, "{expr}").evaluate(r))r  zjr["{name}"] = []
for _ in xrange({num}):
    r["{name}"].append(self.cstruct.{struct_name}._read(stream))
)r`   r(  Ústruct_namez7r["{name}"] = self.cstruct.{struct_name}._read(stream)
)r`   r«  z#sizes["{name}"] = stream.tell() - s)r`   z>r["{name}"] = bitreader.read(self.cstruct.{type_name}, {bits}))r`   Ú	type_namerº   Tzbitreader.reset()z

r˜   c                 S   s   g | ]}d | ‘qS )z        r   )rÄ   r   r   r   r   rÇ   *  s    z-Compiler.gen_struct_class.<locals>.<listcomp>)r`   Ú	read_code)rª   r   rZ   r›   rq   r±   r¾   r¡   r½   rT   rU   rV   rW   r   r   rÀ   Úgen_read_blockr¸   rŸ   r  r`   rº   rç   r¼   Úgen_dynamic_blockrä   rœ   ÚCOMPILE_TEMPL)r\   r›  ÚblocksÚclassesÚ	cur_blockÚ	read_sizeÚprev_was_bitsrÂ   rC  Ústruct_readr(  r¸   r­  r   r   r   r§  Î  s¤   
øþ
ÿ
ÿ

ÿýÿÿÿ
ÿÿ
û

zCompiler.gen_struct_classc                 C   sP  dj |d�}g }g }d }d}d}d}	|D �]z}
| j |
j¡}|}d}d}d}t|tƒr/|j}n	t|tƒr8| jj}t|tƒrt|j	}|}|j}t|tƒrN|j}n	t|tƒrW| jj}t|t
ttfƒrkd  ||||j  ¡}n(d  |	|	| ¡}nt|t
ƒr~t|ƒ}nt|ttfƒr�d  |||j ¡}nt|	ƒ}|s t|tƒrž|j}nd}t|tt
tttfƒrÖ|}t|t
ttfƒr¾d}d}||j9 }n|j}||krÐ| d  ||¡¡ d}||7 }|}d}t|tƒrðd	j ||j||j|dkrëd
ndd�}nt|t
tfƒ�rd  |¡}t|tƒ�r|d7 }nd  |¡}t|tƒ�rdj |j|d�}nOt|tƒ�r3t|jtƒ�r3dj |jj|d�}n8t|tƒ�rCdj |jj|d�}n(t|tƒ�rZt|jtƒ�rZdj |jj|d�}nt|tƒ�rkt|tƒ�rkd  |¡}| dj |
j|d�¡ | dj |
j||j d�¡ |	|7 }	|||j 7 }q|�rœ| d  ||¡¡ |  d |¡d |¡¡S )Nz~buf = stream.read({size})
if len(buf) != {size}: raise EOFError()
data = struct.unpack(self.cstruct.endian + "{{}}", buf)
{{}}r4  r   r   r¶   z{}:{}Úxz{}{}z\BytesInteger.parse(buf[{slice}], {size}, {count}, {signed}, self.cstruct.endian){data_slice}z[0])Úslicer2  r¸   rw  Ú
data_slicezbuf[{}]úC.decode('utf-16-le' if self.cstruct.endian == '<' else 'utf-16-be')zdata[{}]z0EnumInstance(self.cstruct.{type_name}, {getter}))r¬  Úgetterz=[EnumInstance(self.cstruct.{type_name}, d) for d in {getter}]z>PointerInstance(self.cstruct.{type_name}, stream, {getter}, r)zK[PointerInstance(self.cstruct.{type_name}, stream, d, r) for d in {getter}]zlist({})zr["{name}"] = {getter})r`   r»  zsizes["{name}"] = {size})r`   r2  r˜   )r   r   rZ   r›   rq   r¡   r¾   r[   r½   r¸   rU   rV   rW   r2  rr   rT   rS  rÀ   rw  r`   rä   )r\   r2  ÚblockÚtemplÚreadcoderZ  ÚcurtypeÚcurcountÚ
buf_offsetÚdata_offsetrÂ   rC  ra   r¸   Ú
data_countÚ
read_sliceÚ	charcountrS  r»  r   r   r   r®  /  sÄ   ýÿ





ÿ



û
€
ÿÿÿÿ
ÿÿzCompiler.gen_read_blockc                 C   s>  t |jtƒstd |j¡ƒ‚|jj}d }|jjsYt |tƒr'dj|j|jd�}n*t |t	t
fƒrCdj|jd|j d�}t |t
ƒrB|d7 }nt |tƒrQdj|j|jd	�}d
j||jd�S |jjj}dj||j|jd�}t |tƒrwdj|j|jd�}n!t |t	t
fƒrŠd}t |t
ƒr‰|d7 }nt |tƒr˜dj|j|jd	�}|j|d d�S )Nz#Only Array can be dynamic, got {!r}z½t = []
while True:
    d = stream.read({size})
    if len(d) != {size}: raise EOFError()
    v = struct.unpack(self.cstruct.endian + "{packchar}", d)[0]
    if v == 0: break
    t.append(v))r2  rS  z•t = []
while True:
    c = stream.read({size})
    if len(c) != {size}: raise EOFError()
    if c == b"{null}": break
    t.append(c)
t = b"".join(t)z\x00)r2  Únullrº  zÅt = []
while True:
    d = stream.read({size})
    if len(d) != {size}: raise EOFError()
    v = BytesInteger.parse(d, {size}, 1, {signed}, self.cstruct.endian)
    if v == 0: break
    t.append(v))r2  rw  z1{reader}
r["{name}"] = t
sizes["{name}"] = len(t))Úreaderr`   zádynsize = max(0, Expression(self.cstruct, "{expr}").evaluate(r))
buf = stream.read(dynsize * {type_size})
if len(buf) != dynsize * {type_size}: raise EOFError()
r["{name}"] = {{reader}}
sizes["{name}"] = dynsize * {type_size})r  r`   Ú	type_sizezRlist(struct.unpack(self.cstruct.endian + "{{:d}}{packchar}".format(dynsize), buf)))rS  rÈ  r  zGBytesInteger.parse(buf, {size}, dynsize, {signed}, self.cstruct.endian))rÇ  r2  )rq   r›   r½   r   r   r¸   rT   r2  rS  rU   rV   rW   rw  r`   r  )r\   rÂ   ra   rÇ  r  Ú	expr_readr   r   r   r¯  «  sb   
ÿ

ûÿ	úÿ
€

úÿ
ÿ

ûÿ

ÿ
€
ÿzCompiler.gen_dynamic_blockN)	r
   r   r   ry   r]   r­   r§  r®  r¯  r   r   r   r   r¯   ²  s    a|r¯   r¶   c                 C   s~  |r	|ddd… }d}d}t dt| ƒdƒD ]§}d}g }t dƒD ]‹}	|s0|r0| ¡ \}}||7 }n
|r:|	dkr:||7 }||	 t| ƒkrG|d7 }nW| ||	  }
trSt|
ƒn|
}
|
tv r[|
nd}|rr|d t|
ƒ¡7 }| || t	 ¡ n|d t|
ƒ¡7 }| |¡ |d	8 }|dkr’d}|dur’|t	7 }|	d
krž|durž|t	7 }|d7 }|	dkrª|d7 }qd 
|¡}td ||| ||¡ƒ qdS )zÌHexdump some data.

    Args:
        s: Bytes to hexdump.
        palette: Colorize the hexdump using this color pattern.
        offset: Byte offset of the hexdump.
        prefix: Optional prefix.
    Nr«   r   r  r¶   z  Ú.z{:02x}r   é   r   é   z{}{:08x}  {:48s}  {})rs   rç   r  rk  rj  Ú	PRINTABLEr   r|  rÀ   ÚCOLOR_NORMALrä   r   )rg   Úpaletter7  ÚprefixÚ	remainingÚactiver@   ÚvalsÚcharsÚjri  Úpr   r   r   Úhexdump÷  sL   	


€
×r×  c              	   C   sp  t tfttfttfttftt	ft
tfttfg}t| tƒr&| }| j} | ¡ }nt| tƒr2|r2| |ƒ}ntdƒ‚g }d}d | j¡d }|jjD ]^}||t|ƒ  \}	}
| | |j¡|
f¡ |d7 }t||jƒ}t|tƒrqt|ƒ}n(t|tƒr{t|ƒ}nt|tƒr™t  !|¡}d|v r™| "dd dt|jƒd	  ¡¡}|d
 |	|jt#|¡7 }qFt$ƒ  t%|||d� t$ƒ  t$|ƒ dS )a  Dump a structure or parsed structure instance.

    Prints a colorized hexdump and parsed structure output.

    Args:
        t: Structure or Instance to dump.
        data: Bytes to parse the Structure on, if t is not a parsed Instance.
        offset: Byte offset of the hexdump.
    zInvalid argumentsr   rH  z:
r   r˜   z
{}r   r?   z- {}{}{}: {}
rE  N)&Ú	COLOR_REDÚCOLOR_BG_REDÚCOLOR_GREENÚCOLOR_BG_GREENÚCOLOR_YELLOWÚCOLOR_BG_YELLOWÚ
COLOR_BLUEÚCOLOR_BG_BLUEÚCOLOR_PURPLEÚCOLOR_BG_PURPLEÚ
COLOR_CYANÚCOLOR_BG_CYANÚCOLOR_WHITEÚCOLOR_BG_WHITErq   rÍ   rÎ   r×   r±   r_   r   r`   rª   rç   rÀ   rê   rø   rr   rã   r9   râ   rW  ÚpprintÚpformatrb   rÎ  r   r×  )ra   rƒ   r7  ÚcolorsÚgrÏ  Úcir  rÂ   ÚfgÚbgr–   r   r   r   Ú
dumpstruct2  sH   ù









 rí  )Nr   r¶   rú   )Lr�   r   r“   ræ  Ústringr©   r�  rš  Úior   Úcollectionsr   Úbuiltinsr   r  ÚImportErrorÚversion_infork  r9   r+   Úrangers   r   rØ  rÚ  rÜ  rÞ  rà  râ  rä  rÎ  rÙ  rÛ  rÝ  rß  rá  rã  rå  ÚdigitsÚascii_lettersÚpunctuationrÍ  r°  r¼   r   r   r   r   r   r   rÑ   r   rz   re   rÍ   rë   rŸ   r  r1  r±   r>  r¿   r½   rT   rU   rV   rW   r¡   r†  r–  r¾   rX   r™  r¯   r×  rí  r   r   r   r   Ú<module>   s’   ÿ
 % A(Af /66136WJ#	
  
G;