
    dS                     j   d dl mZ d dlmZmZmZmZ d dlmZm	Z	m
Z
mZmZmZmZmZmZmZmZmZmZmZmZmZmZmZ d dlmZmZmZmZmZm Z m!Z!m"Z"m#Z#m$Z$ d Z%dFdZ&dGdZ'dHd	Z(d
 Z)d Z*d Z+d Z,d Z-d Z.d Z/d Z0d Z1d Z2d Z3d Z4d Z5d Z6d Z7d Z8d Z9d Z:d Z;d Z<d Z=d Z>d  Z?d! Z@d" ZAd# ZBd$ ZCd% ZDd& ZEd' ZFd( ZGd) ZHd* ZId+ ZJ e,d,      fd-ZKd. ZLd/ ZMd0 ZNd1 ZOd2 ZPdId3ZQd4 ZRd5 ZSd6 ZTd7 ZUeVfd8ZWd9 ZXd: ZYd; ZZd< Z[d= Z\	 	 dJd?Z] e,d,      d>fd@Z^dd> e%d>d       fdAZ_dB Z`dKdCZadLdDZbdE Zcy>)M   )int2byte)BitStreamReaderBitStreamWriter
encode_bin
decode_bin)Struct	MetaFieldStaticFieldFormatFieldOnDemandPointerSwitchValueRepeatUntil	MetaArraySequenceRangeSelectPassSizeofErrorBufferedRestreamReconfig)
BitIntegerAdapterPaddingAdapterConstAdapterCStringAdapterLengthValueAdapterIndexingAdapterPaddedStringAdapterFlagsAdapterStringAdapterMappingAdapterc                 H    t        |      rt        | |      S t        | |      S )a*  
    A field consisting of a specified number of bytes.

    :param str name: the name of the field
    :param length: the length of the field. the length can be either an integer
      (StaticField), or a function that takes the context as an argument and
      returns the length (MetaField)
    )callabler	   r
   )namelengths     ;/usr/lib/python3/dist-packages/elftools/construct/macros.pyFieldr)      s&     v&&4((    c                 6    t        t        | |      ||||      S )a  
    BitFields, as the name suggests, are fields that operate on raw, unaligned
    bits, and therefore must be enclosed in a BitStruct. Using them is very
    similar to all normal fields: they take a name and a length (in bits).

    :param str name: name of the field
    :param int length: number of bits in the field, or a function that takes
                       the context as its argument and returns the length
    :param bool swapped: whether the value is byte-swapped
    :param bool signed: whether the value is signed
    :param int bytesize: number of bits per byte, for byte-swapping

    >>> foo = BitStruct("foo",
    ...     BitField("a", 3),
    ...     Flag("b"),
    ...     Padding(3),
    ...     Nibble("c"),
    ...     BitField("d", 5),
    ... )
    >>> foo.parse("\xe1\x1f")
    Container(a = 7, b = False, c = 8, d = 31)
    >>> foo = BitStruct("foo",
    ...     BitField("a", 3),
    ...     Flag("b"),
    ...     Padding(3),
    ...     Nibble("c"),
    ...     Struct("bar",
    ...             Nibble("d"),
    ...             Bit("e"),
    ...     )
    ... )
    >>> foo.parse("\xe1\x1f")
    Container(a = 7, b = False, bar = Container(d = 15, e = 1), c = 8)
    )swappedsignedbytesize)r   r)   )r&   r'   r,   r-   r.   s        r(   BitFieldr/      s'    H U40	 r*       c                 2    t        t        d|       ||      S )a  a padding field (value is discarded)
    * length - the length of the field. the length can be either an integer,
      or a function that takes the context as an argument and returns the
      length
    * pattern - the padding pattern (character/byte) to use. default is b"\x00"
    * strict - whether or not to raise an exception is the actual padding
      pattern mismatches the desired pattern. default is False.
    N)patternstrict)r   r)   )r'   r2   r3   s      r(   Paddingr4   H   s      %f- r*   c                 \    t        t        | d      t        |      t        |      d|      S )a@  
    A flag.

    Flags are usually used to signify a Boolean value, and this construct
    maps values onto the ``bool`` type.

    .. note:: This construct works with both bit and byte contexts.

    .. warning:: Flags default to False, not True. This is different from the
        C and Python way of thinking about truth, and may be subject to change
        in the future.

    :param str name: field name
    :param int truth: value of truth (default 1)
    :param int falsehood: value of falsehood (default 0)
    :param bool default: default value (default False)
    r   TF)default)SymmetricMappingr)   r   )r&   truth	falsehoodr7   s       r(   Flagr;   V   s-    & E$N))<= r*   c                     t        | d      S )z1a 1-bit BitField; must be enclosed in a BitStructr   r/   r&   s    r(   Bitr?   q       D!r*   c                     t        | d      S )z1a 4-bit BitField; must be enclosed in a BitStruct   r=   r>   s    r(   NibblerC   t   r@   r*   c                     t        | d      S )z2an 8-bit BitField; must be enclosed in a BitStruct   r=   r>   s    r(   OctetrF   w   r@   r*   c                     t        | dd      S )z"unsigned, big endian 8-bit integer>Br   r>   s    r(   UBInt8rK   {       tS#&&r*   c                     t        | dd      S )z#unsigned, big endian 16-bit integerrH   HrJ   r>   s    r(   UBInt16rO   ~   rL   r*   c                     t        | dd      S )z#unsigned, big endian 32-bit integerrH   LrJ   r>   s    r(   UBInt32rR      rL   r*   c                     t        | dd      S )z#unsigned, big endian 64-bit integerrH   QrJ   r>   s    r(   UBInt64rU      rL   r*   c                     t        | dd      S )z signed, big endian 8-bit integerrH   brJ   r>   s    r(   SBInt8rX      rL   r*   c                     t        | dd      S )z!signed, big endian 16-bit integerrH   hrJ   r>   s    r(   SBInt16r[      rL   r*   c                     t        | dd      S )z!signed, big endian 32-bit integerrH   lrJ   r>   s    r(   SBInt32r^      rL   r*   c                     t        | dd      S )z!signed, big endian 64-bit integerrH   qrJ   r>   s    r(   SBInt64ra      rL   r*   c                     t        | dd      S )z%unsigned, little endian 8-bit integer<rI   rJ   r>   s    r(   ULInt8rd      rL   r*   c                     t        | dd      S )z&unsigned, little endian 16-bit integerrc   rN   rJ   r>   s    r(   ULInt16rf      rL   r*   c                     t        | dd      S )z&unsigned, little endian 32-bit integerrc   rQ   rJ   r>   s    r(   ULInt32rh      rL   r*   c                     t        | dd      S )z&unsigned, little endian 64-bit integerrc   rT   rJ   r>   s    r(   ULInt64rj      rL   r*   c                     t        | dd      S )z#signed, little endian 8-bit integerrc   rW   rJ   r>   s    r(   SLInt8rl      rL   r*   c                     t        | dd      S )z$signed, little endian 16-bit integerrc   rZ   rJ   r>   s    r(   SLInt16rn      rL   r*   c                     t        | dd      S )z$signed, little endian 32-bit integerrc   r]   rJ   r>   s    r(   SLInt32rp      rL   r*   c                     t        | dd      S )z$signed, little endian 64-bit integerrc   r`   rJ   r>   s    r(   SLInt64rr      rL   r*   c                     t        | dd      S )z(unsigned, native endianity 8-bit integer=rI   rJ   r>   s    r(   UNInt8ru      rL   r*   c                     t        | dd      S )z)unsigned, native endianity 16-bit integerrt   rN   rJ   r>   s    r(   UNInt16rw      rL   r*   c                     t        | dd      S )z)unsigned, native endianity 32-bit integerrt   rQ   rJ   r>   s    r(   UNInt32ry      rL   r*   c                     t        | dd      S )z)unsigned, native endianity 64-bit integerrt   rT   rJ   r>   s    r(   UNInt64r{      rL   r*   c                     t        | dd      S )z&signed, native endianity 8-bit integerrt   rW   rJ   r>   s    r(   SNInt8r}      rL   r*   c                     t        | dd      S )z'signed, native endianity 16-bit integerrt   rZ   rJ   r>   s    r(   SNInt16r      rL   r*   c                     t        | dd      S )z'signed, native endianity 32-bit integerrt   r]   rJ   r>   s    r(   SNInt32r      rL   r*   c                     t        | dd      S )z'signed, native endianity 64-bit integerrt   r`   rJ   r>   s    r(   SNInt64r      rL   r*   c                     t        | dd      S )z-big endian, 32-bit IEEE floating point numberrH   frJ   r>   s    r(   BFloat32r      rL   r*   c                     t        | dd      S )z0little endian, 32-bit IEEE floating point numberrc   r   rJ   r>   s    r(   LFloat32r      rL   r*   c                     t        | dd      S )z3native endianity, 32-bit IEEE floating point numberrt   r   rJ   r>   s    r(   NFloat32r      rL   r*   c                     t        | dd      S )z-big endian, 64-bit IEEE floating point numberrH   drJ   r>   s    r(   BFloat64r      rL   r*   c                     t        | dd      S )z0little endian, 64-bit IEEE floating point numberrc   r   rJ   r>   s    r(   LFloat64r      rL   r*   c                     t        | dd      S )z3native endianity, 64-bit IEEE floating point numberrt   r   rJ   r>   s    r(   NFloat64r      rL   r*   c                      t               rt         |      }|S t         fd|      }|j                  |j                         |S )a  
    Repeats the given unit a fixed number of times.

    :param int count: number of times to repeat
    :param ``Construct`` subcon: construct to repeat

    >>> c = Array(4, UBInt8("foo"))
    >>> c.parse("\x01\x02\x03\x04")
    [1, 2, 3, 4]
    >>> c.parse("\x01\x02\x03\x04\x05\x06")
    [1, 2, 3, 4]
    >>> c.build([5,6,7,8])
    '\x05\x06\x07\x08'
    >>> c.build([5,6,7,8,9])
    Traceback (most recent call last):
      ...
    construct.core.RangeError: expected 4..4, found 5
    c                     S N )ctxcounts    r(   <lambda>zArray.<locals>.<lambda>   s    E r*   )r%   r   _clear_flagFLAG_DYNAMIC)r   subconcons   `  r(   Arrayr      sE    ( v& J )62(()Jr*   r'   c           
      b    t        t        | j                  t        fd|       d            S )zan array prefixed by a length field.
    * subcon - the subcon to be repeated
    * length_field - a construct returning an integer
    c                 "    | j                      S r   r>   r   length_fields    r(   r   zPrefixedArray.<locals>.<lambda>  s    c,"3"34 r*   Fnested)r   r   r&   r   )r   r   s    `r(   PrefixedArrayr      s1    
 4f=	
 r*   c                 (    ddl m} t        | ||      S )N    )maxsize)sysr   r   )mincountr   r   s      r(   	OpenRanger   	  s    7F++r*   c                     t        d|       S )a  
    Repeats the given unit one or more times.

    :param ``Construct`` subcon: construct to repeat

    >>> from construct import GreedyRange, UBInt8
    >>> c = GreedyRange(UBInt8("foo"))
    >>> c.parse("\x01")
    [1]
    >>> c.parse("\x01\x02\x03")
    [1, 2, 3]
    >>> c.parse("\x01\x02\x03\x04\x05\x06")
    [1, 2, 3, 4, 5, 6]
    >>> c.parse("")
    Traceback (most recent call last):
      ...
    construct.core.RangeError: expected 1..2147483647, found 0
    >>> c.build([1,2])
    '\x01\x02'
    >>> c.build([])
    Traceback (most recent call last):
      ...
    construct.core.RangeError: expected 1..2147483647, found 0
    r   r   r   s    r(   GreedyRanger     s    4 Qr*   c                     t        d|       S )a  
    Repeats the given unit zero or more times. This repeater can't
    fail, as it accepts lists of any length.

    :param ``Construct`` subcon: construct to repeat

    >>> from construct import OptionalGreedyRange, UBInt8
    >>> c = OptionalGreedyRange(UBInt8("foo"))
    >>> c.parse("")
    []
    >>> c.parse("\x01\x02")
    [1, 2]
    >>> c.build([])
    ''
    >>> c.build([1,2])
    '\x01\x02'
    r   r   r   s    r(   OptionalGreedyRanger   )  s    & Qr*   c                 8    t        | j                  | t              S )zran optional construct. if parsing fails, returns None.
    * subcon - the subcon to optionally parse or build
    )r   r&   r   r   s    r(   Optionalr   B  s     &++vt,,r*   c                     d}d }| j                  | j                        s,| j                         |k  rt        | t        t
        |      }|S t        | t        t        |      }|S )zzconverts the stream to bits, and passes the bitstream to subcon
    * subcon - a bitwise construct (usually BitField)
    i    c                 .    | dz  rt        d|       | dz	  S )N   zsize must be a multiple of 8   )r   )r'   s    r(   resizerzBitwise.<locals>.resizerO  s!    A:<fEE{r*   )encoderdecoderr   )stream_readerstream_writerr   )	_is_flagr   sizeofr   r   r   r   r   r   )r   
