U
    n5{iÐ%  ã                   @   s†   d Z ddlZddlZddlZddlZG dd„ dejƒZG dd„ dƒZG dd„ deƒZ	G d	d
„ d
eƒZ
dZdd„ Zdd„ Zddd„ZdS )zŸ
An incremental approach to unzipping files.  This allows you to unzip a little
bit of a file at a time, which means you can report progress as a file unzips.
é    Nc                   @   s   e Zd ZdZdd„ ZdS )ÚChunkingZipFilez~
    A L{zipfile.ZipFile} object which, with L{readfile}, also gives you access
    to a file-like object for each entry.
    c                 C   s(  | j dkrtdƒ‚| js tdƒ‚|  |¡}| j |jd¡ | j tj¡}|dd… tj	krdt 
d¡‚t tj|¡}| j |tj ¡}|tj r | j |tj ¡ |jd@ r¶| d¡}n
| d	¡}||jkrÞt 
d
|j|f ¡‚|jtjkröt| |jƒS |jtjk�rt| |jƒS t 
d|j|f ¡‚dS )z3
        Return file-like object for name.
        )ÚrÚazread() requires mode "r" or "a"z3Attempt to read ZIP archive that was already closedr   é   z Bad magic number for file headeri   zutf-8Úcp437z3File name in directory "%s" and header "%s" differ.z-Unsupported compression method %d for file %sN)ÚmodeÚRuntimeErrorÚfpÚgetinfoÚseekÚheader_offsetÚreadÚzipfileÚsizeFileHeaderÚstringFileHeaderÚ
BadZipFileÚstructÚunpackÚstructFileHeaderÚ_FH_FILENAME_LENGTHÚ_FH_EXTRA_FIELD_LENGTHÚ	flag_bitsÚdecodeÚorig_filenameÚcompress_typeÚ
ZIP_STOREDÚZipFileEntryÚcompress_sizeÚZIP_DEFLATEDÚDeflatedZipFileEntry)ÚselfÚnameÚzinfoÚfheaderÚfnameÚ	fname_str© r&   ú</tmp/pip-unpacked-wheel-mnhg7r0q/twisted/python/zipstream.pyÚreadfile   s>    






ÿÿÿÿzChunkingZipFile.readfileN)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r(   r&   r&   r&   r'   r      s   r   c                   @   sd   e Zd ZdZdd„ Zdd„ Zdd„ Zdd	„ Zd
d„ ZeZ	dd„ Z
dd„ Zdd„ Zdd„ Zdd„ ZdS )Ú
_FileEntrya!  
    Abstract superclass of both compressed and uncompressed variants of
    file-like objects within a zip archive.

    @ivar chunkingZipFile: a chunking zip file.
    @type chunkingZipFile: L{ChunkingZipFile}

    @ivar length: The number of bytes within the zip file that represent this
    file.  (This is the size on disk, not the number of decompressed bytes
    which will result from reading it.)

    @ivar fp: the underlying file object (that contains pkzip data).  Do not
    touch this, please.  It will quite likely move or go away.

    @ivar closed: File-like 'closed' attribute; True before this file has been
    closed, False after.
    @type closed: L{bool}

    @ivar finished: An older, broken synonym for 'closed'.  Do not touch this,
    please.
    @type finished: L{int}
    c                 C   s&   || _ | j j| _|| _d| _d| _dS )zC
        Create a L{_FileEntry} from a L{ChunkingZipFile}.
        r   FN)ÚchunkingZipFiler	   ÚlengthÚfinishedÚclosed©r    r.   r/   r&   r&   r'   Ú__init__[   s
    
z_FileEntry.__init__c                 C   s   dS )zD
        Returns false because zip files should not be ttys
        Fr&   ©r    r&   r&   r'   Úisattye   s    z_FileEntry.isattyc                 C   s   d| _ d| _| `dS )z/
        Close self (file-like object)
        Té   N)r1   r0   r	   r4   r&   r&   r'   Úclosek   s    z_FileEntry.closec                    s4   d}t ‡ fdd„dƒD ]}||7 }|dkr q0q|S )z
        Read a line.
        ó    c                      s
   ˆ   d¡S )Nr6   )r   r&   r4   r&   r'   Ú<lambda>x   r8   z%_FileEntry.readline.<locals>.<lambda>ó   
)Úiter)r    ÚlineÚbyter&   r4   r'   Úreadlines   s    z_FileEntry.readlinec                 C   s   |   ¡ }|r|S tƒ ‚dS )zi
        Implement next as file does (like readline, except raises StopIteration
        at EOF)
        N)r>   ÚStopIteration)r    Znextliner&   r&   r'   Ú__next__~   s    z_FileEntry.__next__c                 C   s   t | ƒS )z1
        Returns a list of all the lines
        )Úlistr4   r&   r&   r'   Ú	readlines‹   s    z_FileEntry.readlinesc                 C   s   | S ©z/
        Returns an iterator (so self)
        r&   r4   r&   r&   r'   Ú
