comparison lib/python/gzip_plus.py @ 353:6b1137bdbd0d trim

give access to block offsets via callback
author Henry S. Thompson <ht@inf.ed.ac.uk>
date Mon, 16 Mar 2026 10:43:01 +0000
parents 4ead0a390a29
children a0d476144685
comparison
equal deleted inserted replaced
352:4497f2ad3a6f 353:6b1137bdbd0d
178 # Overridden with internal file object to be closed, if only a filename 178 # Overridden with internal file object to be closed, if only a filename
179 # is passed in 179 # is passed in
180 myfileobj = None 180 myfileobj = None
181 181
182 def __init__(self, filename=None, mode=None, 182 def __init__(self, filename=None, mode=None,
183 compresslevel=_COMPRESS_LEVEL_BEST, fileobj=None, mtime=None): 183 compresslevel=_COMPRESS_LEVEL_BEST, fileobj=None, mtime=None,
184 eob_callback=None):
184 """Constructor for the GzipFile class. 185 """Constructor for the GzipFile class.
185 186
186 At least one of fileobj and filename must be given a 187 At least one of fileobj and filename must be given a
187 non-trivial value. 188 non-trivial value.
188 189
211 The optional mtime argument is the timestamp requested by gzip. The time 212 The optional mtime argument is the timestamp requested by gzip. The time
212 is in Unix format, i.e., seconds since 00:00:00 UTC, January 1, 1970. 213 is in Unix format, i.e., seconds since 00:00:00 UTC, January 1, 1970.
213 If mtime is omitted or None, the current time is used. Use mtime = 0 214 If mtime is omitted or None, the current time is used. Use mtime = 0
214 to generate a compressed stream that does not depend on creation time. 215 to generate a compressed stream that does not depend on creation time.
215 216
217 The optional eobCallback will be called with block boundaries if provided.
216 """ 218 """
217 219
218 if mode and ('t' in mode or 'U' in mode): 220 if mode and ('t' in mode or 'U' in mode):
219 raise ValueError("Invalid mode: {!r}".format(mode)) 221 raise ValueError("Invalid mode: {!r}".format(mode))
220 if mode and 'b' not in mode: 222 if mode and 'b' not in mode:
234 mode = getattr(fileobj, 'mode', 'rb') 236 mode = getattr(fileobj, 'mode', 'rb')
235 237
236 238
237 if mode.startswith('r'): 239 if mode.startswith('r'):
238 self.mode = READ 240 self.mode = READ
239 raw = _GzipReader(fileobj) 241 raw = _GzipReader(fileobj, eob_callback)
240 self._buffer = io.BufferedReader(raw) 242 self._buffer = io.BufferedReader(raw)
241 self.name = filename 243 self.name = filename
242 244
243 elif mode.startswith(('w', 'a', 'x')): 245 elif mode.startswith(('w', 'a', 'x')):
244 if origmode is None: 246 if origmode is None:
520 _read_exact(fp, 2) # Read & discard the 16-bit header CRC 522 _read_exact(fp, 2) # Read & discard the 16-bit header CRC
521 return last_mtime 523 return last_mtime
522 524
523 525
524 class _GzipReader(_compression.DecompressReader): 526 class _GzipReader(_compression.DecompressReader):
525 def __init__(self, fp): 527 def __init__(self, fp, eob_callback):
526 super().__init__(_PaddedFile(fp), zlib._ZlibDecompressor, 528 super().__init__(_PaddedFile(fp), zlib._ZlibDecompressor,
527 wbits=-zlib.MAX_WBITS) 529 wbits=-zlib.MAX_WBITS)
528 # Set flag indicating start of a new member 530 # Set flag indicating start of a new member
529 self._new_member = True 531 self._new_member = True
530 self._last_mtime = None 532 self._last_mtime = None
531 self._cur_block = None 533 self._cur_block = None
532 self._next_block = 0 534 self._next_block = 0
535 self._eob_callback = eob_callback
533 536
534 def _init_read(self): 537 def _init_read(self):
535 self._crc = zlib.crc32(b"") 538 self._crc = zlib.crc32(b"")
536 self._stream_size = 0 # Decompressed size of unconcatenated stream 539 self._stream_size = 0 # Decompressed size of unconcatenated stream
537 540
616 if c: 619 if c:
617 self._fp.prepend(c) 620 self._fp.prepend(c)
618 621
619 self._cur_block = self._next_block 622 self._cur_block = self._next_block
620 self._next_block = self._fp.tell() 623 self._next_block = self._fp.tell()
624 if self._eob_callback is not None:
625 self._eob_callback(self._cur_block, self._next_block)
621 626
622 def _rewind(self): 627 def _rewind(self):
623 super()._rewind() 628 super()._rewind()
624 self._new_member = True 629 self._new_member = True
625 630