o
    ie                     @   s~  d Z ddlmZ ddlZddlZddlZddlZddlZddl	Z	ddl
Z
ddlZddlZddlZddlZddlZddlZddlZddlZddlZddlZddlZddlZddlmZ ddlmZ ddlmZ ddlmZ dd	lm Z m!Z!m"Z" dd
l#m$Z$m%Z%m&Z&m'Z' ddl(m)Z) e*e+Z,dddddddddddddZ-dd Z.dd Z/dd Z0dd  Z1d!d" Z2d#d$ Z3d%d& Z4d'Z5d(Z6e7e5e6 Z8d)Z9d*Z:d+d, Z;d-d. Z<d/d0 Z=G d1d2 d2e>Z?d3d4 Z@d5d6 ZAd7d8 ZBd9d: ZCd;ZDdd<d=ZEdd>d?ZFdd@dAZGddBdCZHdDdE ZIddFdGZJdHdI ZKddJdKZLG dLdM dMe>ZMG dNdO dOe>ZNG dPdQ dQe>ZOG dRdS dSe>ZPG dTdU dUe>ZQdVZRdWZSdXZTdYZUdZZVeWejXG d[d\ d\e>ZYG d]d^ d^eYZZd_d` Z[dadb Z\dcdd Z]e
^ Z_deZ`eadfZbeadgZcddhdidjdkdldmdndodpdqdrdsZddtdu ZeddvdwZfdxdy Zgdzd{ Zhd|d} Zid~d Zjdd Zkdd Zldd Zm		dddZndd Zodd Zpdd ZqdS )u.   
oss2.utils
----------

工具函数模块。
    
formatdateN)AES)Random)Counter   )mkCombineFun)	to_stringto_bytesurlparse)ClientErrorInconsistentErrorRequestErrorOpenApiFormatError)defaultszapplication/javascriptzAapplication/vnd.openxmlformats-officedocument.spreadsheetml.sheetzDapplication/vnd.openxmlformats-officedocument.spreadsheetml.templatezEapplication/vnd.openxmlformats-officedocument.presentationml.templatezFapplication/vnd.openxmlformats-officedocument.presentationml.slideshowzIapplication/vnd.openxmlformats-officedocument.presentationml.presentationzBapplication/vnd.openxmlformats-officedocument.presentationml.slidezGapplication/vnd.openxmlformats-officedocument.wordprocessingml.documentzGapplication/vnd.openxmlformats-officedocument.wordprocessingml.templatez.application/vnd.ms-excel.addin.macroEnabled.12z5application/vnd.ms-excel.sheet.binary.macroEnabled.12z'application/vnd.android.package-archive)z.jsz.xlsxz.xltxz.potxz.ppsxz.pptxz.sldxz.docxz.dotxz.xlamz.xlsbz.apkc                 C   s   t tt| S N)r	   base64	b64encoder
   data r   >/home/ubuntu/.local/lib/python3.10/site-packages/oss2/utils.pyb64encode_as_string;   s   r   c              
   C   s@   zt t| W S  ttjfy } ztdt|  d }~ww )NzBase64 Error: )r   	b64decoder	   	TypeErrorbinasciiErrorr   )r   er   r   r   b64decode_from_string?   s   r   c                 C   s   t t| }t| S )u   计算data的MD5值，经过Base64编码并返回str类型。

    返回值可以直接作为HTTP Content-Type头部的值
    )hashlibmd5r
   r   digest)r   mr   r   r   content_md5F   s   r#   c                 C   s   t t|  S )u[   返回 `data` 的MD5值，以十六进制可读字符串（32个小写字符）的方式。)r   r    r
   	hexdigestr   r   r   r   
md5_stringO   s   r%   c                 C   s2   t j| d  }|tv rt| S t| d S )u'   根据文件名，返回Content-Type。r   r   )ospathsplitextlower_EXTRA_TYPES_MAP	mimetypes
guess_type)nameextr   r   r   content_type_by_nameT   s   r/   c                 C   s,   | pi } d| v r
| S t |}|r|| d< | S )un   根据文件名在headers里设置Content-Type。如果headers中已经存在Content-Type，则直接返回。zContent-Type)r/   )headersr-   content_typer   r   r   set_content_type]   s   r2   c                 C   s   d}|  d}| d dkr|dkr| d| }d}n| dd }|dkr'dS z|r4ttj| W dS t| W dS  tjyF   Y dS w )	u,   判断网络地址是否为IP或localhost。F]r   [r   T:	localhost)findsplitsocket	inet_ptonAF_INET6	inet_atonerror)netlocis_ipv6right_bracket_indexlocr   r   r   is_ip_or_localhostk   s"   
rB   $abcdefghijklmnopqrstuvwxyz0123456789-        c                 C   sH   t | dk st | dkrdS | d tkrdS | d tvrdS t| tkS )u!   判断是否为合法的Bucket名   ?   Fr   )len_HYPHEN
_ALPHA_NUMset_BUCKET_NAME_CHARS)r-   r   r   r   is_valid_bucket_name   s   rO   c                 C   s$   | du rdS d}t || rdS dS )u    判断是否为合法的endpointNFz^([a-zA-Z]+://)?[\w.-]+(:\d+)?$T)rematch)endpointpatternr   r   r   is_valid_endpoint   s   rT   c                 C   s   t jdkr|   d S d S )Nlittle)sys	byteorderreverse)bytes_arrayr   r   r   change_endianness_if_needed   s   
rZ   c                   @   s.   e Zd ZdZdd Zd	ddZedd ZdS )
SizedFileAdapteruh   通过这个适配器（Adapter），可以把原先的 `file_object` 的长度限制到等于 `size`。c                 C   s   || _ || _d| _d S Nr   )file_objectsizeoffset)selfr]   r^   r   r   r   __init__   s   
zSizedFileAdapter.__init__Nc                 C   sj   | j | jkrdS |d u s|dk s|| j  | jkr(| j| j| j  }| j| _ |S |  j |7  _ | j|S N r   )r_   r^   r]   read)r`   amtr   r   r   r   rd      s    zSizedFileAdapter.readc                 C      | j S r   r^   r`   r   r   r   rJ         zSizedFileAdapter.lenr   )__name__
__module____qualname____doc__ra   rd   propertyrJ   r   r   r   r   r[      s    
r[   c                 C   s   | | d | S )Nr   r   )r"   nr   r   r   how_many      rp   c                 C   s4   |   }| dtj |   }| |tj || S r\   )tellseekr&   SEEK_ENDSEEK_SET)fileobjcurrentendr   r   r   file_object_remaining_bytes   s
   ry   c                 C   s(   t | dpt | dpt | dot | dS N__len__rJ   rs   rr   )hasattrr   r   r   r   _has_data_size_attr   s   (r}   c                 C   sB   t | dr	t| S t | dr| jS t | drt | drt| S d S rz   )r|   rJ   ry   r   r   r   r   _get_data_size   s   

r~   i    c                 C   sf   t | } |du rt| }|du r-t| drt| |S t| dr$t| |S td| jjt	| ||S )u  返回一个适配器，从而在读取 `data` ，即调用read或者对其进行迭代的时候，能够
     调用进度回调函数。当 `size` 没有指定，且无法确定时，上传回调函数返回的总字节数为None。

    :param data: 可以是bytes、file object或iterable
    :param progress_callback: 进度回调函数，参见 :ref:`progress_callback`
    :param size: 指定 `data` 的大小，可选

    :return: 能够调用进度回调函数的适配器
    Nrd   __iter__){0} is not a file object, nor an iterator)
r
   r~   r|   _FileLikeAdapter_IterableAdapterr   format	__class__rj   _BytesAndFileAdapter)r   progress_callbackr^   r   r   r   make_progress_adapter   s   




r   c                 C   s   t | } t| r|rtdt| t| t|dS t| dr't| t||dS t| dr:|r2tdt| t|dS td	| j
j)	u6  返回一个适配器，从而在读取 `data` ，即调用read或者对其进行迭代的时候，能够计算CRC。

    :param discard:
    :return:
    :param data: 可以是bytes、file object或iterable
    :param init_crc: 初始CRC值，可选

    :return: 能够调用计算CRC函数的适配器
    ;Bytes of file object adapter does not support discard bytes)r^   crc_callbackrd   )r   discardr   /Iterator adapter does not support discard bytes)r   r   )r
   r}   r   r   r~   Crc64r|   r   r   r   r   rj   )r   init_crcr   r   r   r   make_crc_adapter   s   


r   c                 C   s>   d}t |}| D ]}|jr|js d S |||j|j}q|S r\   )r   part_crcr^   combine)partsr   
object_crccrc_objpartr   r   r   calc_obj_crc_from_parts  s   r   c                 C   sz   t | } t| r|rtdt| t| |dS t| dr#t| ||dS t| dr4|r.tdt| |dS td| j	j
)	uq  返回一个适配器，从而在读取 `data` ，即调用read或者对其进行迭代的时候，能够进行加解密操作。

        :param encrypt:
        :param cipher_callback:
        :param discard: 读取时需要丢弃的字节
        :param data: 可以是bytes、file object或iterable

        :return: 能够客户端加密函数的适配器
        r   )r^   cipher_callbackrd   )r   r   r   r   )r   z{0} is not a file object)r
   r}   r   r   r~   r|   r   r   r   r   rj   )r   r   r   r   r   r   make_cipher_adapter#  s   


r   c                 C   sL   |d ur |d ur"||kr$t d|| ||}td| |d S d S d S )NzeInconsistentError: req_id: {0}, operation: {1}, CRC checksum of client: {2} is mismatch with oss: {3}zException: {0})r   r   loggerr=   )	operation
client_crcoss_crc
request_idr   r   r   r   	check_crc?  s   r   c                 C   s   | r| ||d   d S d S r   r   )r   contentr   r   r   r   _invoke_crc_callbackG  s   r   c                 C   s   | r	| || d S d S r   r   )r   consumed_bytestotal_bytesr   r   r   _invoke_progress_callbackL  s   r   c                 C   s   | r| |}||d  S |S r   r   )r   r   r   r   r   r   _invoke_cipher_callbackQ  s   r   c                   @   s:   e Zd ZdddZdd Zdd Zdd	 Zed
d ZdS )r   Nc                 C   s&   t || _ || _d| _|| _|| _d S r\   )iterr   r_   r   r   )r`   r   r   r   r   r   r   r   ra   Y  s
   