xreadlines‘   s    z_FileEntry.xreadlinesc                 C   s   | S rC   r&   r4   r&   r&   r'   Ú__iter__—   s    z_FileEntry.__iter__c                 C   s   | S ©Nr&   r4   r&   r&   r'   Ú	__enter__�   s    z_FileEntry.__enter__c                 C   s   |   ¡  d S rF   )r7   )r    Úexc_typeÚ	exc_valueÚ	tracebackr&   r&   r'   Ú__exit__    s    z_FileEntry.__exit__N)r)   r*   r+   r,   r3   r5   r7   r>   r@   ÚnextrB   rD   rE   rG   rK   r&   r&   r&   r'   r-   C   s   
r-   c                   @   s*   e Zd ZdZdd„ Zdd„ Zd	dd„ZdS )
r   zJ
    File-like object used to read an uncompressed entry in a ZipFile
    c                 C   s   t  | ||¡ d| _d S )Nr   )r-   r3   Ú	readBytesr2   r&   r&   r'   r3   ©   s    zZipFileEntry.__init__c                 C   s   | j S rF   )rM   r4   r&   r&   r'   Útell­   s    zZipFileEntry.tellNc                 C   sv   |d kr| j | j }|dks"| jr&dS | jj t|| j | j ƒ¡}|  jt|ƒ7  _| j| j kslt|ƒ|k rrd| _|S )Nr   r8   r6   )r/   rM   r0   r.   r	   r   ÚminÚlen)r    ÚnÚdatar&   r&   r'   r   °   s    zZipFileEntry.read)N©r)   r*   r+   r,   r3   rN   r   r&   r&   r&   r'   r   ¤   s   r   c                   @   s*   e Zd ZdZdd„ Zdd„ Zd	dd„ZdS )
r   zE
    File-like object used to read a deflated entry in a ZipFile
    c                 C   s0   t  | ||¡ d| _d| _t d¡| _d| _d S )Nr   iñÿÿÿr8   )r-   r3   ÚreturnedBytesrM   ÚzlibÚdecompressobjÚdecompÚbufferr2   r&   r&   r'   r3   Á   s
    zDeflatedZipFileEntry.__init__c                 C   s   | j S rF   )rT   r4   r&   r&   r'   rN   È   s    zDeflatedZipFileEntry.tellNc                 C   s`  | j r
dS |d krŒ| jg}| | j | jj | j| j	 ¡¡¡ | | j d¡¡ | | j 
¡ ¡ d| _d| _ d |¡}|  jt|ƒ7  _|S t| jƒ|k �r(| jj t|d| j| j	 ƒ¡}|  j	t|ƒ7  _	|�s| j| j d¡ | j 
¡  }d| _ d| _|  jt|ƒ7  _|S |  j| j |¡7  _qŒ| jd |… }| j|d … | _|  jt|ƒ7  _|S d S )Nr8   ó   Zr6   i   )r0   rX   ÚappendrW   Ú
decompressr.   r	   r   r/   rM   ÚflushÚjoinrT   rP   rO   )r    rQ   ÚresultrR   r&   r&   r'   r   Ë   sD    ÿÿÿ
ÿÿzDeflatedZipFileEntry.read)NrS   r&   r&   r&   r'   r   ¼   s   r   é   c                 C   s,   d}t | ƒ}| ¡ D ]}|t||ƒ7 }q|S )zr
    Predict the number of chunks that will be extracted from the entire
    zipfile, given chunksize blocks.
    r   )r   ÚinfolistÚcountFileChunks)ÚfilenameÚ	chunksizeZtotalchunksÚzfÚinfor&   r&   r'   ÚcountZipFileChunks÷   s
    rf   c                 C   s(   t | j|ƒ\}}|dkr |d7 }|p&dS )a9  
    Count the number of chunks that will result from the given C{ZipInfo}.

    @param zipinfo: a C{zipfile.ZipInfo} instance describing an entry in a zip
    archive to be counted.

    @return: the number of chunks present in the zip file.  (Even an empty file
    counts as one chunk.)
    @rtype: L{int}
    r   r6   )ÚdivmodÚ	file_size)Úzipinforc   ÚcountÚextrar&   r&   r'   ra     s    ra   Ú.é   c              
   c   sP  t | dƒ}tj |¡s t |¡ t| |ƒ}| ¡ }| ¡ }t||ƒD �]\}}	|	j	t
@ }
tj ||¡}|
r�tj |¡s€t |¡ |d8 }|V  qDtj |¡d }tj |¡s¶t |¡ |sÈtj |¡�s6| |¡}|	jdkrê|d8 }|V  t|dƒ�:}| ¡ |	jk �r*| |¡}| |¡ |d8 }|V  qöW 5 Q R X qD|t|	|ƒ8 }|V  qDdS )zï
    Return a generator for the zipfile.  This implementation will yield after
    every chunksize uncompressed bytes, or at the end of a file, whichever
    comes first.

    The value it yields is the number of chunks left to unzip.
    r   r6   r   ÚwbN)r   ÚosÚpathÚexistsÚmakedirsrf   Únamelistr`   ÚzipÚexternal_attrÚDIR_BITr]   Úsplitr(   rh   ÚopenrN   r   Úwritera   )rb   Ú	directoryÚ	overwriterc   ZczfÚ	remainingÚnamesZinfosÚentryre   ÚisdirÚfZfdirr	   ÚoutfileZhunkr&   r&   r'   ÚunzipIterChunky  s<    









r‚   )rl   r   rm   )r,   Úos.pathro   r   r   rU   ÚZipFiler   r-   r   r   rv   rf   ra   r‚   r&   r&   r&   r'   Ú<module>   s   3a8