
                         H    d Z ddlmZ ddlmZ dgZ	 	 d	dZ G d de      Zy)
z!Compression support for apitools.    )deque)gzipCompressStreamNc                 >   d}d}t               }t        j                  d||      5 }|r|j                  |k  rM| j	                  |      }t        |      }	|j                  |       ||	z  }|	|k  rd}n|s=|j                  |k  rMddd       |||fS # 1 sw Y   xY w)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Y&# J--6	
4 w,,
4 
4s   AB6BBc                   @    e Zd ZdZd Zd Zd Zed        Zd Z	d	dZ
y)
r   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    t               | _        d| _        y )Nr   )r   _StreamingBuffer__buf_StreamingBuffer__sizeselfs    r   __init__zStreamingBuffer.__init__a   s    W
    c                     | j                   S Nr   r   s    r   __len__zStreamingBuffer.__len__g   s    {{r!   c                 ,    t        | j                        S r#   )boolr   r   s    r   __nonzero__zStreamingBuffer.__nonzero__j   s     DKK  r!   c                     | j                   S r#   r$   r   s    r   r   zStreamingBuffer.lengtho   s     {{r!   c                     |=|r:| j                   j                  |       | xj                  t        |      z  c_        y y y r#   )r   appendr   r   )r   r   s     r   r   zStreamingBuffer.writet   s8     JJd#KK3t9$K !%r!   Nc                    || j                   }g }|dkD  rW| j                  rK| j                  j                         }|t        |      z  }|j	                  |       |dkD  r| j                  rK|dk  r/|d   d| |d   |d c|d<   }| j                  j                  |       dj                  |      }| xj                   t        |      z  c_         |S )aM  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   r+   
appendleftjoin)r   sizeret_listr   	remainderrets         r   r   zStreamingBuffer.read{   s     <;;DQh4::::%%'DCIDOOD! Qh4:: !8&.rl5D&98B<;N#HRL)JJ!!),hhx s3x
r!   r#   )__name__
__module____qualname____doc__r    r%   r(   propertyr   r   r    r!   r   r   r   X   s4    !
  %r!   r   )N   i   )	r8   collectionsr   apitools.base.pyr   __all__r   objectr   r:   r!   r   <module>r@      s6   " (  !  :;%7-t;f ;r!   