U
    <æ{f%  ã                   @  sz   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	 ddl
mZmZ ddlmZ dgZe d¡ZG d	d„ dƒZdS )
é    )ÚannotationsN)ÚIteratorÚListÚOptionalÚcasté   )ÚFrameÚOpcode)ÚDataÚ	Assemblerzutf-8c                   @  s\   e Zd ZdZddœdd„Zdddd	œd
d„Zddœdd„Zdddœdd„Zddœdd„ZdS )r   z)
    Assemble messages from frames.

    ÚNone)Úreturnc                 C  sF   t  ¡ | _t  ¡ | _t  ¡ | _d| _d| _d | _g | _	d | _
d| _d S )NF)Ú	threadingÚLockÚmutexÚEventÚmessage_completeÚmessage_fetchedÚget_in_progressÚput_in_progressÚdecoderÚchunksÚchunks_queueÚclosed©Úself© r   úW/var/www/html/Darija-Ai-API/env/lib/python3.8/site-packages/websockets/sync/messages.pyÚ__init__   s    



zAssembler.__init__NzOptional[float]r
   )Útimeoutr   c              
   C  sî   | j ( | jrtdƒ‚| jr$tdƒ‚d| _W 5 Q R X | j |¡}| j ž d| _|sdtd|d›dƒ‚| jrrtdƒ‚| j ¡ s€t	‚| j 
¡  | jdkr˜d	nd
}| | j¡}| j ¡ r¶t	‚| j ¡  g | _| jdksÔt	‚|W  5 Q R £ S Q R X 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`.

        Raises:
            EOFError: If the stream of frames has ended.
            RuntimeError: If two threads run :meth:`get` or :meth:``get_iter`
                concurrently.

        ústream of frames endedú"get or get_iter is already runningTFztimed out in z.1fÚsNó    Ú )r   r   ÚEOFErrorr   ÚRuntimeErrorr   ÚwaitÚTimeoutErrorÚis_setÚAssertionErrorÚclearr   Újoinr   r   Úsetr   )r   r   Ú	completedÚjoinerÚmessager   r   r   Úget;   s,    

zAssembler.getzIterator[Data]c              	   c  sú   | j Z | jrtdƒ‚| jr$tdƒ‚| j}g | _tdt ¡ ƒ| _	| j
 ¡ rV| j	 d¡ d| _W 5 Q R X |E dH  | j	 ¡ }|dkr„qŒ|V  qp| j ^ d| _| j
 ¡ s¨t‚| j
 ¡  | jrÀtdƒ‚| j ¡ rÎt‚| j ¡  | jg ksæt‚d| _	W 5 Q R X dS )aw  
        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:`RuntimeError` is raised.

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

        Raises:
            EOFError: If the stream of frames has ended.
            RuntimeError: If two threads run :meth:`get` or :meth:``get_iter`
                concurrently.

        r    r!   z!queue.SimpleQueue[Optional[Data]]NTF)r   r   r%   r   r&   r   r   ÚqueueÚSimpleQueuer   r   r)   Úputr1   r*   r+   r   r-   )r   r   Úchunkr   r   r   Úget_iterw   s:    ý	




zAssembler.get_iterr   )Úframer   c              	   C  sp  | j  | jrtdƒ‚| jr&tdƒ‚|jtjkr@tdd| _	n0|jtj
krTd| _	n|jtjkrbnW 5 Q R £ dS | j	dk	rŽ| j	 |j|j¡}n|j}| jdkr¬| j |¡ n| j |¡ |jsÌW 5 Q R £ dS | j ¡ rÚt‚| j ¡  | jdk	rú| j d¡ | j ¡ r
t‚d| _W 5 Q R X | j ¡  | j < d| _| j ¡ sBt‚| j ¡  | jr\tdƒ‚d| _	W 5 Q R X dS )a  
        Add ``frame`` to the next message.

        When ``frame`` is the final frame in a message, :meth:`put` waits until
        the message is fetched, either by calling :meth:`get` or by fully
        consuming the return value of :meth:`get_iter`.

        :meth:`put` assumes that the stream of frames respects the protocol. If
        it doesn't, the behavior is undefined.

        Raises:
            EOFError: If the stream of frames has ended.
            RuntimeError: If two threads run :meth:`put` concurrently.

        r    zput is already runningÚstrict)ÚerrorsNTF)r   r   r%   r   r&   Úopcoder	   ZTEXTÚUTF8Decoderr   ÚBINARYZCONTÚdecodeÚdataZfinr   r   Úappendr4   r   r)   r*   r-   r   r'   r+   )r   r7   r>   r   r   r   r4   ¹   sD    






zAssembler.putc              	   C  sf   | j V | jrW 5 Q R £ dS d| _| jrH| j ¡  | jdk	rH| j d¡ | jrX| j ¡  W 5 Q R X dS )z¾
        End the stream of frames.

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

        NT)	r   r   r   r   r-   r   r4   r   r   r   r   r   r   Úclose  s    

zAssembler.close)N)	Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   r1   r6   r4   r@   r   r   r   r   r      s   $<BJ)Ú
__future__r   Úcodecsr2   r   Útypingr   r   r   r   Úframesr   r	   r
   Ú__all__Úgetincrementaldecoderr;   r   r   r   r   r   Ú<module>   s   
