Changeset 388 for python/vendor/current/Lib/gzip.py
- Timestamp:
- Mar 19, 2014, 11:11:30 AM (11 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
python/vendor/current/Lib/gzip.py
r2 r388 6 6 # based on Andrew Kuchling's minigzip.py distributed with the zlib module 7 7 8 import struct, sys, time 8 import struct, sys, time, os 9 9 import zlib 10 import io 10 11 import __builtin__ 11 12 … … 33 34 return GzipFile(filename, mode, compresslevel) 34 35 35 class GzipFile :36 class GzipFile(io.BufferedIOBase): 36 37 """The GzipFile class simulates most of the methods of a file object with 37 38 the exception of the readinto() and truncate() methods. … … 43 44 44 45 def __init__(self, filename=None, mode=None, 45 compresslevel=9, fileobj=None ):46 compresslevel=9, fileobj=None, mtime=None): 46 47 """Constructor for the GzipFile class. 47 48 … … 66 67 for cross-platform portability. 67 68 68 The compresslevel argument is an integer from 1to 9 controlling the69 The compresslevel argument is an integer from 0 to 9 controlling the 69 70 level of compression; 1 is fastest and produces the least compression, 70 and 9 is slowest and produces the most compression. The default is 9. 71 and 9 is slowest and produces the most compression. 0 is no compression 72 at all. The default is 9. 73 74 The mtime argument is an optional numeric timestamp to be written 75 to the stream when compressing. All gzip compressed streams 76 are required to contain a timestamp. If omitted or None, the 77 current time is used. This module ignores the timestamp when 78 decompressing; however, some programs, such as gunzip, make use 79 of it. The format of the timestamp is the same as that of the 80 return value of time.time() and of the st_mtime member of the 81 object returned by os.stat(). 71 82 72 83 """ 73 84 85 # Make sure we don't inadvertently enable universal newlines on the 86 # underlying file object - in read mode, this causes data corruption. 87 if mode: 88 mode = mode.replace('U', '') 74 89 # guarantee the file is opened in binary mode on platforms 75 90 # that care about that sort of thing … … 79 94 fileobj = self.myfileobj = __builtin__.open(filename, mode or 'rb') 80 95 if filename is None: 81 if hasattr(fileobj, 'name'): filename = fileobj.name 82 else: filename = '' 96 # Issue #13781: os.fdopen() creates a fileobj with a bogus name 97 # attribute. Avoid saving this in the gzip header's filename field. 98 if hasattr(fileobj, 'name') and fileobj.name != '<fdopen>': 99 filename = fileobj.name 100 else: 101 filename = '' 83 102 if mode is None: 84 103 if hasattr(fileobj, 'mode'): mode = fileobj.mode … … 89 108 # Set flag indicating start of a new member 90 109 self._new_member = True 110 # Buffer data read from gzip file. extrastart is offset in 111 # stream where buffer starts. extrasize is number of 112 # bytes remaining in buffer from current stream position. 91 113 self.extrabuf = "" 92 114 self.extrasize = 0 115 self.extrastart = 0 93 116 self.name = filename 94 117 # Starts small, scales exponentially … … 108 131 self.fileobj = fileobj 109 132 self.offset = 0 133 self.mtime = mtime 110 134 111 135 if self.mode == WRITE: … … 124 148 return '<gzip ' + s[1:-1] + ' ' + hex(id(self)) + '>' 125 149 150 def _check_closed(self): 151 """Raises a ValueError if the underlying file object has been closed. 152 153 """ 154 if self.closed: 155 raise ValueError('I/O operation on closed file.') 156 126 157 def _init_write(self, filename): 127 158 self.name = filename … … 134 165 self.fileobj.write('\037\213') # magic header 135 166 self.fileobj.write('\010') # compression method 136 fname = self.name167 fname = os.path.basename(self.name) 137 168 if fname.endswith(".gz"): 138 169 fname = fname[:-3] … … 141 172 flags = FNAME 142 173 self.fileobj.write(chr(flags)) 143 write32u(self.fileobj, long(time.time())) 174 mtime = self.mtime 175 if mtime is None: 176 mtime = time.time() 177 write32u(self.fileobj, long(mtime)) 144 178 self.fileobj.write('\002') 145 179 self.fileobj.write('\377') … … 159 193 raise IOError, 'Unknown compression method' 160 194 flag = ord( self.fileobj.read(1) ) 161 # modtime = self.fileobj.read(4)195 self.mtime = read32(self.fileobj) 162 196 # extraflag = self.fileobj.read(1) 163 197 # os = self.fileobj.read(1) 164 self.fileobj.read( 6)198 self.fileobj.read(2) 165 199 166 200 if flag & FEXTRA: … … 184 218 self.fileobj.read(2) # Read & discard the 16-bit header CRC 185 219 186 187 220 def write(self,data): 221 self._check_closed() 188 222 if self.mode != WRITE: 189 223 import errno … … 192 226 if self.fileobj is None: 193 227 raise ValueError, "write() on closed GzipFile object" 228 229 # Convert data type if called by io.BufferedWriter. 230 if isinstance(data, memoryview): 231 data = data.tobytes() 232 194 233 if len(data) > 0: 195 234 self.size = self.size + len(data) … … 198 237 self.offset += len(data) 199 238 239 return len(data) 240 200 241 def read(self, size=-1): 242 self._check_closed() 201 243 if self.mode != READ: 202 244 import errno … … 223 265 size = self.extrasize 224 266 225 chunk = self.extrabuf[:size]226 self.extrabuf = self.extrabuf[size:]267 offset = self.offset - self.extrastart 268 chunk = self.extrabuf[offset: offset + size] 227 269 self.extrasize = self.extrasize - size 228 270 … … 231 273 232 274 def _unread(self, buf): 233 self.extrabuf = buf + self.extrabuf234 275 self.extrasize = len(buf) + self.extrasize 235 276 self.offset -= len(buf) … … 287 328 def _add_read_data(self, data): 288 329 self.crc = zlib.crc32(data, self.crc) & 0xffffffffL 289 self.extrabuf = self.extrabuf + data 330 offset = self.offset - self.extrastart 331 self.extrabuf = self.extrabuf[offset:] + data 290 332 self.extrasize = self.extrasize + len(data) 333 self.extrastart = self.offset 291 334 self.size = self.size + len(data) 292 335 … … 306 349 raise IOError, "Incorrect length of data produced" 307 350 351 # Gzip files can be padded with zeroes and still have archives. 352 # Consume all zero bytes and set the file position to the first 353 # non-zero byte. See http://www.gzip.org/#faq8 354 c = "\x00" 355 while c == "\x00": 356 c = self.fileobj.read(1) 357 if c: 358 self.fileobj.seek(-1, 1) 359 360 @property 361 def closed(self): 362 return self.fileobj is None 363 308 364 def close(self): 309 365 if self.fileobj is None: … … 321 377 self.myfileobj = None 322 378 323 def __del__(self):324 try:325 if (self.myfileobj is None and326 self.fileobj is None):327 return328 except AttributeError:329 return330 self.close()331 332 379 def flush(self,zlib_mode=zlib.Z_SYNC_FLUSH): 380 self._check_closed() 333 381 if self.mode == WRITE: 334 382 # Ensure the compressor's buffer is flushed 335 383 self.fileobj.write(self.compress.flush(zlib_mode)) 336 self.fileobj.flush()384 self.fileobj.flush() 337 385 338 386 def fileno(self): … … 343 391 """ 344 392 return self.fileobj.fileno() 345 346 def isatty(self):347 return False348 349 def tell(self):350 return self.offset351 393 352 394 def rewind(self): … … 359 401 self.extrabuf = "" 360 402 self.extrasize = 0 403 self.extrastart = 0 361 404 self.offset = 0 405 406 def readable(self): 407 return self.mode == READ 408 409 def writable(self): 410 return self.mode == WRITE 411 412 def seekable(self): 413 return True 362 414 363 415 def seek(self, offset, whence=0): … … 371 423 raise IOError('Negative seek in write mode') 372 424 count = offset - self.offset 373 for i in range(count // 1024):425 for i in xrange(count // 1024): 374 426 self.write(1024 * '\0') 375 427 self.write((count % 1024) * '\0') … … 379 431 self.rewind() 380 432 count = offset - self.offset 381 for i in range(count // 1024):433 for i in xrange(count // 1024): 382 434 self.read(1024) 383 435 self.read(count % 1024) 384 436 437 return self.offset 438 385 439 def readline(self, size=-1): 386 440 if size < 0: 441 # Shortcut common case - newline found in buffer. 442 offset = self.offset - self.extrastart 443 i = self.extrabuf.find('\n', offset) + 1 444 if i > 0: 445 self.extrasize -= i - offset 446 self.offset += i - offset 447 return self.extrabuf[offset: i] 448 387 449 size = sys.maxint 388 450 readsize = self.min_readsize … … 413 475 self.min_readsize = min(readsize, self.min_readsize * 2, 512) 414 476 return ''.join(bufs) # Return resulting line 415 416 def readlines(self, sizehint=0):417 # Negative numbers result in reading all the lines418 if sizehint <= 0:419 sizehint = sys.maxint420 L = []421 while sizehint > 0:422 line = self.readline()423 if line == "":424 break425 L.append(line)426 sizehint = sizehint - len(line)427 428 return L429 430 def writelines(self, L):431 for line in L:432 self.write(line)433 434 def __iter__(self):435 return self436 437 def next(self):438 line = self.readline()439 if line:440 return line441 else:442 raise StopIteration443 477 444 478
Note:
See TracChangeset
for help on using the changeset viewer.