z_IterableAdapter.__init__c                 C      | S r   r   rh   r   r   r   r   a     z_IterableAdapter.__iter__c                 C      |   S r   nextrh   r   r   r   __next__d     z_IterableAdapter.__next__c                 C   sH   t | j| jd  t| j}|  jt|7  _t| j| t| j	|}|S r   )
r   r   r_   r   r   rJ   r   r   r   r   r`   r   r   r   r   r   g  s   
z_IterableAdapter.nextc                 C       | j r| j jS | jr| jjS d S r   )r   crcr   rh   r   r   r   r   s  
   z_IterableAdapter.crc)NNN)	rj   rk   rl   ra   r   r   r   rn   r   r   r   r   r   r   X  s    
r   c                   @   sH   e Zd ZdZdddZdd Zdd	 Zd
d ZdddZe	dd Z
dS )r   u   通过这个适配器，可以给无法确定内容长度的 `fileobj` 加上进度监控。

    :param fileobj: file-like object，只要支持read即可
    :param progress_callback: 进度回调函数
    Nr   c                 C   s.   || _ || _d| _|| _|| _|| _d| _d S )Nr   F)rv   r   r_   r   r   r   read_all)r`   rv   r   r   r   r   r   r   r   ra     s   
z_FileLikeAdapter.__init__c                 C   r   r   r   rh   r   r   r   r     r   z_FileLikeAdapter.__iter__c                 C   r   r   r   rh   r   r   r   r     r   z_FileLikeAdapter.__next__c                 C   s    | j rt| t}|r|S tr   )r   StopIterationrd   _CHUNK_SIZEr   r   r   r   r     s   
z_FileLikeAdapter.nextc                 C   s   | j }|| jk r|r| jr|| j7 }| j|}|s'd| _t| j| j d  |S t| j| j d  |  j t|7  _ d}|| jk rNt|| jkrKt|}n| j}t	| j
|| t| j||}|  j|8  _|S )NTr   )r_   r   r   rv   rd   r   r   r   rJ   r   r   r   )r`   re   offset_startr   real_discardr   r   r   rd     s&   


z_FileLikeAdapter.readc                 C   r   r   )r   r   rv   rh   r   r   r   r     r   z_FileLikeAdapter.crc)NNNr   r   )rj   rk   rl   rm   ra   r   r   r   rd   rn   r   r   r   r   r   r   }  s    


r   c                   @   s`   e Zd ZdZdddZedd Zdd ZeZd	d
 Z	dd Z
