o
    i(                     @   sZ   d Z ddlZddlmZ dZdZdZdZdZdZ	d	Z
d
ZdZdZdZdZG dd dZdS )a  
TLV (Type-Length-Value) Binary Encoder/Decoder

Provides efficient binary serialization for dirty worker protocol messages.
Inspired by OpenBSD msgctl/msgsnd message format.

Type Codes:
    0x00: None (no value bytes)
    0x01: bool (1 byte: 0x00 or 0x01)
    0x05: int64 (8 bytes big-endian signed)
    0x06: float64 (8 bytes IEEE 754)
    0x10: bytes (4-byte length + raw bytes)
    0x11: string (4-byte length + UTF-8 encoded)
    0x20: list (4-byte count + encoded elements)
    0x21: dict (4-byte count + encoded key-value pairs)
    N   )DirtyProtocolError                !   i   i   c                   @   sP   e Zd ZdZedefddZeddededefdd	Z	edefd
dZ
dS )
TLVEncoderz
    TLV binary encoder/decoder.

    Encodes Python values to binary TLV format and decodes back.
    Supports: None, bool, int, float, bytes, str, list, dict.
    returnc                 C   s:  | du r	t tgS t| trt t| rdgS dgS t| tr*t tgtd|  S t| t	r:t t
gtd|  S t| t rat| tkrRtdt|  dt dt tgtd	t|  |  S t| tr| d
}t|tkr~tdt| dt dt tgtd	t| | S t| ttfrt| tkrtdt|  dt dt tgtd	t| g}| D ]
}|t| qd|S t| trt| tkrtdt|  dt dt tgtd	t| g}|  D ]\}}t|tst|}|t| |t| qd|S tdt| j )aJ  
        Encode a Python value to TLV binary format.

        Args:
            value: Python value to encode (None, bool, int, float,
                   bytes, str, list, or dict)

        Returns:
            bytes: TLV-encoded binary data

        Raises:
            DirtyProtocolError: If value type is not supported
        Nr   r   >q>dBytes too large:  bytes (max: )>Iutf-8String too large: List too large:  items (max:     Dict too large: z#Unsupported type for TLV encoding: ) bytes	TYPE_NONE
isinstancebool	TYPE_BOOLint
TYPE_INT64structpackfloatTYPE_FLOAT64lenMAX_BYTES_SIZEr   
TYPE_BYTESstrencodeMAX_STRING_SIZETYPE_STRINGlisttupleMAX_LIST_SIZE	TYPE_LISTappendr
   joindictMAX_DICT_SIZE	TYPE_DICTitemstype__name__)valueencodedpartsitemkv r<   F/home/ubuntu/.local/lib/python3.10/site-packages/gunicorn/dirty/tlv.pyr'   4   sj   









zTLVEncoder.encoder   dataoffsetc                 C   s  |t | krtd| ||d  d| | }|d7 }|tkr"d|fS |tkrF|t | kr:td| |d |d  d| | dk}||d fS |tkrt|d t | kr`td	| |d |d  dtd
| ||d  d }||d fS |tkr|d t | krtd| |d |d  dtd| ||d  d }||d fS |tkr|d t | krtd| |d |d  dtd| ||d  d }|d7 }|t	krtd| dt	 d|| t | krtd| dt | |  | |d |d  d| |||  }||| fS |t
kr|d t | kr(td| |d |d  dtd| ||d  d }|d7 }|tkrJtd| dt d|| t | krktd| dt | |  | |d |d  dz| |||  d}W n ty } ztd| | ||t|d  dd}~ww ||| fS |tkr|d t | krtd| |d |d  dtd| ||d  d }|d7 }|tkrtd| dt dg }t|D ]}t| |\}	}||	 q||fS |tkrg|d t | krtd| |d |d  dtd| ||d  d }|d7 }|tkr5td| dt di }
t|D ]'}t| |\}}t|tsUtd t|j t| |\}}||
|< q;|
|fS td!|d"| |d |d  d)#a9  
        Decode a TLV-encoded value from binary data.

        Args:
            data: Binary data to decode
            offset: Starting offset in the data

        Returns:
            tuple: (decoded_value, new_offset)

        Raises:
            DirtyProtocolError: If data is malformed or truncated
        z Truncated TLV data: no type byte   raw_datar   Nz&Truncated TLV data: missing bool valuer      z$Truncated TLV data: incomplete int64r   z&Truncated TLV data: incomplete float64r      z+Truncated TLV data: incomplete bytes lengthr   r   r   r   zTruncated TLV data: expected z bytes, got r   z,Truncated TLV data: incomplete string lengthr   z bytes for string, got r   zInvalid UTF-8 in string: z)Truncated TLV data: incomplete list countr   r   z)Truncated TLV data: incomplete dict countr   zDict key must be string, got zUnknown TLV type code: 0x02x)r#   r   r   r   r   r   unpackr"   r%   r$   r)   r(   decodeUnicodeDecodeErrorminr-   r,   ranger
   r.   r2   r1   r   r&   r4   r5   )r>   r?   	type_coder6   lengthecountr3   _r9   resultkeyr<   r<   r=   rG      s   









zTLVEncoder.decodec                 C   sH   t | d\}}|t| kr"tdt| |  d| ||d  d|S )a  
        Decode a complete TLV-encoded value, ensuring all data is consumed.

        Args:
            data: Binary data to decode

        Returns:
            Decoded Python value

        Raises:
            DirtyProtocolError: If data is malformed or has trailing bytes
        r   zTrailing data after TLV: z bytesr@   rA   )r
   rG   r#   r   )r>   r6   r?   r<   r<   r=   decode_full  s   zTLVEncoder.decode_fullN)r   )r5   
__module____qualname____doc__staticmethodr   r'   r   r+   rG   rR   r<   r<   r<   r=   r
   ,   s    J r
   )rU   r   errorsr   r   r   r   r"   r%   r)   r-   r2   r(   r$   r,   r1   r
   r<   r<   r<   r=   <module>   s    