a
    њh?1                     @  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   S/wd/webapps/venvs/v2025_4um/lib/python3.9/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 q0 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 rt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 sJ |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 || qW 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 sJ |du r|jtu }|rt }|	|j
|jV  n|j
V  |js2|  }| j  |   W d   n1 s0    Y  |jtu sJ |r(|	|j
|jV  q|j
V  qd| _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    