dd ZdddZedd ZdS )r   u  通过这个适配器，可以给 `data` 加上进度监控。

    :param data: 可以是unicode字符串（内部会转换为UTF-8编码的bytes）、bytes或file object
    :param progress_callback: 用户提供的进度报告回调，形如 callback(bytes_read, total_bytes)。
        其中bytes_read是已经读取的字节数；total_bytes是总的字节数。
    :param int size: `data` 包含的字节数。
    Nc                 C   s,   t || _|| _|| _d| _|| _|| _d S r\   )r
   r   r   r^   r_   r   r   )r`   r   r   r^   r   r   r   r   r   ra     s   

z_BytesAndFileAdapter.__init__c                 C   rf   r   rg   rh   r   r   r   rJ     ri   z_BytesAndFileAdapter.lenc                 C      dS NTr   rh   r   r   r   __bool__  r   z_BytesAndFileAdapter.__bool__c                 C   r   r   r   rh   r   r   r   r     r   z_BytesAndFileAdapter.__iter__c                 C   r   r   r   rh   r   r   r   r     r   z_BytesAndFileAdapter.__next__c                 C   s   |  t}|r	|S tr   )rd   r   r   r   r   r   r   r     s   
z_BytesAndFileAdapter.nextc                 C   s   | j | jkr
tdS |d u s|dk r| j| j  }n	t|| j| j  }t| jtr4| j| j | j |  }n| j|}|  j |7  _ t| j	t| j | j| j t
| j| t| j|}|S rb   )r_   r^   r
   min
isinstancer   bytesrd   r   r   r   r   r   r   )r`   re   bytes_to_readr   r   r   r   rd     s   z_BytesAndFileAdapter.readc                 C   r   r   )r   r   r   rh   r   r   r   r     r   z_BytesAndFileAdapter.crc)NNNNr   )rj   rk   rl   rm   ra   rn   rJ   r   __nonzero__r   r   r   rd   r   r   r   r   r   r     s    
	

