
                         J    S r SSKJr  SSKJr  S/r  S	S jr " S S\5      rg)
z!Compression support for apitools.    )deque)gzipCompressStreamNc                 \   SnSn[        5       n[        R                  " SUUS9 nU(       a  UR                  U:  aT  U R	                  U5      n[        U5      n	UR                  U5        XI-  nX:  a  SnOU(       d  MB  UR                  U:  a  MT  SSS5        XdU4$ ! , (       d  f       N= f)a{  Compresses an input stream into a file-like buffer.

This reads from the input stream until either we've stored at least length
compressed bytes, or the input stream has been exhausted.

This supports streams of unknown size.

Args:
    in_stream: The input stream to read from.
    length: The target number of compressed bytes to buffer in the output
        stream. If length is none, the input stream will be compressed
        until it's exhausted.

        The actual length of the output buffer can vary from the target.
        If the input stream is exhaused, the output buffer may be smaller
        than expected. If the data is incompressible, the maximum length
        can be exceeded by can be calculated to be:

          chunksize + 5 * (floor((chunksize - 1) / 16383) + 1) + 17

        This accounts for additional header data gzip adds. For the default
        16MiB chunksize, this results in the max size of the output buffer
        being:

          length + 16Mib + 5142 bytes

    compresslevel: Optional, defaults to 2. The desired compression level.
    chunksize: Optional, defaults to 16MiB. The chunk size used when
        reading data from the input stream to write into the output
        buffer.

Returns:
    A file-like output buffer of compressed bytes, the number of bytes read
    from the input stream, and a flag denoting if the input stream was
    exhausted.
r   Fwb)modefileobjcompresslevelTN)StreamingBufferr   GzipFilelengthreadlenwrite)
	in_streamr   r
   	chunksizein_readin_exhausted
out_streamcompress_streamdatadata_lengths
             /lib/third_party/apitools/base/py/compression.pyr   r      s    N GL "J	D)%2
47FJ--6>>),Dd)K!!$'"G&# &J--6	
4 ,,
4 
4s   AB?B
B+c                   J    \ rS rSrSrS rS rS r\S 5       r	S r
SS	 jrS
rg)r   X   zProvides a file-like object that writes to a temporary buffer.

When data is read from the buffer, it is permanently removed. This is
useful when there are memory constraints preventing the entire buffer from
being stored in memory.
c                 0    [        5       U l        SU l        g )Nr   )r   _StreamingBuffer__buf_StreamingBuffer__sizeselfs    r   __init__StreamingBuffer.__init__a   s    W
    c                     U R                   $ Nr   r   s    r   __len__StreamingBuffer.__len__g   s    {{r#   c                 ,    [        U R                  5      $ r%   )boolr   r   s    r   __nonzero__StreamingBuffer.__nonzero__j   s     DKK  r#   c                     U R                   $ r%   r&   r   s    r   r   StreamingBuffer.lengtho   s     {{r#   c                     UbB  U(       a:  U R                   R                  U5        U =R                  [        U5      -  sl        g g g r%   )r   appendr   r   )r    r   s     r   r   StreamingBuffer.writet   s8     JJd#KK3t9$K !%r#   Nc                    Uc  U R                   n/ nUS:  ac  U R                  (       aR  U R                  R                  5       nU[        U5      -  nUR	                  U5        US:  a  U R                  (       a  MR  US:  a/  US   SU US   US sUS'   nU R                  R                  U5        SR                  U5      nU =R                   [        U5      -  sl         U$ )a  Read at most size bytes from this buffer.

Bytes read from this buffer are consumed and are permanently removed.

Args:
  size: If provided, read no more than size bytes from the buffer.
    Otherwise, this reads the entire buffer.

Returns:
  The bytes read from this buffer.
Nr   r#   )r   r   popleftr   r0   
appendleftjoin)r    sizeret_listr   	remainderrets         r   r   StreamingBuffer.read{   s     <;;DQh4::::%%'DCIDOOD! Qh4::: !8&.rl5D&98B<;N#HRL)JJ!!),hhx s3x
r#   )__buf__sizer%   )__name__
__module____qualname____firstlineno____doc__r!   r'   r+   propertyr   r   r   __static_attributes__ r#   r   r   r   X   s4    !
  %r#   r   )N   i   )	rB   collectionsr   apitools.base.pyr   __all__r   objectr   rE   r#   r   <module>rK      s6   " (  !  :;%7-t;f ;r#   