MAX_BUFFERr   r   s       r(   Bitwiser   H  si     J ??6../FMMOj4Pv  
 J	 v++ Jr*   c                 |     dk  rt        d       fd}t         j                   t        ||      d      S )zaligns subcon to modulus boundary using padding pattern
    * subcon - the subcon to align
    * modulus - the modulus boundary (default is 4)
    * pattern - the padding pattern (default is \x00)
       zmodulus must be >= 2c                 8    j                  |       z  z
  z  S r   )_sizeof)r   modulusr   s    r(   	padlengthzAligned.<locals>.padlengthh  s!    6>>#.89WDDr*   )r2   Fr   )
ValueErrorSeqOfOner&   r4   )r   r   r2   r   s   ``  r(   Alignedr   `  sE     {/99EFKK
 		W- r*   c                 6    t        t        | g|i |d      S )za sequence of one element. only the first element is meaningful, the
    rest are discarded
    * name - the name of the sequence
    * args - subconstructs
    * kw - any keyword arguments to Sequence
    r   )index)r   r   )r&   argskws      r(   r   r   t  s      8D64626BBr*   c                 D    t        | j                  | | j                        S )zRembeds a struct into the enclosing struct.
    * subcon - the struct to embed
    )r   r&   
FLAG_EMBEDr   s    r(   Embeddedr   }  s     FKK):):;;r*   c                     t        | |      S )zcrenames an existing construct
    * newname - the new name
    * subcon - the subcon to rename
    )r   )newnamer   s     r(   Renamer     s    
 GV$$r*   c                 "    t        | fd      S )zcreates an alias for an existing element in a struct
    * newname - the new name
    * oldname - the name of an existing element
    c                     |    S r   r   )r   oldnames    r(   r   zAlias.<locals>.<lambda>  s    c'l r*   )r   )r   r   s    `r(   Aliasr     s    
 233r*   c                 b    t        d |j                         D              }t        | ||||      S )a  defines a symmetrical mapping: a->b, b->a.
    * subcon - the subcon to map
    * mapping - the encoding mapping (a dict); the decoding mapping is
      achieved by reversing this mapping
    * default - the default value to use when no mapping is found. if no
      default value is given, and exception is raised. setting to Pass would
      return the value "as is" (unmapped)
    c              3   *   K   | ]  \  }}||f  y wr   r   ).0kvs      r(   	<genexpr>z#SymmetricMapping.<locals>.<genexpr>  s     ?tq!QF?s   )encodingdecoding
encdefault
decdefault)dictitemsr#   )r   mappingr7   reversed_mappings       r(   r8   r8     s6     ?w}}??&#	 r*   c                 D    t        | ||j                  dt                    S )a  a set of named values mapping.
    * subcon - the subcon to map
    * kw - keyword arguments which serve as the encoding mapping
    * _default_ - an optional, keyword-only argument that specifies the
      default value to use when the mapping is undefined. if not given,
      and exception is raised when the mapping is undefined. use `Pass` to
      pass the unmapped value as-is
    	_default_)r8   popNotImplementedr   r   s     r(   Enumr     s     FB{N(KLLr*   c                     t        | |      S )za set of flag values mapping.
    * subcon - the subcon to map
    * kw - keyword arguments which serve as the encoding mapping
    )r!   r   s     r(   	FlagsEnumr     s    
 ##r*   c                 .    t        | gfd|D         S )za struct of aligned fields
    * name - the name of the struct
    * subcons - the subcons that make up this structure
    * kw - keyword arguments to pass to Aligned: 'modulus' and 'pattern'
    c              3   6   K   | ]  }t        |fi   y wr   )r   )r   scr   s     r(   r   z AlignedStruct.<locals>.<genexpr>  s     >'"++>s   )r   )r&   subconsr   s     `r(   AlignedStructr     s     $?>g>??r*   c                 ,    t        t        | g|       S )z{a struct of bitwise fields
    * name - the name of the struct
    * subcons - the subcons that make up this structure
    )r   r   )r&   r   s     r(   	BitStructr     s    
 6$))**r*   c                  >    t        t        t        dg|              S )zian embedded BitStruct. no name is necessary.
    * subcons - the subcons that make up this structure
    N)r   r   r   )r   s    r(   EmbeddedBitStructr     s     8F42'2344r*   Nc                 V    t        t        | |      |      }|t        ||||      }|S )ae  
    A configurable, fixed-length string field.

    The padding character must be specified for padding and trimming to work.

    :param str name: name
    :param int length: length, in bytes
    :param str encoding: encoding (e.g. "utf8") or None for no encoding
    :param str padchar: optional character to pad out strings
    :param str paddir: direction to pad out strings; one of "right", "left",
                       or "both"
    :param str trim: direction to trim strings; one of "right", "left"

    >>> from construct import String
    >>> String("foo", 5).parse("hello")
    'hello'
    >>>
    >>> String("foo", 12, encoding = "utf8").parse("hello joh\xd4\x83n")
    u'hello joh\u0503n'
    >>>
    >>> foo = String("foo", 10, padchar = "X", paddir = "right")
    >>> foo.parse("helloXXXXX")
    'hello'
    >>> foo.build("hello")
    'helloXXXXX'
    r   )padcharpaddirtrimdir)r"   r)   r    )r&   r'   r   r   r   r   r   s          r(   Stringr     s5    : dF+h