r   c                   @   sB   e Zd ZdZdZdddZdd Zdd	 Zd
d Ze	dd Z
dS )r   l   6S rF   r   c                 C   s2   t j| j|d| jd| _t| j|d| jd| _d S NT)initCrcrevxorOut)crcmodCrc_POLY_XOROUTcrc64r   crc64_combineFunr`   r   r   r   r   ra     s   zCrc64.__init__c                 C      |  | d S r   updater`   r   r   r   r   __call__     zCrc64.__call__c                 C      | j | d S r   )r   r   r   r   r   r   r     rq   zCrc64.updatec                 C   s   |  |||S r   )r   )r`   crc1crc2len2r   r   r   r     r   zCrc64.combinec                 C      | j jS r   )r   crcValuerh   r   r   r   r   "     z	Crc64.crcNr   )rj   rk   rl   r   r   ra   r   r   r   rn   r   r   r   r   r   r     s    
r   c                   @   s:   e Zd ZdZdZdddZdd Zdd	 Zed
d Z	dS )Crc32l   	 rE   r   c                 C   s   t j| j|d| jd| _d S r   )r   r   r   r   crc32r   r   r   r   ra   *  s   zCrc32.__init__c                 C   r   r   r   r   r   r   r   r   -  r   zCrc32.__call__c                 C   r   r   )r   r   r   r   r   r   r   0  rq   zCrc32.updatec                 C   r   r   )r   r   rh   r   r   r   r   3  r   z	Crc32.crcNr   )
rj   rk   rl   r   r   ra   r   r   rn   r   r   r   r   r   r   &  s    
r             zAES/GCM/NoPaddingzAES/CTR/NoPaddingc                   @   s   e Zd ZdZdd Zejdd Zejdd Zejdd	d
Z	ejdd Z
ejdd ZejdddZdd Zdd ZdddZdS )	AESCipheru  AES256 加密实现。
            :param str key: 对称加密数据密钥
            :param str start: 对称加密初始随机值
        .. note::
            用户可自行实现对称加密算法，需服务如下规则：
            1、提供对称加密算法名，ALGORITHM
            2、提供静态方法，返回加密密钥和初始随机值（若算法不需要初始随机值，也需要提供）
            3、提供加密解密方法
    c                 C   s   d | _ t| _t| _t| _d S r   )alg_AES_256_KEY_SIZEkey_len_AES_BLOCK_LENblock_size_len_AES_BLOCK_BITS_LENblock_size_len_in_bitsrh   r   r   r   ra   M  s   
zAESCipher.__init__c                 C      d S r   r   rh   r   r   r   get_keyS     zAESCipher.get_keyc                 C   r   r   r   rh   r   r   r   get_ivW  r   zAESCipher.get_ivr   c                 C   r   r   r   )r`   keyivoffr   r   r   
initialize[  r   zAESCipher.initializec                 C   r   r   r   r`   rawr   r   r   encrypt_  r   zAESCipher.encryptc                 C   r   r   r   r`   encr   r   r   decryptc  r   zAESCipher.decryptNc                 C   r   r   r   )r`   	data_sizeexcepted_part_sizer   r   r   determine_part_sizeg  r   zAESCipher.determine_part_sizec                 C   s   ||fS r   r   r`   startrx   r   r   r   adjust_rangek  r   zAESCipher.adjust_rangec                 C   s   |d u rd}d|| j  kS r\   r   r`   r_   r   r   r   is_block_alignedn  s   zAESCipher.is_block_alignedc                 C   r   r   r   r`   	part_sizer   r   r   r   is_valid_part_sizes  r   zAESCipher.is_valid_part_sizer   r   )rj   rk   rl   rm   ra   abcabstractmethodr   r   r   r   r   r   r   r   r   r   r   r   r   r   @  s$    



