a
    ñ»j˜2  ã                   @  s¢   d dl mZ d dlZd dlZd dlZd dlmZmZmZm	Z	m
Z
mZ ddlmZ ddlmZmZmZmZ ddlmZ dd	lmZ d
gZe d¡ZG dd
„ d
ƒZdS )é    )ÚannotationsN)ÚAnyÚCallableÚIterableÚIteratorÚLiteralÚoverloadé   )ÚConcurrencyError)Ú	OP_BINARYÚOP_CONTÚOP_TEXTÚFrame)ÚDataé   )ÚDeadlineÚ	Assemblerzutf-8c                   @  sl  e Zd ZdZdddd„ dd„ fdddddd	œd
d„Zd6dddœdd„Zdddœdd„Zeddddœdd„ƒZeddddœdd„ƒZed7ddddœdd„ƒZed8ddddœdd„ƒZed9ddd dœd!d„ƒZd:ddd dœd"d„Zedd#d$œd%d&„ƒZ	edd'd$œd(d&„ƒZ	ed;dd)d$œd*d&„ƒZ	d<dd)d$œd+d&„Z	ddd,œd-d.„Z
dd/œd0d1„Zdd/œd2d3„Zdd/œd4d5„ZdS )=r   aË  
    Assemble messages from frames.

    :class:`Assembler` expects only data frames. The stream of frames must
    respect the protocol; if it doesn't, the behavior is undefined.

    Args:
        pause: Called when the buffer of frames goes above the high water mark;
            should pause reading from the network.
        resume: Called when the buffer of frames goes below the low water mark;
            should resume reading from the network.

    Nc                   C  s   d S ©N© r   r   r   ú>E:\soccer\ml_env\Lib\site-packages\websockets/sync/messages.pyÚ<lambda>&   ó    zAssembler.<lambda>c                   C  s   d S r   r   r   r   r   r   r   '   r   z
int | NonezCallable[[], Any]ÚNone)ÚhighÚlowÚpauseÚresumeÚreturnc                 C  s¤   t  ¡ | _t ¡ | _|d ur,|d u r,|d }|d u rD|d urD|d }|d urt|d urt|dk rdtdƒ‚||k rttdƒ‚|| | _| _|| _	|| _
d| _d| _d| _d S )Né   r   z%low must be positive or equal to zeroz)high must be greater than or equal to lowF)Ú	threadingÚLockÚmutexÚqueueÚSimpleQueueÚframesÚ
ValueErrorr   r   r   r   ÚpausedÚget_in_progressÚclosed)Úselfr   r   r   r   r   r   r   Ú__init__"   s"    	

zAssembler.__init__zfloat | Noner   )Útimeoutr   c                 C  s¬   | j r:z| jjdd�}W q˜ tjy6   tdƒd ‚Y q˜0 n^z4|d ur\|dkr\| jjdd�}n| jjd|d�}W n( tjy–   td|d›d	�ƒd ‚Y n0 |d u r¨tdƒ‚|S )
NF©Úblockústream of frames endedr   T)r-   r+   ztimed out in z.1fÚs)r(   r$   Úgetr"   ÚEmptyÚEOFErrorÚTimeoutError)r)   r+   Úframer   r   r   Úget_next_frameH   s    zAssembler.get_next_framezIterable[Frame])r$   r   c              	   C  sŠ   | j �p g }z| | jjdd�¡ qW n tjy:   Y n0 |D ]}| j |¡ q@|D ]}| j |¡ qVW d   ƒ n1 s|0    Y  d S )NFr,   )r!   Úappendr$   r0   r"   r1   Úput)r)   r$   Zqueuedr4   r   r   r   Úreset_queue^   s    zAssembler.reset_queuezLiteral[True]Ústr)r+   Údecoder   c                 C  s   d S r   r   ©r)   r+   r:   r   r   r   r0   t   s    zAssembler.getzLiteral[False]Úbytesc                 C  s   d S r   r   r;   r   r   r   r0   w   s    c                C  s   d S r   r   r;   r   r   r   r0   z   s    c                C  s   d S r   r   r;   r   r   r   r0   }   s    zbool | Noner   c                 C  s   d S r   r   r;   r   r   r   r0   €   s    c                 C  s|  | j �$ | jrtdƒ‚d| _W d  ƒ n1 s00    Y  �zt|ƒ}|  |jdd�¡}| j � |  ¡  W d  ƒ n1 s|0    Y  |jtu sž|jt	u sžJ ‚|du r°|jtu }|g}|j
�s@z|  |jdd�¡}W n tyò   |  |¡ ‚ Y n0 | j � |  ¡  W d  ƒ n1 �s0    Y  |jtu �s4J ‚| |¡ q¶W d| _nd| _0 d dd„ |D ƒ¡}|�rt| ¡ S |S dS )	a?  
        Read the next message.

        :meth:`get` returns a single :class:`str` or :class:`bytes`.

        If the message is fragmented, :meth:`get` waits until the last frame is
        received, then it reassembles the message and returns it. To receive
        messages frame by frame, use :meth:`get_iter` instead.

        Args:
            timeout: If a timeout is provided and elapses before a complete
                message is received, :meth:`get` raises :exc:`TimeoutError`.
            decode: :obj:`False` disables UTF-8 decoding of text frames and
                returns :class:`bytes`. :obj:`True` forces UTF-8 decoding of
                binary frames and returns :class:`str`.

        Raises:
            EOFError: If the stream of frames has ended.
            UnicodeDecodeError: If a text frame contains invalid UTF-8.
            ConcurrencyError: If two coroutines run :meth:`get` or
                :meth:`get_iter` concurrently.
            TimeoutError: If a timeout is provided and elapses before a
                complete message is received.

        ú&get() or get_iter() is already runningTNF)Zraise_if_elapsedr   c                 s  s   | ]}|j V  qd S r   )Údata)Ú.0r4   r   r   r   Ú	<genexpr>Ä   r   z Assembler.get.<locals>.<genexpr>)r!   r'   r
   r   r5   r+   Úmaybe_resumeÚopcoder   r   Úfinr3   r8   r   r6   Újoinr:   )r)   r+   r:   Údeadliner4   r$   r>   r   r   r   r0   ƒ   s<    $&

