o
    .jV                     @  sb   d Z ddlmZ ddlmZmZmZ ddlmZm	Z	 ddl
mZmZmZmZ dZG dd	 d	Zd
S )zy
h2/frame_buffer
~~~~~~~~~~~~~~~

A data structure that provides a way to iterate over a byte buffer in terms of
frames.
    )annotations   )FrameDataMissingErrorFrameTooLargeErrorProtocolError)InvalidDataErrorInvalidFrameError)ContinuationFrameFrameHeadersFramePushPromiseFrame@   c                   @  sB   e Zd ZdZdddZdd Zdd Zd	d
 Zdd Zdd Z	dS )FrameBufferz
    This is a data structure that expects to act as a buffer for HTTP/2 data
    that allows iteraton in terms of H2 frames.
    Fc                 C  s2   t  | _d| _|rdnd| _t| j| _g | _d S )Nr   s   PRI * HTTP/2.0

SM

    )	bytearray_datamax_frame_size	_preamblelen_preamble_len_headers_buffer)selfserver r   E/home/thesage/.local/lib/python3.10/site-packages/jh2/frame_buffer.py__init__    s
   
zFrameBuffer.__init__c                 C  sx   | j r3t|}t| j |}| jd| |d| krtd||d }|  j |8  _ | j|d | _|  j|7  _dS )zs
        Add more data to the frame buffer.

        :param data: A bytestring containing the byte buffer.
        NzInvalid HTTP/2 preamble.)r   r   minr   r   r   )r   datadata_lenof_which_preambler   r   r   add_data'   s   zFrameBuffer.add_datac                 C  s    || j krtd|| j f dS )zB
        Confirm that the frame is an appropriate length.
        z*Received overlong frame: length %d, max %dN)r   r   )r   lengthr   r   r   _validate_frame_length:   s   
z"FrameBuffer._validate_frame_lengthc                 C  s   | j rS| j d j}|duot|to|j|k}|std| j | t| j tkr.tdd|jv rO| j d }|j	d d
dd | j D |_g | _ |S d}|S t|ttfrgd|jvrg| j | d}|S )	z
        Updates the internal header buffer. Returns a frame that should replace
        the current one. May throw exceptions if this frame is invalid.
        r   Nz"Invalid frame during header block.z&Too many continuation frames received.END_HEADERSr   c                 s  s    | ]}|j V  qd S N)r   ).0xr   r   r   	<genexpr>d   s    z4FrameBuffer._update_header_buffer.<locals>.<genexpr>)r   	stream_id
isinstancer	   r   appendr   CONTINUATION_BACKLOGflagsaddjoinr   r   r   )r   fr(   valid_framer   r   r   _update_header_bufferD   s4   




z!FrameBuffer._update_header_bufferc                 C  s   | S r$   r   )r   r   r   r   __iter__t   s   zFrameBuffer.__iter__c              
   C  s  t | jdk r
t ztt| jd d \}}W n ttfy0 } ztdt	| d }~ww t | j|d k r=t | 
| z|t| jdd|   W n ty]   td tyg   tdw | jd| d  | _| |}|d ur}|S |  S )N	   z&Received frame with invalid header: %sz&Received frame with non-compliant datazFrame data missing or invalid)r   r   StopIterationr
   parse_frame_header
memoryviewr   r   r   strr"   
parse_bodyr   r1   __next__)r   r/   r!   er   r   r   r9   w   s*    
 
zFrameBuffer.__next__N)F)
__name__
__module____qualname____doc__r   r    r"   r1   r2   r9   r   r   r   r   r      s    

0r   N)r>   
__future__r   
exceptionsr   r   r   hyperframe.exceptionsr   r   hyperframe.framer	   r
   r   r   r+   r   r   r   r   r   <module>   s    