r   c                       st   e Zd ZdZ fddZdd Zdd Zdd	d
Zdd Zdd Z	dd Z
dd Zdd Zdd ZdddZ  ZS )AESCTRCipheru  AES256 加密实现。
        :param str key: 对称加密数据密钥
        :param str start: 对称加密初始随机值
    .. note::
        用户可自行实现对称加密算法，需服务如下规则：
        1、提供对称加密算法名，ALGORITHM
        2、提供静态方法，返回加密密钥和初始随机值（若算法不需要初始随机值，也需要提供）
        3、提供加密解密方法
    c                    s   t t|   t| _d | _d S r   )superr   ra   AES_CTRr   _AESCTRCipher__cipherrh   r   r   r   ra     s   
zAESCTRCipher.__init__c                 C   s
   t | jS r   )
random_keyr   rh   r   r   r   r        
zAESCTRCipher.get_keyc                 C   s   t  S r   )	random_ivrh   r   r   r   r     s   zAESCTRCipher.get_ivr   c                 C   s   t || }| || d S r   )iv_to_big_intinitial_by_counter)r`   r   r   r_   counterr   r   r   r     s   zAESCTRCipher.initializec                 C   s(   t j| j|d}tj|tj|d| _d S )N)initial_value)r	  )r   newr   r   MODE_CTRr  )r`   r   r	  ctrr   r   r   r    s   zAESCTRCipher.initial_by_counterc                 C      | j |S r   r  r   r   r   r   r   r        zAESCTRCipher.encryptc                 C   r  r   r  r   r   r   r   r     r  zAESCTRCipher.decryptc                 C   s@   |r|r||kr|| j  | j  }||fS || j  | j  }||fS r   r   r   r   r   r   r     s   zAESCTRCipher.adjust_rangec                 C   s.   |  |r
|tjk rdS |tj |k rdS dS )NFT)r   r   min_part_sizemax_part_countr   r   r   r   r     s
   zAESCTRCipher.is_valid_part_sizec                 C   s   |  |s	td|| j S )Nz$offset is not align to encrypt block)r   r   r   r   r   r   r   calc_offset  s   