ÿ
(zIterator[str])r:   r   c                 C  s   d S r   r   ©r)   r:   r   r   r   Úget_iterÊ   s    zAssembler.get_iterzIterator[bytes]c                 C  s   d S r   r   rF   r   r   r   rG   Í   s    zIterator[Data]c                 C  s   d S r   r   rF   r   r   r   rG   Ð   s    c                 c  s<  | j �$ | jrtdƒ‚d| _W d  ƒ n1 s00    Y  |  ¡ }| j � |  ¡  W d  ƒ n1 sf0    Y  |jtu sˆ|jtu sˆJ ‚|du rš|jtu }|r¸tƒ }| 	|j
|j¡V  n|j
V  |j�s2|  ¡ }| j � |  ¡  W d  ƒ n1 sô0    Y  |jtu �sJ ‚|�r(| 	|j
|j¡V  qÀ|j
V  qÀd| _dS )a©  
        Stream the next message.

        Iterating the return value of :meth:`get_iter` yields a :class:`str` or
        :class:`bytes` for each frame in the message.

        The iterator must be fully consumed before calling :meth:`get_iter` or
        :meth:`get` again. Else, :exc:`ConcurrencyError` is raised.

        This method only makes sense for fragmented messages. If messages aren't
        fragmented, use :meth:`get` instead.

        Args:
            decode: :obj:`False` disables UTF-8 decoding of text frames and
                returns :class:`bytes`. :obj:`True` forces UTF-8 decoding of
                binary frames and returns :class:`str`.

        Raises:
            EOFError: If the stream of frames has ended.
            UnicodeDecodeError: If a text frame contains invalid UTF-8.
            ConcurrencyError: If two coroutines run :meth:`get` or
                :meth:`get_iter` concurrently.

        r=   TNF)r!   r'   r
   r5   rA   rB   r   r   ÚUTF8Decoderr:   r>   rC   r   )r)   r:   r4   Údecoderr   r   r   rG   Ó   s.    $	&
&
)r4   r   c                 C  sL   | j �2 | jrtdƒ‚| j |¡ |  ¡  W d  ƒ n1 s>0    Y  dS )z
        Add ``frame`` to the next message.

        Raises:
            EOFError: If the stream of frames has ended.

        r.   N)r!   r(   r2   r$   r7   Úmaybe_pause)r)   r4   r   r   r   r7     s
    zAssembler.put)r   c                 C  sD   | j du rdS | j ¡ sJ ‚| j ¡ | j kr@| js@d| _|  ¡  dS )z7Pause the writer if queue is above the high water mark.NT)r   r!   Úlockedr$   Úqsizer&   r   ©r)   r   r   r   rJ   *  s    
zAssembler.maybe_pausec                 C  sD   | j du rdS | j ¡ sJ ‚| j ¡ | j kr@| jr@d| _|  ¡  dS )z7Resume the writer if queue is below the low water mark.NF)r   r!   rK   r$   rL   r&   r   rM   r   r   r   rA   7  s    
zAssembler.maybe_resumec                 C  sl   | j �R | jrW d  ƒ dS d| _| jr6| j d¡ | jrJd| _|  ¡  W d  ƒ n1 s^0    Y  dS )z½
        End the stream of frames.

        Calling :meth:`close` concurrently with :meth:`get`, :meth:`get_iter`,
        or :meth:`put` is safe. They will raise :exc:`EOFError`.

        NTF)r!   r(   r'   r$   r7   r&   r   rM   r   r   r   ÚcloseD  s    zAssembler.close)N)N)N)NN)NN)N)N)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r*   r5   r8   r   r0   rG   r7   rJ   rA   rN   r   r   r   r   r      s<   û&G>)Ú
__future__r   Úcodecsr"   r   Útypingr   r   r   r   r   r   Ú
exceptionsr
   r$   r   r   r   r   r   Úutilsr   Ú__all__ÚgetincrementaldecoderrH   r   r   r   r   r   Ú<module>   s    
