U
    
W[&                     @   s   d Z ddlZddlZddlZddlZeejZG dd dej	Z
G dd de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}|dd tj	krbt
dttj|}| j|tj }|tj r| j|tj  |jd@ r|d}n
|d	}||jkrt
d
|j|f |jtjkrt| |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fpZgetinfoseekheader_offsetread_fileHeaderSizezipfileZstringFileHeaderZ
BadZipfilestructZunpackstructFileHeaderZ_FH_FILENAME_LENGTHZ_FH_EXTRA_FIELD_LENGTHZ	flag_bitsdecodeZorig_filenameZcompress_typeZ
ZIP_STOREDZipFileEntryZcompress_sizeZZIP_DEFLATEDDeflatedZipFileEntry)selfnameZzinfoZfheaderfnameZ	fname_str r   :/usr/lib/python3/dist-packages/twisted/python/zipstream.pyreadfile   sD    






 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   isattyh   s    z_FileEntry.isattyc                 C   s   d| _ d| _| `dS )z/
        Close self (file-like object)
        T   N)r"   r!   r	   r%   r   r   r   closeo   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 )Nr'   )r   r   r%   r   r   <lambda>}   r)   z%_FileEntry.readline.<locals>.<lambda>   
)iter)r   lineZbyter   r%   r   readlinex   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
        )listr%   r   r   r   	readlines   s    z_FileEntry.readlinesc                 C   s   | S z/
        Returns an iterator (so self)
        r   r%   r   r   r   
xreadlines   s    z_FileEntry.xreadlinesc                 C   s   | S r3   r   r%   r   r   r   __iter__   s    z_FileEntry.__iter__c                 C   s   | S Nr   r%   r   r   r   	__enter__   s    z_FileEntry.__enter__c                 C   s   |    d S r6   )r(   )r   exc_type	exc_value	tracebackr   r   r   __exit__   s    z_FileEntry.__exit__N)r   r   r   r   r$   r&   r(   r.   r0   nextr2   r4   r5   r7   r;   r   r   r   r   r   F   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   r$   	readBytesr#   r   r   r   r$      s    zZipFileEntry.__init__c                 C   s   | j S r6   )r=   r%   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   r)   r'   )r    r=   r!   r   r	   r   minlen)r   ndatar   r   r   r      s    zZipFileEntry.read)Nr   r   r   r   r$   r>   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   ir)   )r   r$   returnedBytesr=   zlibZdecompressobjdecompbufferr#   r   r   r   r$      s
    zDeflatedZipFileEntry.__init__c                 C   s   | j S r6   )rD   r%   r   r   r   r>      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 )Nr)      Zr'   i   )r!   rG   appendrF   
decompressr   r	   r   r    r=   flushjoinrD   r@   r?   )r   rA   resultrB   r   r   r   r      sL    


zDeflatedZipFileEntry.read)NrC   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totalchunksZzfinfor   r   r   countZipFileChunks  s
    rT   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   r'   )divmod	file_size)ZzipinforR   countZextrar   r   r   rP     s    rP   .   c              
   c   sP  t | d}tj|s t| t| |}| }| }t||D ]\}}	|	j	t
@ }
tj||}|
rtj|st| |d8 }|V  qDtj|d }tj|st| |stj|s6||}|	jdkr|d8 }|V  t|d:}| |	jk r*||}|| |d8 }|V  qW 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   r'   r   wbN)r   ospathexistsmakedirsrT   ZnamelistrO   zipZexternal_attrDIR_BITrL   splitr   rV   openr>   r   writerP   )rQ   Z	directoryZ	overwriterR   ZczfZ	remainingnamesZinfosentryrS   isdirfZfdirr	   ZoutfileZhunkr   r   r   unzipIterChunky$  s<    	









rh   )rX   r   rY   )r   r   os.pathr[   rE   r   Zcalcsizer   r   ZZipFiler   objectr   r   r   r`   rT   rP   rh   r   r   r   r   <module>   s   4j7  