zAESCTRCipher.calc_offsetNc                 C   s   |r|  ||r
|S |tj |krt|| j d | j }|S tj}|tj |k r4|d }|tj |k s)| |sEt|| j d | j }|S )Nr      )r   r   r  intr   r   r   )r`   r   r   r   r   r   r   r     s   
z AESCTRCipher.determine_part_sizer   r   )rj   rk   rl   rm   ra   r   r   r   r  r   r   r   r   r  r   __classcell__r   r   r  r   r   w  s    

	r   c                 C   s   t  | S r   )r   r  rd   )r   r   r   r   r    r   r  c                  C   s6   t  d} | dd tdd | dd   }|S )Nr   r      z>L   )r   r  rd   structpack)r   safe_ivr   r   r   r    s   $r  c                 C   s$   t d| }|d d> |d B }|S )Nz>QQr   @   r   )r  unpack)r   iv_high_low_pair
iv_big_intr   r   r   r    s   r  z%Y-%m-%dT%H:%M:%S.000Zz(?:Mon|Tue|Wed|Thu|Fri|Sat|Sun), (?P<day>0[1-9]|([1-2]\d)|(3[0-1])) (?P<month>Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec) (?P<year>\d+) (?P<hour>([0-1]\d)|(2[0-3])):(?P<minute>[0-5]\d):(?P<second>[0-5]\d) GMT$z(?P<year>\d+)-(?P<month>01|02|03|04|05|06|07|08|09|10|11|12)-(?P<day>0[1-9]|([1-2]\d)|(3[0-1]))T(?P<hour>([0-1]\d)|(2[0-3])):(?P<minute>[0-5]\d):(?P<second>[0-5]\d)\.000Z$r  rG               r  	   
      r  )JanFebMarAprMayJunJulAugSepOctNovDecc                 C   s>   t  ttt| |W  d    S 1 sw   Y  d S r   )_STRPTIME_LOCKr  calendartimegmtimestrptime)time_stringformat_stringr   r   r   to_unixtime  s   $r:  c                 C   s   t | ddS )u   返回符合HTTP标准的GMT时间字符串，用strftime的格式表示就是"%a, %d %b %Y %H:%M:%S GMT"。
    但不能使用strftime，因为strftime的结果是和locale相关的。
    T)usegmtr   )timevalr   r   r   	http_date  s   r=  c           	      C   s   t | }|st| d t|d}t|d }t|d}t|d}t|d}t|d}t|||||| }t	|S )u   把HTTP Date格式的字符串转换为UNIX时间（自1970年1月1日UTC零点的秒数）。

    HTTP Date形如 `Sat, 05 Dec 2015 11:10:29 GMT` 。
    z! is not in valid HTTP date formatdaymonthyearhourminutesecond)
_HTTP_GMT_RErQ   
ValueErrorr  group_MONTH_MAPPINGdatetime	timetupler4  r5  	r8  r"   r>  r?  r@  rA  rB  rC  tmr   r   r   http_to_unixtime   s   

rL  c           	      C   s   t | }|st| d t|d}t|d}t|d}t|d}t|d}t|d}t|||||| }t|S )ue   把ISO8601时间字符串（形如，2012-02-24T06:07:48.000Z）转换为UNIX时间，精确到秒。z is not in valid ISO8601 formatr>  r?  r@  rA  rB  rC  )	_ISO8601_RErQ   rE  r  rF  rH  rI  r4  r5  rJ  r   r   r   iso8601_to_unixtime  s   

rN  c                 C   s
   |  tS r   )strftime_ISO8601_FORMAT)dr   r   r   date_to_iso8601*  r  rR  c                 C   s   t | }tj|S r   )rN  rH  datefromtimestamp)r8  	timestampr   r   r   iso8601_to_date.  s   rV  c              
   C   sH   zt |  W d S  t jy# } z|jtjkr W Y d }~d S d }~ww r   )r&   makedirsr=   errnoEEXIST)dirpathr   r   r   r   	makedir_p3  s   r[  c              
   C   sF   zt |  W dS  ty" } z|jtjkr W Y d}~dS d}~ww )u3   删除文件，如果文件不存在也不报错。N)r&   removeOSErrorrX  ENOENT)filenamer   r   r   r   silently_remove;  s   r`  c              
   C   s^   z	t | | W d S  ty. } z|jtjkr"t| t | | n W Y d }~d S d }~ww r   )r&   renamer]  rX  rY  r`  )srcdstr   r   r   r   force_renameD  s   rd   @  rc   c                 C   sD   d}	 |  |}|sn|t|7 }|| q||kr td|dS )zPcopy data from file-like object fsrc to file-like object fdst, and verify lengthr   r   zIncompleteRead from sourceN)rd   rJ   writer   )fsrcfdstexpected_len
