
    c                         d Z ddlmZ ddlZddlmZmZmZm	Z
mZmZmZ dZeZdZd Zd	 Z G d
 de          Z G d de          ZefdZedfdZ	ddefdZdS )aA  The module implements compression/decompression with snappy using
Hadoop snappy format: https://github.com/kubo/snzip#hadoop-snappy-format

Expected usage like:

    import snappy

    src = 'uncompressed'
    dst = 'compressed'
    dst2 = 'decompressed'

    with open(src, 'rb') as fin, open(dst, 'wb') as fout:
        snappy.hadoop_stream_compress(src, dst)

    with open(dst, 'rb') as fin, open(dst2, 'wb') as fout:
        snappy.hadoop_stream_decompress(fin, fout)

    with open(src, 'rb') as fin1, open(dst2, 'rb') as fin2:
        assert fin1.read() == fin2.read()

    )absolute_importN   )	_compress_uncompressstream_compressstream_decompresscheck_formatUncompressError
_CHUNK_MAXi      c                 0    t          j        d|           }|S )N>I)structpack)numbig_endian_uints     4lib/python3.11/site-packages/snappy/hadoop_snappy.pypack_intr   )   s    k$,,O    c                 8    t          j        d|           d         S )Nr   r   )r   unpack)datas    r   
unpack_intr   .   s    =t$$Q''r   c                   2    e Zd ZdZd Zd Zd ZddZd ZdS )	StreamCompressorai  This class implements the compressor-side of the hadoop snappy
    format, taken from https://github.com/kubo/snzip#hadoop-snappy-format

    Keep in mind that this compressor object does no buffering for you to
    appropriately size chunks. Every call to StreamCompressor.compress results
    in a unique call to the underlying snappy compression method.
    c                     d S N selfs    r   __init__zStreamCompressor.__init__<   s    r   c                 <   g }t          |          }|                    t          |                     t          |          }t          |          }|                    t          |                     |                    |           d                    |          S )aM  Add a chunk containing 'data', returning a string that is
        compressed. This data should be concatenated to
        the tail end of an existing Snappy stream. In the absence of any
        internal buffering, no data is left in any internal buffers, and so
        unlike zlib.compress, this method returns everything.
        r   )lenappendr   r   join)r    r   outuncompressed_lengthcompressed_chunkcompressed_lengths         r   	add_chunkzStreamCompressor.add_chunk?   s     !$ii

8/00111$T?? 011

8-..///

#$$$xx}}r   c                 ,    |                      |          S )zjThis method is simply an alias for compatibility with zlib
        compressobj's compress method.
        )r*   )r    r   s     r   compresszStreamCompressor.compressO   s     ~~d###r   Nc                     dS )zeThis method does nothing and only exists for compatibility with
        the zlib compressobj
        Nr   )r    modes     r   flushzStreamCompressor.flushU   s	     	r   c                     t                      S )zHThis method exists for compatibility with the zlib compressobj.
        )r   r   s    r   copyzStreamCompressor.copy[   s      !!!r   r   )	__name__
__module____qualname____doc__r!   r*   r,   r/   r1   r   r   r   r   r   2   sn              $ $ $   " " " " "r   r   c                   H    e Zd ZdZg dZd Zed             Zd Zd Z	d Z
dS )	StreamDecompressoraw  This class implements the decompressor-side of the hadoop snappy
    format.

    This class matches a subset of the interface found for the zlib module's
    decompression objects (see zlib.decompressobj). Specifically, it currently
    implements the decompress method without the max_length option, the flush
    method without the length option, and the copy method.
    _buf_block_length_uncompressed_lengthc                 0    d| _         d| _        d| _        d S )Nr   r   r8   r   s    r   r!   zStreamDecompressor.__init__n   s    	$%!!!r   c                 ^    t           }t          |           |dz  k     rt          d          dS )a  Just checks that first two integers (big endian four-bytes int)
        in the given data block comply to: first int >= second int.
        This is a simple assumption that we have in the data a start of a
        block for hadoop snappy format. It should contain uncompressed block
        length as the first integer, and compressed subblock length as the
        second integer.
        Raises UncompressError if the condition is not fulfilled.
        :return: None
           zToo short data lengthN)	_INT_SIZEr#   r
   )r   int_sizes     r   r	   zStreamDecompressor.check_formatu   s6     t99x!|# 	;!"9:::
 	r   c                 &   t           }| xj        |z  c_        g }	 t          | j                  |k     rd                    |          S d}| j        sbt          | j        d|                   | _        | j        |d         | _        t          | j                  |k     rd                    |          S t          | j        |||z                      }||z  }t          | j                  ||z   k     rd                    |          S | j        |||z            }| j        ||z   d         | _        t          |          }| xj        t          |          z  c_        |                    |           | j        | j        k    rd| _        d| _        wx)ab  Decompress 'data', returning a string containing the uncompressed
        data corresponding to at least part of the data in string. This data
        should be concatenated to the output produced by any preceding calls to
        the decompress() method. Some of the input data may be preserved in
        internal buffers for later processing.
        Tr   r   N)	r?   r9   r#   r%   r:   r   r   r;   r$   )r    r   r@   uncompressed
next_startr)   chunkuncompressed_chunks           r   
decompresszStreamDecompressor.decompress   s    		T			49~~( .xx---J% 2%/	)8)0D%E%E" Ihii0	ty>>H, 288L111 *	*Z(%::;! ! ("J49~~ 1J >> .xx---I:(999E 	*/@"@"A"ABDI!,U!3!3%%-?)@)@@%% 2333(D,>> ,-)%&"5	r   c                 :    | j         dk    rt          d          dS )a  All pending input is processed, and a string containing the
        remaining uncompressed output is returned. After calling flush(), the
        decompress() method cannot be called again; the only realistic action
        is to delete the object.
        r   zchunk truncated)r9   r
   r   s    r   r/   zStreamDecompressor.flush   s'     9 	5!"3444sr   c                 j    t                      }| j        |_        | j        |_        | j        |_        |S )zReturns a copy of the decompression object. This can be used to save
        the state of the decompressor midway through the data stream in order
        to speed up random seeks into the stream at a future point.
        )r7   r9   r:   r;   )r    r1   s     r   r1   zStreamDecompressor.copy   s3    
 "##I	!/$($=!r   N)r2   r3   r4   r5   	__slots__r!   staticmethodr	   rF   r/   r1   r   r   r   r7   r7   a   s          BAAI& & &   \&$ $ $L  	 	 	 	 	r   r7   c                 2    t          | ||t                    S )N)	blocksizecompressor_cls)_stream_compressr   )srcdstrL   s      r   r   r      s#    SI6F   r   c                 4    t          | ||t          |          S )N)rL   decompressor_clsstart_chunk)_stream_decompressr7   )rO   rP   rL   rS   s       r   r   r      s&    SI+   r   c                 2    t          | ||t                    S )N)finrD   rL   rR   )_check_formatr7   )rV   rD   rL   s      r   r	   r	      s#    u	+   r   )r5   
__future__r   r   snappyr   r   r   rN   r   rT   r	   rW   r
   r   SNAPPY_BUFFER_SIZE_DEFAULT_STREAM_TO_STREAM_BLOCK_SIZEr?   r   r   objectr   r7   r   r   r   <module>r]      st   * ' & & & & &                   ( ) 	  
( ( (," ," ," ," ,"v ," ," ,"^a a a a a a a aH )C     +G"&    1M      r   