o
    Yiy+                     @  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                   @  sN   e Zd ZdZdddZdddZdddZddddZdddZdddZ	dS )SimpleQueuez
    Simplified version of :class:`asyncio.Queue`.

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

    returnNonec                 C  s   t  | _d | _t | _d S N)asyncioZget_running_looploop
get_waitercollectionsdequequeueself r    U/home/kim/smarthome/.venv/lib/python3.10/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__itemr   c                 C  s8   | j | | jdur| j s| jd dS dS dS )zPut an item into the queue.N)r   appendr   doneZ
set_result)r   r&   r    r    r!   put%   s   zSimpleQueue.putTblockboolc                   sp   | j s3|s
td| jdu sJ d| j | _z| jI dH  W | j  d| _n	| j  d| _w | 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.getitemsIterable[T]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   r1   r    r    r!   reset9   s   zSimpleQueue.resetc                 C  s0   | j dur| j  s| j td dS dS 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r   r   )r   r#   )r&   r   r   r   )T)r*   r+   r   r   )r1   r2   r   r   )
__name__
__module____qualname____doc__r"   r%   r)   r0   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Zed/ddZed0ddZed1d2ddZd1d2ddZed3ddZed4d dZed1d5d"dZd1d5d#dZd6d&d'Zd7d(d)Z	d7d*d+Z
d7d,d-ZdS )8r   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     d S r   r    r    r    r    r!   <lambda>X       zAssembler.<lambda>c                   C  r;   r   r    r    r    r    r!   r<   Y   r=   high
int | NonelowpauseCallable[[], Any]resumer   r   c                 C  s   t  | _|d ur|d u r|d }|d u r|d ur|d }|d ur4|d ur4|dk r,td||k r4t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@   rA   rC   pausedget_in_progressclosed)r   r>   r@   rA   rC   r    r    r!   r"   T   s    
zAssembler.__init__decodeLiteral[True]strc                      d S r   r    r   rJ   r    r    r!   r0   v      zAssembler.getLiteral[False]bytesc                   rM   r   r    rN   r    r    r!   r0   y   rO   bool | Noner   c                   rM   r   r    rN   r    r    r!   r0   |   rO   c                   s  | j rtdd| _ z_| j| j I dH }|   |jtu s'|jtu s'J |du r0|jtu }|g}|j	sfz| j| j I dH }W n t
jyR   | j|  w |   |jtu s^J || |j	r6W d| _ nd| _ w ddd |D }|r| S |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 runningTNF    c                 s  s    | ]}|j V  qd S r   )data).0framer    r    r!   	<genexpr>   s    z Assembler.get.<locals>.<genexpr>)rH   r   rE   r0   rI   maybe_resumeopcoder   r   finr   CancelledErrorr4   r   r'   joinrJ   )r   rJ   rW   rE   rU   r    r    r!   r0      s8   

AsyncIterator[str]c                 C  r;   r   r    rN   r    r    r!   get_iter      zAssembler.get_iterAsyncIterator[bytes]c                 C  r;   r   r    rN   r    r    r!   r_      r`   AsyncIterator[Data]c                 C  r;   r   r    rN   r    r    r!   r_      r`   c                 C s  | j rtdd| _ z| j| j I dH }W n tjy$   d| _  w |   |jt	u s5|jt
u s5J |du r>|jt	u }|rMt }||j|jV  nt|jV  |js| j| j I dH }|   |jtu slJ |rx||j|jV  nt|jV  |jrVd| _ 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.

        rS   TNF)rH   r   rE   r0   rI   r   r\   rY   rZ   r   r   UTF8DecoderrJ   rU   r[   rQ   r   )r   rJ   rW   decoderr    r    r!   r_      s6   	

rW   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)rI   r-   rE   r)   maybe_pause)r   rW   r    r    r!   r)   
  s   zAssembler.putc                 C  s>   | j du rdS t| j| j kr| jsd| _|   dS dS dS )z7Pause the writer if queue is above the high water mark.NT)r>   r$   rE   rG   rA   r   r    r    r!   re        
zAssembler.maybe_pausec                 C  s>   | j du rdS t| j| j kr| jrd| _|   dS dS dS )z7Resume the writer if queue is below the low water mark.NF)r@   r$   rE   rG   rC   r   r    r    r!   rY   #  rf   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)rI   rE   r5   r   r    r    r!   close.  s   zAssembler.close)
r>   r?   r@   r?   rA   rB   rC   rB   r   r   )rJ   rK   r   rL   )rJ   rP   r   rQ   r   )rJ   rR   r   r   )rJ   rK   r   r^   )rJ   rP   r   ra   )rJ   rR   r   rb   )rW   r   r   r   r6   )r7   r8   r9   r:   r"   r
   r0   r_   r)   re   rY   rg   r    r    r    r!   r   E   s2    "=
E

)
__future__r   r   codecsr   collections.abcr   r   typingr   r   r   r   r	   r
   
exceptionsr   rE   r   r   r   r   r   __all__getincrementaldecoderrc   r   r   r   r    r    r    r!   <module>   s     
0