U
    h~                     @   s   d Z ddlZddlZddlmZmZmZ ddlmZ ddlm	Z	 ddl
mZ eeddd  Zejejd	ZG d
d dZdS )z6
This module contains the BinaryReader utility class.
    N)datetime	timedeltatimezone   )TypeNotFoundError)	tlobjects)core_objects   )tzinfoc                   @   s   e Zd ZdZdd Zdd Zd/ddZd0d	d
Zdd Zdd Z	d1ddZ
d2d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 )3BinaryReaderz2
    Small utility class to read binary data.
    c                 C   s   |pd| _ d| _d | _d S )N    r   )streamposition_last)selfdata r   D/tmp/pip-unpacked-wheel-t5wbaijj/telethon/extensions/binaryreader.py__init__   s    
zBinaryReader.__init__c                 C   s&   t d| j| j\}|  jd7  _|S )zReads a single byte value.z<B   structunpack_fromr   r   r   valuer   r   r   	read_byte   s    zBinaryReader.read_byteTc                 C   s2   |rdnd}t || j| j\}|  jd7  _|S )z!Reads an integer (4 bytes) value.z<iz<I   r   r   signedfmtr   r   r   r   read_int$   s    zBinaryReader.read_intc                 C   s2   |rdnd}t || j| j\}|  jd7  _|S )z%Reads a long integer (8 bytes) value.z<qz<Q   r   r   r   r   r   	read_long+   s    zBinaryReader.read_longc                 C   s&   t d| j| j\}|  jd7  _|S )z,Reads a real floating point (4 bytes) value.z<fr   r   r   r   r   r   
read_float2   s    zBinaryReader.read_floatc                 C   s&   t d| j| j\}|  jd7  _|S )z,Reads a real floating point (8 bytes) value.z<dr!   r   r   r   r   r   read_double8   s    zBinaryReader.read_doublec                 C   s   t j| |d d|dS )z"Reads a n-bits long integer value.r!   little)	byteorderr   )int
from_bytesread)r   bitsr   r   r   r   read_large_int>   s
      zBinaryReader.read_large_intc                 C   s   |dkr.| j | j| j|  }|  j|7  _n"| j | jd }|  jt|7  _|dkrt||krtd|t|t|t| j|| _|S )z<Read the given amount of bytes, or -1 to read all remaining.r   Nz=No more data left to read (need {}, got {}: {}); last read {})r   r   lenBufferErrorformatreprr   )r   lengthresultr   r   r   r)   C   s        zBinaryReader.readc                 C   s   | j S )z?Gets the byte array representing the current buffer as a whole.r   r   r   r   r   	get_bytesT   s    zBinaryReader.get_bytesc                 C   sr   |   }|dkr:|   |   d> B |   d> B }|d }n|}|d d }| |}|dkrnd| }| | |S )zi
        Reads a Telegram-encoded byte array, without the need of
        specifying its length.
           r!      r   r   r   )r   r)   )r   Z
first_byter1   paddingr   r   r   r   tgread_bytes\   s    



zBinaryReader.tgread_bytesc                 C   s   t |  dddS )z Reads a Telegram-encoded string.zutf-8replace)encodingerrors)strr9   r4   r   r   r   tgread_stringq   s    zBinaryReader.tgread_stringc                 C   s:   | j dd}|dkrdS |dkr$dS tdt|dS )zReads a Telegram boolean value.Fr      u2 T   7x zInvalid boolean code {}N)r    RuntimeErrorr/   hexr   r   r   r   tgread_boolu   s    zBinaryReader.tgread_boolc                 C   s   |   }tt|d S )zbReads and converts Unix time (used by Telegram)
           into a Python datetime object.
        )seconds)r    _EPOCHr   r   r   r   r   tgread_date   s    zBinaryReader.tgread_datec                    s    j dd}t|d}|dkr|}|dkr0dS |dkr<dS |dkr^ fdd	t   D S t|d}|dkr d
   }t|  } 	| ||
 S )zReads a Telegram object.Fr?   Nr@   TrA   ĵc                    s   g | ]}   qS r   tgread_object.0_r4   r   r   
<listcomp>   s     z.BinaryReader.tgread_object.<locals>.<listcomp>)r    r   getranger   seektell_positionr   r)   set_positionZfrom_reader)r   Zconstructor_idZclazzr   poserrorr   r4   r   rJ      s$    

zBinaryReader.tgread_objectc                    s6   d j ddkrtd   } fddt|D S )z,Reads a vector (a list) of Telegram objects.rH   Fr?   z-Invalid constructor code, vector was expectedc                    s   g | ]}   qS r   rI   rK   r4   r   r   rN      s     z.BinaryReader.tgread_vector.<locals>.<listcomp>)r    rB   rQ   )r   countr   r4   r   tgread_vector   s    zBinaryReader.tgread_vectorc                 C   s
   d| _ dS )z.Closes the reader, freeing the BytesIO stream.r   Nr3   r4   r   r   r   close   s    zBinaryReader.closec                 C   s   | j S )z)Tells the current position on the stream.r   r4   r   r   r   rS      s    zBinaryReader.tell_positionc                 C   s
   || _ dS )z(Sets the current position on the stream.NrZ   )r   r   r   r   r   rT      s    zBinaryReader.set_positionc                 C   s   |  j |7  _ dS )zz
        Seeks the stream position given an offset from the current position.
        The offset may be negative.
        NrZ   )r   offsetr   r   r   rR      s    zBinaryReader.seekc                 C   s   | S Nr   r4   r   r   r   	__enter__   s    zBinaryReader.__enter__c                 C   s   |    d S r\   )rY   )r   exc_typeexc_valexc_tbr   r   r   __exit__   s    zBinaryReader.__exit__N)T)T)T)r,   )__name__
__module____qualname____doc__r   r   r    r"   r#   r$   r+   r)   r5   r9   r>   rD   rG   rJ   rX   rY   rS   rT   rR   r]   ra   r   r   r   r   r      s,   	





r   )re   r   timer   r   r   r<   r   Ztl.alltlobjectsr   Ztl.corer   gmtimeZ_EPOCH_NAIVEr:   utcrF   r   r   r   r   r   <module>   s   