U  W[&@sdZddlZddlZddlZddlZeejZGdddej Z Gddde Z Gddde Z Gd d d e Zd Zd d ZddZdddZdS)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@seZdZdZddZdS)ChunkingZipFilez~ A L{zipfile.ZipFile} object which, with L{readfile}, also gives you access to a file-like object for each entry. cCs&|jdkrtd|js td||}|j|jd|jt}|ddtj krbt dt tj |}|j|tj}|tjr|j|tj|jd@r|d}n |d }||jkrt d |j|f|jtjkrt||jS|jtjkrt||jSt d |j|fd S) z3 Return file-like object for name. )razread() requires mode "r" or "a"z3Attempt to read ZIP archive that was already closedrz Bad magic number for file headerizutf-8cp437z3File name in directory "%s" and header "%s" differ.z-Unsupported compression method %d for file %sN)mode RuntimeErrorfpZgetinfoseek header_offsetread_fileHeaderSizezipfileZstringFileHeaderZ BadZipfilestructZunpackstructFileHeaderZ_FH_FILENAME_LENGTHZ_FH_EXTRA_FIELD_LENGTHZ flag_bitsdecodeZ orig_filenameZ compress_typeZ ZIP_STORED ZipFileEntryZ compress_sizeZ ZIP_DEFLATEDDeflatedZipFileEntry)selfnameZzinfoZfheaderfnameZ fname_strr:/usr/lib/python3/dist-packages/twisted/python/zipstream.pyreadfilesD            zChunkingZipFile.readfileN)__name__ __module__ __qualname____doc__rrrrrrsrc@sdeZdZdZddZddZddZdd Zd d ZeZ d d Z ddZ ddZ ddZ ddZdS) _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} cCs&||_|jj|_||_d|_d|_dS)zC Create a L{_FileEntry} from a L{ChunkingZipFile}. rFN)chunkingZipFiler lengthfinishedclosedrrr rrr__init__]s  z_FileEntry.__init__cCsdS)zD Returns false because zip files should not be ttys Frrrrrisattyhsz_FileEntry.isattycCsd|_d|_|`dS)z/ Close self (file-like object) TN)r"r!r r%rrrcloseosz_FileEntry.closecs4d}tfdddD]}||7}|dkrq0q|S)z Read a line. cs dS)Nr')r rr%rr}r)z%_FileEntry.readline.. )iter)rlineZbyterr%rreadlinexs z_FileEntry.readlinecCs|}|r|StdS)zi Implement next as file does (like readline, except raises StopIteration at EOF) N)r. StopIteration)rZnextlinerrr__next__sz_FileEntry.__next__cCst|S)z1 Returns a list of all the lines )listr%rrr readlinessz_FileEntry.readlinescCs|Sz/ Returns an iterator (so self) rr%rrr xreadlinessz_FileEntry.xreadlinescCs|Sr3rr%rrr__iter__sz_FileEntry.__iter__cCs|SNrr%rrr __enter__sz_FileEntry.__enter__cCs |dSr6)r()rexc_type exc_value tracebackrrr__exit__sz_FileEntry.__exit__N)rrrrr$r&r(r.r0nextr2r4r5r7r;rrrrrFs    rc@s*eZdZdZddZddZd ddZdS) rzJ File-like object used to read an uncompressed entry in a ZipFile cCst|||d|_dS)Nr)rr$ readBytesr#rrrr$szZipFileEntry.__init__cCs|jSr6)r=r%rrrtellszZipFileEntry.tellNcCsv|dkr|j|j}|dks"|jr&dS|jjt||j|j}|jt|7_|j|jkslt||krrd|_|S)Nrr)r')r r=r!rr r minlen)rndatarrrr s zZipFileEntry.read)Nrrrrr$r>r rrrrrsrc@s*eZdZdZddZddZd ddZdS) rzE File-like object used to read a deflated entry in a ZipFile cCs0t|||d|_d|_td|_d|_dS)Nrir))rr$ returnedBytesr=zlibZ decompressobjdecompbufferr#rrrr$s  zDeflatedZipFileEntry.__init__cCs|jSr6)rDr%rrrr>szDeflatedZipFileEntry.tellNcCs`|jr dS|dkr|jg}||j|jj|j|j ||jd||j d|_d|_d |}|j t |7_ |St |j|kr(|jjt|d|j|j }|j t |7_ |s|j|jd|j }d|_d|_|j t |7_ |S|j|j|7_q|jd|}|j|d|_|j t |7_ |SdS)Nr)Zr'i)r!rGappendrF decompressrr r r r=flushjoinrDr@r?)rrAresultrBrrrr sL   zDeflatedZipFileEntry.read)NrCrrrrrsrcCs,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)rinfolistcountFileChunks)filename chunksizeZ totalchunksZzfinforrrcountZipFileChunkss  rTcCs(t|j|\}}|dkr |d7}|p&dS)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} rr')divmod file_size)ZzipinforRcountZextrarrrrPs rP.c csPt|d}tj|s t|t||}|}|}t||D]\}} | j t @} tj ||} | rtj| st| |d8}|VqDtj | d} tj| st| |stj| s6| |} | jdkr|d8}|Vt| d:}| | jkr*| |}|||d8}|VqW5QRXqD|t| |8}|VqDdS)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. rr'rwbN)rospathexistsmakedirsrTZnamelistrOzipZ external_attrDIR_BITrLsplitrrVopenr>r writerP)rQZ directoryZ overwriterRZczfZ remainingnamesZinfosentryrSisdirfZfdirr ZoutfileZhunkrrrunzipIterChunky$s<              rh)rXrrY)rros.pathr[rErZcalcsizerr ZZipFilerobjectrrrr`rTrPrhrrrrs 4j7