a
    Ñšhñ*  ã                   @  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 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	gZe d
¡ZedƒZG dd„ dee ƒZG dd	„ d	ƒZdS )é    )ÚannotationsN)ÚAsyncIteratorÚIterable)ÚAnyÚCallableÚGenericÚLiteralÚTypeVarÚoverloadé   )ÚConcurrencyError)Ú	OP_BINARYÚOP_CONTÚOP_TEXTÚFrame)ÚDataÚ	Assemblerzutf-8ÚTc                   @  sl   e Zd ZdZddœdd„Zddœdd„Zd	dd
œdd„Zddd	dœdd„Zdddœdd„Zddœdd„Z	dS )ÚSimpleQueuez…
    Simplified version of :class:`asyncio.Queue`.

    Provides only the subset of functionality needed by :class:`Assembler`.

    ÚNone©Úreturnc                 C  s   t  ¡ | _d | _t ¡ | _d S ©N)ÚasyncioZget_running_loopÚloopÚ
get_waiterÚcollectionsÚdequeÚqueue©Úself© r!   úV/wd/webapps/venvs/v2025_4um/lib/python3.9/site-packages/websockets/asyncio/messages.pyÚ__init__   s    
zSimpleQueue.__init__Úintc                 C  s
   t | jƒS r   )Úlenr   r   r!   r!   r"   Ú__len__"   s    zSimpleQueue.__len__r   )Úitemr   c                 C  s0   | j  |¡ | jdur,| j ¡ s,| j d¡ dS )z+Put an item into the queue without waiting.N)r   Úappendr   ÚdoneZ
set_result)r    r'   r!   r!   r"   Úput%   s    zSimpleQueue.putTÚbool)Úblockr   c                 Ã  sn   | j sd|stdƒ‚| jdu s$J dƒ‚| j ¡ | _z | jI dH  W | j ¡  d| _n| j ¡  d| _0 | j  ¡ S )z?Remove and return an item from the queue, waiting if necessary.ústream of frames endedNzcannot call get() concurrently)r   ÚEOFErrorr   r   Zcreate_futureÚcancelÚpopleft)r    r,   r!   r!   r"   Úget+   s    
ÿ
zSimpleQueue.getzIterable[T])Úitemsr   c                 C  s0   | j du sJ dƒ‚| jr J dƒ‚| j |¡ dS )z)Put back items into an empty, idle queue.Nz%cannot reset() while get() is runningz&cannot reset() while queue isn't empty)r   r   Úextend)r    r2   r!   r!   r"   Úreset9   s    zSimpleQueue.resetc                 C  s(   | j dur$| j  ¡ s$| j  tdƒ¡ dS )z8Close the queue, raising EOFError in get() if necessary.Nr-   )r   r)   Zset_exceptionr.   r   r!   r!   r"   Úabort?   s    zSimpleQueue.abortN)T)
Ú__name__Ú
__module__Ú__qualname__Ú__doc__r#   r&   r*   r1   r4   r5   r!   r!   r!   r"   r      s   r   c                   @  s  e Zd ZdZdddd„ dd„ fd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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$œd%d&„Z	dd$œd'd(„Z
dd$œd)d*„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 r   r!   r!   r!   r!   r"   Ú<lambda>Y   ó    zAssembler.<lambda>c                   C  s   d S r   r!   r!   r!   r!   r"   r:   Z   r;   z
int | NonezCallable[[], Any]r   )ÚhighÚlowÚpauseÚresumer   c                 C  s˜   t ƒ | _|d ur |d u r |d }|d u r8|d ur8|d }|d urh|d urh|dk rXtdƒ‚||k rht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)
r   ÚframesÚ
ValueErrorr<   r=   r>   r?   ÚpausedÚget_in_progressÚclosed)r    r<   r=   r>   r?   r!   r!   r"   r#   U   s     zAssembler.__init__zLiteral[True]Ústr)Údecoder   c                 Ã  s   d S r   r!   ©r    rG   r!   r!   r"   r1   w   s    zAssembler.getzLiteral[False]Úbytesc                 Ã  s   d S r   r!   rH   r!   r!   r"   r1   z   s    zbool | Noner   c                 Ã  s   d S r   r!   rH   r!   r!   r"   r1   }   s    c                 Ã  s  | j rtdƒ‚d| _ z¾| j | j ¡I dH }|  ¡  |jtu sL|jtu sLJ ‚|du r^|jtu }|g}|j	sÊz| j | j ¡I dH }W n" t
jy¦   | j |¡ ‚ Y n0 |  ¡  |jtu s¾J ‚| |¡ qdW d| _ nd| _ 0 d dd„ |D ƒ¡}|rü| ¡ S |S dS )a0  
        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:
            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.

        ú&get() or get_iter() is already runningTNFr;   c                 s  s   | ]}|j V  qd S r   )Údata)Ú.0Úframer!   r!   r"   Ú	<genexpr>¶   r;   z Assembler.get.<locals>.<genexpr>)rD   r   rA   r1   rE   Úmaybe_resumeÚopcoder   r   Úfinr   ÚCancelledErrorr4   r   r(   ÚjoinrG   )r    rG   rM   rA   rK   r!   r!   r"   r1   €   s0    
zAsyncIterator[str]c                 C  s   d S r   r!   rH   r!   r!   r"   Úget_iter¼   s    zAssembler.get_iterzAsyncIterator[bytes]c                 C  s   d S r   r!   rH   r!   r!   r"   rT   ¿   s    zAsyncIterator[Data]c                 C  s   d S r   r!   rH   r!   r!   r"   rT   Â   s    c                 C s  | j rtdƒ‚d| _ z| j | j ¡I dH }W n tjyJ   d| _ ‚ Y n0 |  ¡  |jt	u sl|jt
u slJ ‚|du r~|jt	u }|rœtƒ }| |j|j¡V  n|jV  |jsø| j | j ¡I dH }|  ¡  |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` asynchronously 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.

        rJ   TNF)rD   r   rA   r1   rE   r   rR   rO   rP   r   r   ÚUTF8DecoderrG   rK   rQ   r   )r    rG   rM   Údecoderr!   r!   r"   rT   Å   s0    	

r   )rM   r   c                 C  s&   | j rtdƒ‚| j |¡ |  ¡  dS )z
        Add ``frame`` to the next message.

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

        r-   N)rE   r.   rA   r*   Úmaybe_pause)r    rM   r!   r!   r"   r*     s    zAssembler.putr   c                 C  s6   | j du rdS t| jƒ| j kr2| js2d| _|  ¡  dS )z7Pause the writer if queue is above the high water mark.NT)r<   r%   rA   rC   r>   r   r!   r!   r"   rW     s
    
zAssembler.maybe_pausec                 C  s6   | j du rdS t| jƒ| j kr2| jr2d| _|  ¡  dS )z7Resume the writer if queue is below the low water mark.NF)r=   r%   rA   rC   r?   r   r!   r!   r"   rO   !  s
    
zAssembler.maybe_resumec                 C  s   | j r
dS d| _ | j ¡  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`.

        NT)rE   rA   r5   r   r!   r!   r"   Úclose,  s    zAssembler.close)N)N)N)N)r6   r7   r8   r9   r#   r
   r1   rT   r*   rW   rO   rX   r!   r!   r!   r"   r   E   s0   û"<C)Ú
__future__r   r   Úcodecsr   Úcollections.abcr   r   Útypingr   r   r   r   r	   r
   Ú
exceptionsr   rA   r   r   r   r   r   Ú__all__ÚgetincrementaldecoderrU   r   r   r   r!   r!   r!   r"   Ú<module>   s    
0