
    (j                     $    S r SSKr " S S5      rg)zt
Async version of gunicorn/http/unreader.py for ASGI workers.

Provides async reading with pushback buffer support.
    Nc                   P    \ rS rSrSrSS jrS rS rS rSS jr	S	 r
S
 rS rSrg)AsyncUnreader   a$  Async socket reader with pushback buffer support.

This class wraps an asyncio StreamReader and provides the ability
to "unread" data back into a buffer for re-parsing.

Performance optimization: Reuses BytesIO buffer with truncate/seek
instead of creating new objects to reduce GC pressure.
c                 ^    Xl         [        R                  " 5       U l        X l        SU l        g)z}Initialize the async unreader.

Args:
    reader: asyncio.StreamReader instance
    max_chunk: Maximum bytes to read at once
r   N)readerioBytesIObuf	max_chunk
_buf_start)selfr   r   s      N/var/www/html/KUNJ/venv/lib/python3.13/site-packages/gunicorn/asgi/unreader.py__init__AsyncUnreader.__init__   s"     ::<"    c                 ~    U R                   R                  S5        U R                   R                  S5        SU l        g)z7Reset buffer for reuse instead of creating new BytesIO.r   N)r
   seektruncater   r   s    r   _reset_bufferAsyncUnreader._reset_buffer$   s+    a!r   c                     U R                   R                  U R                  5        U R                   R                  5       nU R	                  5         U$ )z'Get all buffered data and reset buffer.)r
   r   r   readr   )r   datas     r   _get_buffered_data AsyncUnreader._get_buffered_data*   s6    doo&xx}}r   c                 r    U R                   R                  S[        R                  5      nXR                  -
  $ )zGet size of buffered data.r   )r
   r   r   SEEK_ENDr   )r   ends     r   _buffer_sizeAsyncUnreader._buffer_size1   s'    hhmmAr{{+__$$r   Nc                   #    Ub   [        U[        5      (       d  [        S5      eUb  US:X  a  gUS:  a  SnU R                  5       nUc  US:  a  U R	                  5       $ Uc  U R                  5       I Sh  vN nU$ X!:  a  U R                  5       I Sh  vN nU(       d  U R	                  5       $ U R                  R                  S[        R                  5        U R                  R                  U5        U[        U5      -  nX!:  a  M  U R                  R                  U R                  5        U R                  R                  U5      nU =R                  U-  sl        U R                  S:  aL  U R                  R                  5       nU R                  5         U(       a  U R                  R                  U5        U$  GNH GN,7f)zRead data from the stream, using buffered data first.

Args:
    size: Number of bytes to read. If None, returns all buffered
          data or reads a single chunk.

Returns:
    bytes: Data read from buffer or stream
Nz&size parameter must be an int or long.r   r       )
isinstanceint	TypeErrorr    r   _read_chunkr
   r   r   r   writelenr   r   r   )r   sizebuf_sizechunkr   	remainings         r   r   AsyncUnreader.read6   sn     JtS$9$9DEEqyax$$& <HqL**,,<**,,EL o**,,E..00HHMM!R[[)HHNN5!E
"H o 	doo&xx}}T" 	4 ??T!I y)5 -
 -s,   A5G7F?8GGA3GB4GGc                    #     U R                   R                  U R                  5      I Sh  vN $  N! [         a     gf = f7f)z0Read a chunk of data from the underlying stream.Nr   )r   r   r   	Exceptionr   s    r   r'   AsyncUnreader._read_chunkk   s:     	))$..9999 		s/   A(3 13 A3 
A AA  Ac                 .   U(       a  U R                   R                  U R                  5        U R                   R                  5       nU R	                  5         U R                   R                  U5        U(       a  U R                   R                  U5        ggg)zPush data back into the buffer for re-reading.

Args:
    data: bytes to push back

Note: This prepends data to the buffer so it will be read first.
N)r
   r   r   r   r   r(   )r   r   existings      r   unreadAsyncUnreader.unreadr   se     HHMM$//*xx}}H  HHNN4 x(  r   c                 (    U R                  5       S:  $ )z-Check if there's data in the pushback buffer.r   )r    r   s    r   has_buffered_dataAsyncUnreader.has_buffered_data   s      "Q&&r   )r   r
   r   r   )r#   )N)__name__
__module____qualname____firstlineno____doc__r   r   r   r    r   r'   r4   r7   __static_attributes__ r   r   r   r      s0    
%
3j)&'r   r   )r=   r   r   r?   r   r   <module>r@      s   
 
y' y'r   