chunk_sizer   num_readbufr   r   r   copyfileobj_and_verifyO  s   


rm  c                 C   >   | d u rdS | d }| d }|d u r|d u rdS dt || S )Nrc   r   r   zline-range=_range_internalranger   lastr   r   r   _make_line_range_stringa     rt  c                 C   rn  )Nrc   r   r   zsplit-range=ro  rq  r   r   r   _make_split_range_stringm  ru  rv  c                 C   s   dd }|| d || S )Nc                 S   s   | d u rdS t | S )Nrc   )str)posr   r   r   to_strz  s   z_range_internal.<locals>.to_strrD   r   )r   rs  ry  r   r   r   rp  y  s   rp  r   )r   r   r   )re  rc   )rrm   email.utilsr   loggingos.pathr&   r+   r9   r   r   	threadingr4  rH  r6  rX  r   r   rP   rV   randomr   sixr  Crypto.Cipherr   Cryptor   Crypto.Utilr   crc64_combiner   compatr	   r
   r   
exceptionsr   r   r   r   rc   r   	getLoggerrj   r   r*   r   r   r#   r%   r/   r2   rB   rL   rK   rM   rN   _MAX_UINT32_MAX_UINT64rO   rT   rZ   objectr[   rp   ry   r}   r~   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   AES_GCMr  add_metaclassABCMetar   r   r  r  r  Lockr3  rP  compilerD  rM  rG  r:  r=  rL  rN  rR  rV  r[  r`  rd  rm  rt  rv  rp  r   r   r   r   <module>   s   
		






%GK
6N
	
