Mercurial > ~astiob > upreckon > hgweb
comparison zipfiles/zipfile314.diff @ 170:b993d9257400
Updated zipfiles
| author | Oleg Oshmyan <chortos@inbox.lv> |
|---|---|
| date | Thu, 16 Jun 2011 01:24:10 +0100 |
| parents | zipfiles/zipfile313.diff@45d4a9dc707b |
| children |
comparison
equal
deleted
inserted
replaced
| 169:d7f4b051ad79 | 170:b993d9257400 |
|---|---|
| 1 --- /usr/local/lib/python3.1/zipfile.py 2011-06-16 01:02:30.000000000 +0100 | |
| 2 +++ zipfile31.py 2011-06-16 01:16:53.000000000 +0100 | |
| 3 @@ -3,6 +3,7 @@ | |
| 4 | |
| 5 XXX references to utf-8 need further investigation. | |
| 6 """ | |
| 7 +# Improved by Chortos-2 in 2010 (added bzip2 support) | |
| 8 import struct, os, time, sys, shutil | |
| 9 import binascii, io, stat | |
| 10 | |
| 11 @@ -13,8 +14,13 @@ | |
| 12 zlib = None | |
| 13 crc32 = binascii.crc32 | |
| 14 | |
| 15 +try: | |
| 16 + import bz2 # We may need its compression method | |
| 17 +except ImportError: | |
| 18 + bz2 = None | |
| 19 + | |
| 20 __all__ = ["BadZipfile", "error", "ZIP_STORED", "ZIP_DEFLATED", "is_zipfile", | |
| 21 - "ZipInfo", "ZipFile", "PyZipFile", "LargeZipFile" ] | |
| 22 + "ZipInfo", "ZipFile", "PyZipFile", "LargeZipFile", "ZIP_BZIP2" ] | |
| 23 | |
| 24 class BadZipfile(Exception): | |
| 25 pass | |
| 26 @@ -35,6 +41,7 @@ class LargeZipFile(Exception): | |
| 27 # constants for Zip file compression methods | |
| 28 ZIP_STORED = 0 | |
| 29 ZIP_DEFLATED = 8 | |
| 30 +ZIP_BZIP2 = 12 | |
| 31 # Other ZIP compression methods not supported | |
| 32 | |
| 33 # Below are some formats and associated data for reading/writing headers using | |
| 34 @@ -477,6 +484,9 @@ def __init__(self, fileobj, zipinfo, | |
| 35 self.compreadsize = 64*1024 | |
| 36 if self.compress_type == ZIP_DEFLATED: | |
| 37 self.dc = zlib.decompressobj(-15) | |
| 38 + elif self.compress_type == ZIP_BZIP2: | |
| 39 + self.dc = bz2.BZ2Decompressor() | |
| 40 + self.compreadsize = 900000 | |
| 41 | |
| 42 if hasattr(zipinfo, 'CRC'): | |
| 43 self._expected_crc = zipinfo.CRC | |
| 44 @@ -604,7 +614,7 @@ def read(self, size = None): | |
| 45 if self.compress_type == ZIP_STORED: | |
| 46 lr = len(self.readbuffer) | |
| 47 bytesToRead = min(bytesToRead, size - lr) | |
| 48 - elif self.compress_type == ZIP_DEFLATED: | |
| 49 + else: | |
| 50 if len(self.readbuffer) > size: | |
| 51 # the user has requested fewer bytes than we've already | |
| 52 # pulled through the decompressor; don't read any more | |
| 53 @@ -639,14 +649,17 @@ def read(self, size = None): | |
| 54 newdata = bytes(map(self.decrypter, newdata)) | |
| 55 | |
| 56 # decompress newly read data if necessary | |
| 57 - if newdata and self.compress_type == ZIP_DEFLATED: | |
| 58 + if newdata and self.compress_type != ZIP_STORED: | |
| 59 newdata = self.dc.decompress(newdata) | |
| 60 - self.rawbuffer = self.dc.unconsumed_tail | |
| 61 + self.rawbuffer = self.dc.unconsumed_tail if self.compress_type == ZIP_DEFLATED else '' | |
| 62 if self.eof and len(self.rawbuffer) == 0: | |
| 63 # we're out of raw bytes (both from the file and | |
| 64 # the local buffer); flush just to make sure the | |
| 65 # decompressor is done | |
| 66 - newdata += self.dc.flush() | |
| 67 + try: | |
| 68 + newdata += self.dc.flush() | |
| 69 + except AttributeError: | |
| 70 + pass | |
| 71 # prevent decompressor from being used again | |
| 72 self.dc = None | |
| 73 | |
| 74 @@ -674,7 +687,8 @@ class ZipFile: | |
| 75 file: Either the path to the file, or a file-like object. | |
| 76 If it is a path, the file will be opened and closed by ZipFile. | |
| 77 mode: The mode can be either read "r", write "w" or append "a". | |
| 78 - compression: ZIP_STORED (no compression) or ZIP_DEFLATED (requires zlib). | |
| 79 + compression: ZIP_STORED (no compression), ZIP_DEFLATED (requires zlib), | |
| 80 + or ZIP_BZIP2 (requires bz2). | |
| 81 allowZip64: if True ZipFile will create files with ZIP64 extensions when | |
| 82 needed, otherwise it will raise an exception when this would | |
| 83 be necessary. | |
| 84 @@ -694,6 +708,10 @@ def __init__(self, file, mode="r", c | |
| 85 if not zlib: | |
| 86 raise RuntimeError( | |
| 87 "Compression requires the (missing) zlib module") | |
| 88 + elif compression == ZIP_BZIP2: | |
| 89 + if not bz2: | |
| 90 + raise RuntimeError( | |
| 91 + "Compression requires the (missing) bz2 module") | |
| 92 else: | |
| 93 raise RuntimeError("That compression method is not supported") | |
| 94 | |
| 95 @@ -1053,7 +1071,10 @@ def _writecheck(self, zinfo): | |
| 96 if zinfo.compress_type == ZIP_DEFLATED and not zlib: | |
| 97 raise RuntimeError( | |
| 98 "Compression requires the (missing) zlib module") | |
| 99 - if zinfo.compress_type not in (ZIP_STORED, ZIP_DEFLATED): | |
| 100 + if zinfo.compress_type == ZIP_BZIP2 and not bz2: | |
| 101 + raise RuntimeError( | |
| 102 + "Compression requires the (missing) bz2 module") | |
| 103 + if zinfo.compress_type not in (ZIP_STORED, ZIP_DEFLATED, ZIP_BZIP2): | |
| 104 raise RuntimeError("That compression method is not supported") | |
| 105 if zinfo.file_size > ZIP64_LIMIT: | |
| 106 if not self._allowZip64: | |
| 107 @@ -1114,6 +1135,8 @@ def write(self, filename, arcname=No | |
| 108 if zinfo.compress_type == ZIP_DEFLATED: | |
| 109 cmpr = zlib.compressobj(zlib.Z_DEFAULT_COMPRESSION, | |
| 110 zlib.DEFLATED, -15) | |
| 111 + elif zinfo.compress_type == ZIP_BZIP2: | |
| 112 + cmpr = bz2.BZ2Compressor() | |
| 113 else: | |
| 114 cmpr = None | |
| 115 while 1: | |
| 116 @@ -1174,6 +1197,10 @@ def writestr(self, zinfo_or_arcname, | |
| 117 zlib.DEFLATED, -15) | |
| 118 data = co.compress(data) + co.flush() | |
| 119 zinfo.compress_size = len(data) # Compressed size | |
| 120 + elif zinfo.compress_type == ZIP_BZIP2: | |
| 121 + co = bz2.BZ2Compressor() | |
| 122 + data = co.compress(data) + co.flush() | |
| 123 + zinfo.compress_size = len(data) # Compressed size | |
| 124 else: | |
| 125 zinfo.compress_size = zinfo.file_size | |
| 126 zinfo.header_offset = self.fp.tell() # Start of header data |
