B
    è?F[¦  ã               @   s‚   d dl Z d dlZd dlZd dlmZ dZde ZdZefdd„Zefdd	„Z	d
d„ Z
ddd„Zdd„ Zdd„ ZG dd„ deƒZdS )é    N)Úsixé   é   i'  c             C   sl   t }|t | k rd| dt  d kr,td|  ƒ‚| d }d}x ||k rXt t |¡}|d7 }q:W t|ƒ}n|}|S )a"  Calculate the minimum part size needed for a multipart upload.

    Glacier allows a maximum of 10,000 parts per upload.  It also
    states that the maximum archive size is 10,000 * 4 GB, which means
    the part size can range from 1MB to 4GB (provided it is one 1MB
    multiplied by a power of 2).

    This function will compute what the minimum part size must be in
    order to upload a file of size ``size_in_bytes``.

    It will first check if ``default_part_size`` is sufficient for
    a part size given the ``size_in_bytes``.  If this is not the case,
    then the smallest part size than can accomodate a file of size
    ``size_in_bytes`` will be returned.

    If the file size is greater than the maximum allowed archive
    size of 10,000 * 4GB, a ``ValueError`` will be raised.

    i   i'  zFile size too large: %sé   é   )Ú	_MEGABYTEÚMAXIMUM_NUMBER_OF_PARTSÚ
ValueErrorÚmathZldexpÚint)Zsize_in_bytesZdefault_part_sizeZ	part_sizeZmin_part_sizeZpower© r   ú1lib/python3.7/site-packages/boto/glacier/utils.pyÚminimum_part_size"   s    

r   c             C   sx   t t t| ƒt|ƒ ¡ƒ}g }x@t|ƒD ]4}|| }|d | }| t | ||… ¡ 	¡ ¡ q(W |stt d¡ 	¡ gS |S )Nr   ó    )
r   r
   ZceilÚlenÚfloatÚrangeÚappendÚhashlibÚsha256Údigest)Z
bytestringÚ
chunk_sizeZchunk_countÚhashesÚiÚstartÚendr   r   r   Úchunk_hashesJ   s     r   c             C   sš   g }|  | ¡ x‚t|ƒdkrg }xbt|ƒdkr\| d¡}| d¡}| t || ¡ ¡ ¡ q"t|ƒdkr~| d¡}| |¡ q"P q"W |  |¡ qW |d S )z¤
    Given a hash of each 1MB chunk (from chunk_hashes) this will hash
    together adjacent hashes until it ends up with one big one. So a
    tree of hashes.
    r   r   )Úextendr   Úpopr   r   r   r   )Zfor   Z
new_hashesÚfirstÚsecondZonlyr   r   r   Ú	tree_hashV   s    



r!   c             C   s²   t jr"t| dƒr"d| jkr"tdƒ‚t ¡ }g }|  |¡}xP|rˆt|t	ƒs^| 
t| ddƒpZd¡}| |¡ | t |¡ ¡ ¡ |  |¡}q:W |sžt d¡ ¡ g}| ¡ tt|ƒƒfS )aÎ  Compute the linear and tree hash from a fileobj.

    This function will compute the linear/tree hash of a fileobj
    in a single pass through the fileobj.

    :param fileobj: A file like object.

    :param chunk_size: The size of the chunks to use for the tree
        hash.  This is also the buffer size used to read from
        `fileobj`.

    :rtype: tuple
    :return: A tuple of (linear_hash, tree_hash).  Both hashes
        are returned in hex.

    ÚmodeÚbz/File-like object must be opened in binary mode!ÚencodingÚ zutf-8r   )r   ZPY3Úhasattrr"   r	   r   r   ÚreadÚ
isinstanceÚbytesÚencodeÚgetattrÚupdater   r   Z	hexdigestÚbytes_to_hexr!   )Zfileobjr   Zlinear_hashZchunksÚchunkr   r   r   Úcompute_hashes_from_fileobjn   s    


r/   c             C   s
   t  | ¡S )N)ÚbinasciiZhexlify)Ústr_as_bytesr   r   r   r-   ”   s    r-   c             C   s   t tt| ƒƒƒS )z²

    :type str_as_bytes: str
    :param str_as_bytes: The string for which to compute the tree hash.

    :rtype: str
    :return: The computed tree hash, returned as hex.

    )r-   r!   r   )r1   r   r   r   Útree_hash_from_str˜   s    
r2   c               @   s   e Zd Zdd„ Zdd„ ZdS )ÚResettingFileSenderc             C   s   || _ | ¡ | _d S )N)Ú_archiveÚtellÚ_starting_offset)ÚselfÚarchiver   r   r   Ú__init__¦   s    zResettingFileSender.__init__c          	   C   s0   z|  ||| j|¡ | ¡ S | j | j¡ X d S )N)Zrequestr4   ZgetresponseÚseekr6   )r7   Z
connectionÚmethodÚpathZbodyZheadersr   r   r   Ú__call__ª   s    zResettingFileSender.__call__N)Ú__name__Ú
__module__Ú__qualname__r9   r=   r   r   r   r   r3   ¥   s   r3   )r   )r   r
   r0   Zboto.compatr   r   ZDEFAULT_PART_SIZEr   r   r   r!   r/   r-   r2   Úobjectr3   r   r   r   r   Ú<module>   s   (
&