a
    mNX=                     @   s   d dl Z d dlZddlmZmZ G dd deZeZG dd dejZ	e	ej
Ze	jZe	jZe	jZdd	 Zeejejd d
fddZdd Zdd Zdd Zdd Zdd ZG dd deZG dd deZdS )    N   )ffilibc                   @   s   e Zd ZdZdS )Errorz
    Raised whenever an error is encountered with compressing or decompressing
    data using brotlipy.

    .. versionadded:: 0.5.1
    N)__name__
__module____qualname____doc__ r
   r
   ,lib/python3.9/site-packages/brotli/brotli.pyr      s   r   c                   @   s"   e Zd ZdZejZejZej	Z
dS )BrotliEncoderModezP
    Compression modes for the Brotli encoder.

    .. versionadded:: 0.5.0
    N)r   r   r   r	   r   ZBROTLI_MODE_GENERICGENERICZBROTLI_MODE_TEXTTEXTZBROTLI_MODE_FONTFONTr
   r
   r
   r   r      s   r   c                 C   s   t  }|| } |  | S )z{
    Decompress a complete Brotli-compressed string.

    :param data: A bytestring containing Brotli-compressed data.
    )Decompressor
decompressfinish)datadr
   r
   r   r   R   s    
r       c                 C   sP   t |||||d}|| tj}t|jtjks6J t|jtjksLJ |S )a  
    Compress a string using Brotli.

    .. versionchanged:: 0.5.0
       Added ``mode``, ``quality``, `lgwin``, ``lgblock``, and ``dictionary``
       parameters.

    :param data: A bytestring containing the data to compress.
    :type data: ``bytes``

    :param mode: The encoder mode.
    :type mode: :class:`BrotliEncoderMode` or ``int``

    :param quality: Controls the compression-speed vs compression-density
        tradeoffs. The higher the quality, the slower the compression. The
        range of this value is 0 to 11.
    :type quality: ``int``

    :param lgwin: The base-2 logarithm of the sliding window size. The range of
        this value is 10 to 24.
    :type lgwin: ``int``

    :param lgblock: The base-2 logarithm of the maximum input block size. The
        range of this value is 16 to 24. If set to 0, the value will be set
        based on ``quality``.
    :type lgblock: ``int``

    :param dictionary: A pre-set dictionary for LZ77. Please use this with
        caution: if a dictionary is used for compression, the same dictionary
        **must** be used for decompression!
    :type dictionary: ``bytes``

    :returns: The compressed bytestring.
    :rtype: ``bytes``
    )modequalitylgwinlgblock
dictionary)	
Compressor	_compressr   BROTLI_OPERATION_FINISHBrotliEncoderIsFinished_encoderBROTLI_TRUEBrotliEncoderHasMoreOutputBROTLI_FALSE)r   r   r   r   r   r   Z
compressorZcompressed_datar
   r
   r   compress^   s    .r#   c                 C   s0   zt | } W n ty*   td|  Y n0 dS )z*
    Validate that the mode is valid.
    z%s is not a valid encoder modeN)r   
ValueErrorr   valr
   r
   r   _validate_mode   s    r'   c                 C   s&   d|   krdks"n t d|  dS )z5
    Validate that the quality setting is valid.
    r      z3%d is not a valid quality, must be between 0 and 11Nr   r%   r
   r
   r   _validate_quality   s    r*   c                 C   s&   d|   krdks"n t d|  dS )z3
    Validate that the lgwin setting is valid.
    
      z2%d is not a valid lgwin, must be between 10 and 24Nr)   r%   r
   r
   r   _validate_lgwin   s    r-   c                 C   s.   | dkr*d|   krdks*n t d|  dS )z5
    Validate that the lgblock setting is valid.
    r      r,   z@%d is not a valid lgblock, must be either 0 or between 16 and 24Nr)   r%   r
   r
   r   _validate_lgblock   s    r/   c                 C   s   t | ||}|t jkr"t| nD|t jkr6t| n0|t jkrJt| n|t jkr^t	| nt
d|t jkrtd||f dS )z
    This helper function sets a specific Brotli encoder parameter, checking
    the return code and raising :class:`Error <brotli.Error>` if it is
    invalid.
    zUnexpected parameter!zError setting parameter %s: %dN)r   ZBrotliEncoderSetParameterBROTLI_PARAM_MODEr'   BROTLI_PARAM_QUALITYr*   BROTLI_PARAM_LGWINr-   BROTLI_PARAM_LGBLOCKr/   RuntimeErrorr    r   )encoderZ	parameterZparameter_namer&   rcr
   r
   r   _set_parameter   s    









r7   c                   @   sP   e Zd ZdZdZdZeejej	ddfddZ
dd Zd	d
 Zdd Zdd ZdS )r   a  
    An object that allows for streaming compression of data using the Brotli
    compression algorithm.

    .. versionadded:: 0.5.0

    :param mode: The encoder mode.
    :type mode: :class:`BrotliEncoderMode` or ``int``

    :param quality: Controls the compression-speed vs compression-density
        tradeoffs. The higher the quality, the slower the compression. The
        range of this value is 0 to 11.
    :type quality: ``int``

    :param lgwin: The base-2 logarithm of the sliding window size. The range of
        this value is 10 to 24.
    :type lgwin: ``int``

    :param lgblock: The base-2 logarithm of the maximum input block size. The
        range of this value is 16 to 24. If set to 0, the value will be set
        based on ``quality``.
    :type lgblock: ``int``

    :param dictionary: A pre-set dictionary for LZ77. Please use this with
        caution: if a dictionary is used for compression, the same dictionary
        **must** be used for decompression!
    :type dictionary: ``bytes``
    Nr   r   c                 C   s   t tjtjtj}|s tdt|t j}t|t jd| t|t j	d| t|t j
d| t|t jd| |rtd|| _t|| _t || j| j || _d S )Nz"Unable to allocate Brotli encoder!r   r   r   r   
uint8_t [])r   ZBrotliEncoderCreateInstancer   NULLr4   gcZBrotliEncoderDestroyInstancer7   r0   r1   r2   r3   new_dictionarylen_dictionary_sizeZ BrotliEncoderSetCustomDictionaryr   )selfr   r   r   r   r   encr
   r
   r   __init__   s"    

zCompressor.__init__c              	   C   s   t tt|t|d?  d }td}||d< td|d }td|}tdt|}td|}td|}	t| j|||	||tj	}
|
tj
krtd|d rJ ||d  }t||dd S )	z
        This private method compresses some data in a given mode. This is used
        because almost all of the code uses the exact same setup. It wouldn't
        have to, but it doesn't hurt at all.
           i (  size_t *r   r8   
uint8_t **z#Error encountered compressing data.N)intmathZceilr=   r   r;   r   ZBrotliEncoderCompressStreamr   r9   r    r   buffer)r?   r   Z	operationZoriginal_output_sizeavailable_outZoutput_bufferZptr_to_output_bufferZ
input_sizeZinput_bufferZptr_to_input_bufferr6   Zsize_of_outputr
   r
   r   r     s0    
	
zCompressor._compressc                 C   s   |  |tjS )a>  
        Incrementally compress more data.

        :param data: A bytestring containing data to compress.
        :returns: A bytestring containing some compressed data. May return the
            empty bytestring if not enough data has been inserted into the
            compressor to create the output yet.
        )r   r   ZBROTLI_OPERATION_PROCESS)r?   r   r
   r
   r   r#   ?  s    	zCompressor.compressc                 C   sJ   g }| | dtj t| jtjkr@| | dtj qd|S )z
        Flush the compressor. This will emit the remaining output data, but
        will not destroy the compressor. It can be used, for example, to ensure
        that given chunks of content will decompress immediately.
        r   )appendr   r   ZBROTLI_OPERATION_FLUSHr!   r   r    joinr?   chunksr
   r
   r   flushJ  s
    zCompressor.flushc                 C   s6   g }t | jt jkr,|| dt j qd|S )z
        Finish the compressor. This will emit the remaining output data and
        transition the compressor to a completed state. The compressor cannot
        be used again after this point, and must be replaced.
        r   )r   r   r   r"   rI   r   r   rJ   rK   r
   r
   r   r   X  s    zCompressor.finish)r   r   r   r	   r<   r>   DEFAULT_MODEr   BROTLI_DEFAULT_QUALITYBROTLI_DEFAULT_WINDOWrA   r   r#   rM   r   r
   r
   r
   r   r      s   
$r   c                   @   s:   e Zd ZdZdZdZdddZdd Zdd	 Zd
d Z	dS )r   a  
    An object that allows for streaming decompression of Brotli-compressed
    data.

    .. versionchanged:: 0.5.0
       Added ``dictionary`` parameter.

    :param dictionary: A pre-set dictionary for LZ77. Please use this with
        caution: if a dictionary is used for compression, the same dictionary
        **must** be used for decompression!
    :type dictionary: ``bytes``
    Nr   c                 C   sX   t tjtjtj}t|t j| _|rTtd|| _t	|| _
t | j| j
| j d S )Nr8   )r   ZBrotliDecoderCreateInstancer   r9   r:   ZBrotliDecoderDestroyInstance_decoderr;   r<   r=   r>   Z BrotliDecoderSetCustomDictionary)r?   r   Zdecr
   r
   r   rA   u  s    
zDecompressor.__init__c                 C   s  g }t dt|}t d|}t d|}dt| }t d|}t d|}t d|}	t| j||||	t j}
|
tjkrt| j}t	|}t
dt | t |||d  dd }|| |
tjkr|d dksJ qq,|
tjkrqq,|
tjks,J q,d|S )	z
        Decompress part of a complete Brotli-compressed string.

        :param data: A bytestring containing Brotli-compressed data.
        :returns: A bytestring containing the decompressed data.
        rC   z	uint8_t[]rD      zDecompression error: %sr   Nr   )r   r;   r=   r   ZBrotliDecoderDecompressStreamrQ   r9   ZBROTLI_DECODER_RESULT_ERRORZBrotliDecoderGetErrorCodeZBrotliDecoderErrorStringr   stringrG   rI   Z&BROTLI_DECODER_RESULT_NEEDS_MORE_INPUTZBROTLI_DECODER_RESULT_SUCCESSZ'BROTLI_DECODER_RESULT_NEEDS_MORE_OUTPUTrJ   )r?   r   rL   Zavailable_inZ	in_bufferZnext_inZbuffer_sizerH   Z
out_bufferZnext_outr6   Z
error_codeZerror_messagechunkr
   r
   r   r     s<    




zDecompressor.decompressc                 C   s   dS )a?  
        Complete the decompression, return whatever data is remaining to be
        decompressed.

        .. deprecated:: 0.4.0

            This method is no longer required, as decompress() will now
            decompress eagerly.

        :returns: A bytestring containing the remaining decompressed data.
        r   r
   r?   r
   r
   r   rM     s    zDecompressor.flushc                 C   s4   t | jt jksJ t | jt jkr0tddS )ao  
        Finish the decompressor. As the decompressor decompresses eagerly, this
        will never actually emit any data. However, it will potentially throw
        errors if a truncated or damaged data stream has been used.

        Note that, once this method is called, the decompressor is no longer
        safe for further use and must be thrown away.
        z2Decompression error: incomplete compressed stream.r   )r   ZBrotliDecoderHasMoreOutputrQ   r"   ZBrotliDecoderIsFinishedr   rU   r
   r
   r   r     s
    
zDecompressor.finish)r   )
r   r   r   r	   r<   r>   rA   r   rM   r   r
   r
   r
   r   r   e  s   
3r   )rF   enumZ_brotlir   r   	Exceptionr   errorIntEnumr   ZBROTLI_DEFAULT_MODErN   r   ZMODE_GENERICr   Z	MODE_TEXTr   Z	MODE_FONTr   rO   rP   r#   r'   r*   r-   r/   r7   objectr   r   r
   r
   r
   r   <module>   s0   

=

 