o
    ¢ØÆh¯  ã                   @   sh   d dl mZmZ ddlmZ ddlmZmZ ddlm	Z	 ddd„Z
d	d
„ ZG dd„ deƒZddd„ZdS )é    )ÚIterableÚSequenceé   )ÚAtomic)Úconsume_length_prefixÚconsume_payload)ÚDecodingErrorNc                 K   sX   t | dƒ\}}|t| ƒkrtd| ƒ‚t|tƒr||_||_|S |r*|j|fi |¤ŽS |S )a¨  
    Decode an RLP encoded object in a lazy fashion.

    If the encoded object is a bytestring, this function acts similar to
    :func:`rlp.decode`. If it is a list however, a :class:`LazyList` is
    returned instead. This object will decode the string lazily, avoiding
    both horizontal and vertical traversing as much as possible.

    The way `sedes` is applied depends on the decoded object: If it is a string
    `sedes` deserializes it as a whole; if it is a list, each element is
    deserialized individually. In both cases, `sedes_kwargs` are passed on.
    Note that, if a deserializer is used, only "horizontal" but not
    "vertical lazyness" can be preserved.

    :param rlp: the RLP string to decode
    :param sedes: an object implementing a method ``deserialize(code)`` which
                  is used as described above, or ``None`` if no
                  deserialization should be performed
    :param `**sedes_kwargs`: additional keyword arguments that will be passed
                             to the deserializers
    :returns: either the already decoded and deserialized object (if encoded as
              a string) or an instance of :class:`rlp.LazyList`
    r   z(RLP length prefix announced wrong length)Úconsume_item_lazyÚlenr   Ú
isinstanceÚLazyListÚsedesÚsedes_kwargsÚdeserialize)Úrlpr   r   ÚitemÚend© r   úU/var/www/html/HyperOracle/crypto_trader/venv/lib/python3.10/site-packages/rlp/lazy.pyÚdecode_lazy   s   

r   c           	      C   s\   t | |ƒ\}}}}|tu rt| ||t|ƒ\}}}||fS |tu s"J ‚t| ||| ƒ|| fS )aË  
    Read an item from an RLP string lazily.

    If the length prefix announces a string, the string is read; if it
    announces a list, a :class:`LazyList` is created.

    :param rlp: the rlp string to read from
    :param start: the position at which to start reading
    :returns: a tuple ``(item, end)`` where ``item`` is the read string or a
              :class:`LazyList` and ``end`` is the position of the first
              unprocessed byte.
    )r   Úbytesr   Úlistr   )	r   ÚstartÚpÚtÚlÚsr   Ú_r   r   r   r   r	   7   s   r	   c                   @   s2   e Zd ZdZddd„Zdd„ Zdd„ Zd	d
„ ZdS )r   a½  
    A RLP encoded list which decodes itself when necessary.

    Both indexing with positive indices and iterating are supported.
    Getting the length with :func:`len` is possible as well but requires full
    horizontal encoding.

    :param rlp: the rlp string in which the list is encoded
    :param start: the position of the first payload byte of the encoded list
    :param end: the position of the last payload byte of the encoded list
    :param sedes: a sedes object which deserializes each element of the list,
                  or ``None`` for no deserialization
    :param `**sedes_kwargs`: keyword arguments which will be passed on to the
                             deserializer
    Nc                 K   s4   || _ || _|| _|| _g | _d | _|| _|| _d S ©N)r   r   r   ÚindexÚ	_elementsÚ_lenr   r   )Úselfr   r   r   r   r   r   r   r   Ú__init__^   s   
zLazyList.__init__c                 C   sp   | j | jkrt| jƒ| _t‚| j | jk sJ ‚t| j| j ƒ\}}|| _ | jr0| jj	|fi | j
¤Ž}| j |¡ |S r   )r   r   r
   r    r!   ÚStopIterationr	   r   r   r   r   Úappend)r"   r   r   r   r   r   Únexth   s   zLazyList.nextc                 C   s¾   t |tƒr|jd urtdƒ‚|j}|j}n|}|d }|d u r$| jd }zt| jƒ|k r7|  	¡  t| jƒ|k s,W n t
yM   | j| jksGJ ‚td| ƒ‚w t |tƒrZ| j||… S | j| S )NzStep not supportedr   zIndex %s out of range)r   ÚsliceÚstepÚ	TypeErrorr   Ústopr   r
   r    r&   r$   r   Ú
IndexError)r"   Úir   r*   r   r   r   Ú__getitem__t   s*   


ÿ€þ

zLazyList.__getitem__c                 C   s<   | j sz	 |  ¡  q ty   t| jƒ| _ Y | j S w | j S r   )r!   r&   r$   r
   r    )r"   r   r   r   Ú__len__�   s   ÿþzLazyList.__len__r   )Ú__name__Ú
__module__Ú__qualname__Ú__doc__r#   r&   r-   r.   r   r   r   r   r   M   s    

r   c                 C   sN   t | ƒ}t|tƒs|g}|D ]}t|tƒrtdƒ‚|| }q|r%| |¡S |S )a  
    Get a specific element from an rlp encoded nested list.

    This function uses :func:`rlp.decode_lazy` and, thus, decodes only the
    necessary parts of the string.

    Usage example::

        >>> import rlp
        >>> rlpdata = rlp.encode([1, 2, [3, [4, 5]]])
        >>> rlp.peek(rlpdata, 0, rlp.sedes.big_endian_int)
        1
        >>> rlp.peek(rlpdata, [2, 0], rlp.sedes.big_endian_int)
        3

    :param rlp: the rlp string
    :param index: the index of the element to peek at (can be a list for
                  nested data)
    :param sedes: a sedes used to deserialize the peeked at object, or `None`
                  if no deserialization should be performed
    :raises: :exc:`IndexError` if `index` is invalid (out of range or too many
             levels)
    zToo many indices given)r   r   r   r   r+   r   )r   r   r   Úllr,   r   r   r   Úpeek—   s   



r4   r   )Úcollections.abcr   r   Úatomicr   Úcodecr   r   Ú
exceptionsr   r   r	   r   r4   r   r   r   r   Ú<module>   s    
%J