?C!#wvJr*   c                 `    t        t        t        | t        dfd                  |      S )a-  
    A length-prefixed string.

    ``PascalString`` is named after the string types of Pascal, which are
    length-prefixed. Lisp strings also follow this convention.

    The length field will appear in the same ``Container`` as the
    ``PascalString``, with the given name.

    :param str name: name
    :param ``Construct`` length_field: a field which will store the length of
                                       the string
    :param str encoding: encoding (e.g. "utf8") or None for no encoding

    >>> foo = PascalString("foo")
    >>> foo.parse("\x05hello")
    'hello'
    >>> foo.build("hello world")
    '\x0bhello world'
    >>>
    >>> foo = PascalString("foo", length_field = UBInt16("length"))
    >>> foo.parse("\x00\x05hello")
    'hello'
    >>> foo.build("hello")
    '\x00\x05hello'
    datac                 "    | j                      S r   r>   r   s    r(   r   zPascalString.<locals>.<lambda>  s    #l.?.?*@ r*   r   )r"   r   r   r)   )r&   r   r   s    ` r(   PascalStringr     s7    8 Tf@A	
  r*   c           	      N    t        | t        t        fd|      |            S )aH  
    A string ending in a terminator.

    ``CString`` is similar to the strings of C, C++, and other related
    programming languages.

    By default, the terminator is the NULL byte (b``0x00``).

    :param str name: name
    :param iterable terminators: sequence of valid terminators, in order of
                                 preference
    :param str encoding: encoding (e.g. "utf8") or None for no encoding
    :param ``Construct`` char_field: construct representing a single character

    >>> foo = CString("foo")
    >>> foo.parse(b"hello\x00")
    b'hello'
    >>> foo.build(b"hello")
    b'hello\x00'
    >>> foo = CString("foo", terminators = b"XYZ")
    >>> foo.parse(b"helloX")
    b'hello'
    >>> foo.parse(b"helloY")
    b'hello'
    >>> foo.parse(b"helloZ")
    b'hello'
    >>> foo.build(b"hello")
    b'helloX'
    c                     | v S r   r   )objr   terminatorss     r(   r   zCString.<locals>.<lambda>?  s    ); r*   )r  r   )r   r   r   )r&   r  r   
char_fields    `  r(   CStringr    s.    @ $;ZH#	
 r*   c                 *    t        | fd||d      S )a  an if-then-else conditional construct: if the predicate indicates True,
    `then_subcon` will be used; otherwise `else_subcon`
    * name - the name of the construct
    * predicate - a function taking the context as an argument and returning
      True or False
    * then_subcon - the subcon that will be used if the predicate returns True
    * else_subcon - the subcon that will be used if the predicate returns False
    c                 &    t         |             S r   )bool)r   	predicates    r(   r   zIfThenElse.<locals>.<lambda>R  s    D3$8 r*   r6   )r   )r&   r	  then_subconelse_subcons    `  r(   
IfThenElser  I  s"     $8	
 r*   c           
      N    t        |j                  | |t        dfd            S )a  an if-then conditional construct: if the predicate indicates True,
    subcon will be used; otherwise, `elsevalue` will be returned instead.
    * predicate - a function taking the context as an argument and returning
      True or False
    * subcon - the subcon that will be used if the predicate returns True
    * elsevalue - the value that will be used should the predicate return False.
      by default this value is None.
    	elsevaluec                     S r   r   )r   r  s    r(   r   zIf.<locals>.<lambda>e  s    y r*   )r  r&   r   )r	  r   r  s     `r(   Ifr  Y  s)     fkkk01 r*   c                 2    t        t        | |      d|      S )a$  an on-demand pointer.
    * offsetfunc - a function taking the context as an argument and returning
      the absolute stream position
    * subcon - the subcon that will be parsed from the `offsetfunc()` stream
      position on demand
    * force_build - see OnDemand. by default True.
    F)advance_streamforce_build)r   r   )
offsetfuncr   r  s      r(   OnDemandPointerr  l  s      GJ/! r*   c                 @    t        t        d t        |             |       S r   )r   r)   len)r   s    r(   Magicr  y  s    dCI.55r*   )FFrE   )r0   F)r   r   F)rB   r0   )NNrightr  r   )T)dlib.py3compatr   libr   r   r   r   corer   r	   r
   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   adaptersr   r   r   r   r   r   r    r!   r"   r#   r)   r/   r4   r;   r?   rC   rF   rK   rO   rR   rU   rX   r[   r^   ra   rd   rf   rh   rj   rl   rn   rp   rr   ru   rw   ry   r{   r}   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r8   r   r   r   r   r   r   r   r  r  r  r  r  r   r*   r(   <module>r     s   # = = = = =F F F))V6''''''''''''''''''''''''''''''6 *0)9 , 8 2-0(C<%4 1? "	M$@+5 >E!F %+8$4t $L &T1~&X &6r*   