
    ;Ig+                        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 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j*                  d      Z G d d
      Zy)    )annotationsN)AnyCallableIterableIterator   )ConcurrencyError)	OP_BINARYOP_CONTOP_TEXTFrame)Data   )Deadline	Assemblerzutf-8c                  ~    e Zd ZdZddd d f	 	 	 	 	 	 	 	 	 ddZdddZddZdddZddd	Zdd
Z	ddZ
ddZddZy)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                      y N r       U/var/www/html/answerous/venv/lib/python3.12/site-packages/websockets/sync/messages.py<lambda>zAssembler.<lambda>&       r   c                      y r   r   r   r   r   r   zAssembler.<lambda>'   r   r   c                8   t        j                         | _        t        j                         | _        |||dz  }|||dz  }|"| |dk  rt        d      ||k  rt        d      ||c| _        | _        || _	        || _
        d| _        d| _        d| _        y )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
ValueErrorhighlowpauseresumepausedget_in_progressclosed)selfr$   r%   r&   r'   s        r   __init__zAssembler.__init__"   s     ^^%
 8=7H7H7J !)C<CO7DQw !HIIcz !LMM"C	48
  % r   c                F   | j                   r	 | j                  j                  d      }n	 | j                  j                  d|      }|t        d      |S # t        j                  $ r t        d      d w xY w# t        j                  $ r t        d|dd      d w xY w)	NFblockstream of frames endedT)r/   timeoutztimed out in z.1fs)r*   r"   getr    EmptyEOFErrorTimeoutError)r+   r1   frames      r   get_next_framezAssembler.get_next_frameH   s     ;;Ce4MdGD =344 ;; C78dBC
 ;; M"]73-q#ABLMs   A A;  A8;%B c                b   | j                   5  g }	 	 |j                  | j                  j                  d             ,# t        j
                  $ r Y nw xY w|D ]  }| j                  j                  |        |D ]  }| j                  j                  |        	 d d d        y # 1 sw Y   y xY w)NFr.   )r   appendr"   r3   r    r4   put)r+   r"   queuedr7   s       r   reset_queuezAssembler.reset_queueY   s     ZZ 	'FMM$++///">? ;;  '&'   '&'	' 	' 	's'   B%->AB%AAB%%B.c                   | j                   5  | j                  rt        d      d| _        ddd       	 t        |      }| j	                  |j                               }| j                   5  | j                          ddd       |j                  t        u s|j                  t        u sJ ||j                  t        u }|g}|j                  sw	 | j	                  |j                               }| j                   5  | j                          ddd       |j                  t        u sJ |j                  |       |j                  swd| _        dj                  d |D              }|r|j!                         S |S # 1 sw Y   MxY w# 1 sw Y   
xY w# t        $ r | j                  |        w xY w# 1 sw Y   xY w# d| _        w xY w)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 runningTNFr   c              3  4   K   | ]  }|j                     y wr   )data).0r7   s     r   	<genexpr>z Assembler.get.<locals>.<genexpr>   s     7u

7s   )r   r)   r	   r   r8   r1   maybe_resumeopcoder   r
   finr6   r=   r   r:   joindecode)r+   r1   rH   deadliner7   r"   rA   s          r   r3   zAssembler.getl   s   4 ZZ 	(##&'OPP#'D 	(	)(H ''(8(8(:;E $!!#$<<7*elli.GGG~0WF ii //0@0@0BCE ZZ (%%'(||w...e$ ii $)D xx777;;= KS	( 	($ $ $  $$V,	
( ( $)D s_   E76F< +F<AF< F -F< 9F0
9F< 7FF	F< F--F< 0F95F< <	Gc              #  f  K   | j                   5  | j                  rt        d      d| _        ddd       | j                         }| j                   5  | j	                          ddd       |j
                  t        u s|j
                  t        u sJ ||j
                  t        u }|r3t               }|j                  |j                  |j                         n|j                   |j                  s| j                         }| j                   5  | j	                          ddd       |j
                  t        u sJ |r)j                  |j                  |j                         n|j                   |j                  sd| _        y# 1 sw Y   _xY w# 1 sw Y   7xY w# 1 sw Y   xY ww)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	   r8   rD   rE   r   r
   UTF8DecoderrH   rA   rF   r   )r+   rH   r7   decoders       r   get_iterzAssembler.get_iter   s`    2 ZZ 	(##&'OPP#'D 	( ##%ZZ 	 	 ||w&%,,)*CCC>\\W,F!mG..UYY77** ))'')E $!!#$<<7***nnUZZ;;jj  ))  %G	( 	(	  	 $ $sS   F1F$F1F#B-F1F%!A!F1F1FF1F"F1%F.*F1c                    | j                   5  | j                  rt        d      | j                  j	                  |       | j                          ddd       y# 1 sw Y   yxY w)z
        Add ``frame`` to the next message.

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

        r0   N)r   r*   r5   r"   r;   maybe_pause)r+   r7   s     r   r;   zAssembler.put   sO     ZZ 	{{788KKOOE"	 	 	s   AAA"c                    | j                   y| j                  j                         sJ | j                  j	                         | j                   kD  r%| j
                  sd| _        | j                          yyy)z7Pause the writer if queue is above the high water mark.NT)r$   r   lockedr"   qsizer(   r&   r+   s    r   rO   zAssembler.maybe_pause  s`     99zz  """ ;;*4;;DKJJL 4?*r   c                    | j                   y| j                  j                         sJ | j                  j	                         | j                   k  r%| j
                  rd| _        | j                          yyy)z7Resume the writer if queue is below the low water mark.NF)r%   r   rQ   r"   rR   r(   r'   rS   s    r   rD   zAssembler.maybe_resume  s`     88zz  """ ;;$((*t{{DKKKM 0;*r   c                    | j                   5  | j                  r
	 ddd       yd| _        | j                  r| j                  j	                  d       ddd       y# 1 sw Y   yxY w)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;   rS   s    r   closezAssembler.close"  sV     ZZ 	&{{	& 	& DK##%	& 	& 	&s   A.AA$)
r$   
int | Noner%   rW   r&   Callable[[], Any]r'   rX   returnNoner   )r1   float | NonerY   r   )r"   zIterable[Frame]rY   rZ   )NN)r1   r[   rH   bool | NonerY   r   )rH   r\   rY   zIterator[Data])r7   r   rY   rZ   )rY   rZ   )__name__
__module____qualname____doc__r,   r8   r=   r3   rM   r;   rO   rD   rV   r   r   r   r   r      sv       #/$0$$ $ !	$
 "$ 
$L"'&CJ<%|2&r   )
__future__r   codecsr    r   typingr   r   r   r   
exceptionsr	   r"   r
   r   r   r   r   utilsr   __all__getincrementaldecoderrK   r   r   r   r   <module>rh      sM    "    4 4 ) 7 7   -*f**73_& _&r   