ó
è?F[c           @   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 d „ Z e d „ Z	 d „  Z
 d d	 „ Z d
 „  Z d „  Z d e f d „  ƒ  YZ d S(   iÿÿÿÿN(   t   sixi   i   i'  c         C   s•   t  } | t |  k  r‹ |  d t  d k r= t d |  ƒ ‚ n  |  d } d } x, | | k  r{ t j t  | ƒ } | d 7} qP Wt | ƒ } n | } | S(   s"  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'  s   File size too large: %si   i   (   t	   _MEGABYTEt   MAXIMUM_NUMBER_OF_PARTSt
   ValueErrort   matht   ldexpt   int(   t   size_in_bytest   default_part_sizet	   part_sizet   min_part_sizet   power(    (    s1   lib/python2.7/site-packages/boto/glacier/utils.pyt   minimum_part_size"   s    
c         C   s   t  t j t |  ƒ t | ƒ ƒ ƒ } g  } xO t | ƒ D]A } | | } | d | } | j t j |  | | !ƒ j	 ƒ  ƒ q8 W| s™ t j d ƒ j	 ƒ  g S| S(   Ni   t    (
   R   R   t   ceilt   lent   floatt   ranget   appendt   hashlibt   sha256t   digest(   t
   bytestringt
   chunk_sizet   chunk_countt   hashest   it   startt   end(    (    s1   lib/python2.7/site-packages/boto/glacier/utils.pyt   chunk_hashesJ   s    %
'c         C   sÙ   g  } | j  |  ƒ x» t | ƒ d k rÐ g  } x t r¿ t | ƒ d k rŠ | j d ƒ } | j d ƒ } | j t j | | ƒ j ƒ  ƒ q1 t | ƒ d k r» | j d ƒ } | j | ƒ q1 Pq1 W| j  | ƒ q W| d S(   s¤   
    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.
    i   i    (   t   extendR   t   Truet   popR   R   R   R   (   t   foR   t
   new_hashest   firstt   secondt   only(    (    s1   lib/python2.7/site-packages/boto/glacier/utils.pyt	   tree_hashV   s    	#c         C   s  t  j r6 t |  d ƒ r6 d |  j k r6 t d ƒ ‚ n  t j ƒ  } g  } |  j | ƒ } xu | rÎ t | t	 ƒ s“ | j
 t |  d d ƒ pŠ d ƒ } n  | j | ƒ | j t j | ƒ j ƒ  ƒ |  j | ƒ } qZ W| sð t j d ƒ j ƒ  g } n  | j ƒ  t t | ƒ ƒ f S(   sÎ  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.

    t   modet   bs/   File-like object must be opened in binary mode!t   encodingR   s   utf-8(   R    t   PY3t   hasattrR'   R   R   R   t   readt
   isinstancet   bytest   encodet   getattrt   updateR   R   t	   hexdigestt   bytes_to_hexR&   (   t   fileobjR   t   linear_hasht   chunkst   chunk(    (    s1   lib/python2.7/site-packages/boto/glacier/utils.pyt   compute_hashes_from_fileobjn   s    '	$c         C   s   t  j |  ƒ S(   N(   t   binasciit   hexlify(   t   str_as_bytes(    (    s1   lib/python2.7/site-packages/boto/glacier/utils.pyR3   ”   s    c         C   s   t  t t |  ƒ ƒ ƒ S(   s²   

    :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.

    (   R3   R&   R   (   R;   (    (    s1   lib/python2.7/site-packages/boto/glacier/utils.pyt   tree_hash_from_str˜   s    
t   ResettingFileSenderc           B   s   e  Z d  „  Z d „  Z RS(   c         C   s   | |  _  | j ƒ  |  _ d  S(   N(   t   _archivet   tellt   _starting_offset(   t   selft   archive(    (    s1   lib/python2.7/site-packages/boto/glacier/utils.pyt   __init__¦   s    	c         C   sB   z' | j  | | |  j | ƒ | j ƒ  SWd  |  j j |  j ƒ Xd  S(   N(   t   requestR>   t   getresponset   seekR@   (   RA   t
   connectiont   methodt   patht   bodyt   headers(    (    s1   lib/python2.7/site-packages/boto/glacier/utils.pyt   __call__ª   s    (   t   __name__t
   __module__RC   RL   (    (    (    s1   lib/python2.7/site-packages/boto/glacier/utils.pyR=   ¥   s   	i   i   (   R   R   R9   t   boto.compatR    R   t   DEFAULT_PART_SIZER   R   R   R&   R8   R3   R<   t   objectR=   (    (    (    s1   lib/python2.7/site-packages/boto/glacier/utils.pyt   <module>   s   
(	&		