annotate lib/python/gzip_plus.py @ 375:a74a3335e0d2 plus

now linked from $CCC, updated to use $CCC and better logging
author Henry S. Thompson <ht@inf.ed.ac.uk>
date Wed, 22 Apr 2026 15:09:30 +0100
parents a0d476144685
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
355
a0d476144685 cython flags
Henry S. Thompson <ht@inf.ed.ac.uk>
parents: 353
diff changeset
1 # cython: profile=False, language_level=3str
350
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
2 """Functions that read and write gzipped files.
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
3
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
4 The user of the file doesn't have to worry about the compression,
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
5 but random access is not allowed."""
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
6
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
7 # based on Andrew Kuchling's minigzip.py distributed with the zlib module
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
8
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
9 import _compression
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
10 import builtins
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
11 import io
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
12 import os
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
13 import struct
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
14 import sys
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
15 import time
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
16 import weakref
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
17 import zlib
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
18
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
19 __all__ = ["BadGzipFile", "GzipFile", "open", "compress", "decompress"]
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
20
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
21 FTEXT, FHCRC, FEXTRA, FNAME, FCOMMENT = 1, 2, 4, 8, 16
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
22
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
23 READ = 'rb'
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
24 WRITE = 'wb'
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
25
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
26 _COMPRESS_LEVEL_FAST = 1
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
27 _COMPRESS_LEVEL_TRADEOFF = 6
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
28 _COMPRESS_LEVEL_BEST = 9
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
29
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
30 READ_BUFFER_SIZE = 128 * 1024
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
31 _WRITE_BUFFER_SIZE = 4 * io.DEFAULT_BUFFER_SIZE
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
32
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
33
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
34 def open(filename, mode="rb", compresslevel=_COMPRESS_LEVEL_BEST,
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
35 encoding=None, errors=None, newline=None):
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
36 """Open a gzip-compressed file in binary or text mode.
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
37
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
38 The filename argument can be an actual filename (a str or bytes object), or
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
39 an existing file object to read from or write to.
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
40
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
41 The mode argument can be "r", "rb", "w", "wb", "x", "xb", "a" or "ab" for
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
42 binary mode, or "rt", "wt", "xt" or "at" for text mode. The default mode is
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
43 "rb", and the default compresslevel is 9.
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
44
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
45 For binary mode, this function is equivalent to the GzipFile constructor:
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
46 GzipFile(filename, mode, compresslevel). In this case, the encoding, errors
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
47 and newline arguments must not be provided.
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
48
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
49 For text mode, a GzipFile object is created, and wrapped in an
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
50 io.TextIOWrapper instance with the specified encoding, error handling
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
51 behavior, and line ending(s).
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
52
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
53 """
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
54 if "t" in mode:
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
55 if "b" in mode:
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
56 raise ValueError("Invalid mode: %r" % (mode,))
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
57 else:
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
58 if encoding is not None:
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
59 raise ValueError("Argument 'encoding' not supported in binary mode")
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
60 if errors is not None:
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
61 raise ValueError("Argument 'errors' not supported in binary mode")
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
62 if newline is not None:
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
63 raise ValueError("Argument 'newline' not supported in binary mode")
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
64
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
65 gz_mode = mode.replace("t", "")
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
66 if isinstance(filename, (str, bytes, os.PathLike)):
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
67 binary_file = GzipFile(filename, gz_mode, compresslevel)
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
68 elif hasattr(filename, "read") or hasattr(filename, "write"):
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
69 binary_file = GzipFile(None, gz_mode, compresslevel, filename)
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
70 else:
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
71 raise TypeError("filename must be a str or bytes object, or a file")
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
72
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
73 if "t" in mode:
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
74 encoding = io.text_encoding(encoding)
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
75 return io.TextIOWrapper(binary_file, encoding, errors, newline)
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
76 else:
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
77 return binary_file
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
78
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
79 def write32u(output, value):
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
80 # The L format writes the bit pattern correctly whether signed
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
81 # or unsigned.
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
82 output.write(struct.pack("<L", value))
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
83
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
84 class _PaddedFile:
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
85 """Minimal read-only file object that prepends a string to the contents
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
86 of an actual file. Shouldn't be used outside of gzip.py, as it lacks
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
87 essential functionality."""
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
88
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
89 def __init__(self, f, prepend=b''):
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
90 #print('i',len(prepend))
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
91 self._buffer = prepend
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
92 self._length = len(prepend)
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
93 self.file = f
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
94 self._read = 0
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
95 self._pos = 0
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
96
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
97 def tell(self):
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
98 if self._read is None:
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
99 return self.file.tell()
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
100 else:
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
101 return self._pos
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
102
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
103 def read(self, size):
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
104 #print('r',size, self._read, self._length, self._pos)
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
105 if self._read is None:
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
106 res = self.file.read(size)
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
107 self._pos += len(res)
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
108 #print('r1', self._pos)
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
109 return res
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
110 if self._read + size <= self._length:
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
111 read = self._read
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
112 self._read += size
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
113 self._pos += size
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
114 #print('r2', self._pos)
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
115 return self._buffer[read:self._read]
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
116 else:
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
117 read = self._read
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
118 self._read = None
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
119 avail = self._length - read
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
120 balance = size - avail
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
121 res = self.file.read(balance)
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
122 self._pos += avail + len(res)
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
123 #print('r3', self._pos)
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
124 return self._buffer[read:] + res
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
125
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
126 def prepend(self, prepend=b''):
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
127 #print('p',len(prepend))
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
128 self._pos -= len(prepend)
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
129 if self._read is None:
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
130 self._buffer = prepend
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
131 else: # Assume data was read since the last prepend() call
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
132 self._read -= len(prepend)
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
133 return
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
134 self._length = len(self._buffer)
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
135 self._read = 0
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
136
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
137 def seek(self, off):
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
138 #print('o',off)
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
139 self._read = None
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
140 self._buffer = None
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
141 self._pos = self.file.seek(off)
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
142 return self._pos
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
143
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
144 def seekable(self):
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
145 return True # Allows fast-forwarding even in unseekable streams
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
146
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
147
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
148 class BadGzipFile(OSError):
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
149 """Exception raised in some cases for invalid gzip files."""
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
150
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
151
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
152 class _WriteBufferStream(io.RawIOBase):
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
153 """Minimal object to pass WriteBuffer flushes into GzipFile"""
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
154 def __init__(self, gzip_file):
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
155 self.gzip_file = weakref.ref(gzip_file)
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
156
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
157 def write(self, data):
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
158 gzip_file = self.gzip_file()
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
159 if gzip_file is None:
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
160 raise RuntimeError("lost gzip_file")
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
161 return gzip_file._write_raw(data)
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
162
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
163 def seekable(self):
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
164 return False
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
165
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
166 def writable(self):
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
167 return True
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
168
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
169
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
170 class GzipFile(_compression.BaseStream):
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
171 """The GzipFile class simulates most of the methods of a file object with
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
172 the exception of the truncate() method.
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
173
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
174 This class only supports opening files in binary mode. If you need to open a
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
175 compressed file in text mode, use the gzip.open() function.
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
176
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
177 """
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
178
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
179 # Overridden with internal file object to be closed, if only a filename
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
180 # is passed in
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
181 myfileobj = None
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
182
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
183 def __init__(self, filename=None, mode=None,
353
6b1137bdbd0d give access to block offsets via callback
Henry S. Thompson <ht@inf.ed.ac.uk>
parents: 350
diff changeset
184 compresslevel=_COMPRESS_LEVEL_BEST, fileobj=None, mtime=None,
6b1137bdbd0d give access to block offsets via callback
Henry S. Thompson <ht@inf.ed.ac.uk>
parents: 350
diff changeset
185 eob_callback=None):
350
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
186 """Constructor for the GzipFile class.
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
187
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
188 At least one of fileobj and filename must be given a
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
189 non-trivial value.
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
190
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
191 The new class instance is based on fileobj, which can be a regular
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
192 file, an io.BytesIO object, or any other object which simulates a file.
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
193 It defaults to None, in which case filename is opened to provide
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
194 a file object.
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
195
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
196 When fileobj is not None, the filename argument is only used to be
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
197 included in the gzip file header, which may include the original
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
198 filename of the uncompressed file. It defaults to the filename of
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
199 fileobj, if discernible; otherwise, it defaults to the empty string,
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
200 and in this case the original filename is not included in the header.
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
201
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
202 The mode argument can be any of 'r', 'rb', 'a', 'ab', 'w', 'wb', 'x', or
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
203 'xb' depending on whether the file will be read or written. The default
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
204 is the mode of fileobj if discernible; otherwise, the default is 'rb'.
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
205 A mode of 'r' is equivalent to one of 'rb', and similarly for 'w' and
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
206 'wb', 'a' and 'ab', and 'x' and 'xb'.
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
207
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
208 The compresslevel argument is an integer from 0 to 9 controlling the
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
209 level of compression; 1 is fastest and produces the least compression,
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
210 and 9 is slowest and produces the most compression. 0 is no compression
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
211 at all. The default is 9.
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
212
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
213 The optional mtime argument is the timestamp requested by gzip. The time
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
214 is in Unix format, i.e., seconds since 00:00:00 UTC, January 1, 1970.
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
215 If mtime is omitted or None, the current time is used. Use mtime = 0
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
216 to generate a compressed stream that does not depend on creation time.
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
217
353
6b1137bdbd0d give access to block offsets via callback
Henry S. Thompson <ht@inf.ed.ac.uk>
parents: 350
diff changeset
218 The optional eobCallback will be called with block boundaries if provided.
350
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
219 """
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
220
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
221 if mode and ('t' in mode or 'U' in mode):
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
222 raise ValueError("Invalid mode: {!r}".format(mode))
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
223 if mode and 'b' not in mode:
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
224 mode += 'b'
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
225
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
226 try:
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
227 if fileobj is None:
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
228 fileobj = self.myfileobj = builtins.open(filename, mode or 'rb')
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
229 if filename is None:
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
230 filename = getattr(fileobj, 'name', '')
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
231 if not isinstance(filename, (str, bytes)):
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
232 filename = ''
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
233 else:
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
234 filename = os.fspath(filename)
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
235 origmode = mode
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
236 if mode is None:
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
237 mode = getattr(fileobj, 'mode', 'rb')
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
238
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
239
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
240 if mode.startswith('r'):
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
241 self.mode = READ
353
6b1137bdbd0d give access to block offsets via callback
Henry S. Thompson <ht@inf.ed.ac.uk>
parents: 350
diff changeset
242 raw = _GzipReader(fileobj, eob_callback)
350
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
243 self._buffer = io.BufferedReader(raw)
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
244 self.name = filename
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
245
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
246 elif mode.startswith(('w', 'a', 'x')):
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
247 if origmode is None:
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
248 import warnings
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
249 warnings.warn(
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
250 "GzipFile was opened for writing, but this will "
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
251 "change in future Python releases. "
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
252 "Specify the mode argument for opening it for writing.",
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
253 FutureWarning, 2)
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
254 self.mode = WRITE
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
255 self._init_write(filename)
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
256 self.compress = zlib.compressobj(compresslevel,
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
257 zlib.DEFLATED,
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
258 -zlib.MAX_WBITS,
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
259 zlib.DEF_MEM_LEVEL,
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
260 0)
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
261 self._write_mtime = mtime
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
262 self._buffer_size = _WRITE_BUFFER_SIZE
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
263 self._buffer = io.BufferedWriter(_WriteBufferStream(self),
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
264 buffer_size=self._buffer_size)
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
265 else:
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
266 raise ValueError("Invalid mode: {!r}".format(mode))
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
267
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
268 self.fileobj = fileobj
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
269
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
270 if self.mode == WRITE:
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
271 self._write_gzip_header(compresslevel)
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
272 except:
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
273 # Avoid a ResourceWarning if the write fails,
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
274 # eg read-only file or KeyboardInterrupt
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
275 self._close()
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
276 raise
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
277
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
278 @property
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
279 def mtime(self):
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
280 """Last modification time read from stream, or None"""
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
281 return self._buffer.raw._last_mtime
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
282
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
283 def __repr__(self):
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
284 s = repr(self.fileobj)
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
285 return '<gzip ' + s[1:-1] + ' ' + hex(id(self)) + '>'
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
286
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
287 def _init_write(self, filename):
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
288 self.name = filename
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
289 self.crc = zlib.crc32(b"")
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
290 self.size = 0
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
291 self.writebuf = []
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
292 self.bufsize = 0
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
293 self.offset = 0 # Current file offset for seek(), tell(), etc
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
294
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
295 def tell(self):
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
296 self._check_not_closed()
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
297 self._buffer.flush()
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
298 return super().tell()
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
299
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
300 def _write_gzip_header(self, compresslevel):
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
301 self.fileobj.write(b'\037\213') # magic header
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
302 self.fileobj.write(b'\010') # compression method
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
303 try:
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
304 # RFC 1952 requires the FNAME field to be Latin-1. Do not
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
305 # include filenames that cannot be represented that way.
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
306 fname = os.path.basename(self.name)
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
307 if not isinstance(fname, bytes):
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
308 fname = fname.encode('latin-1')
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
309 if fname.endswith(b'.gz'):
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
310 fname = fname[:-3]
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
311 except UnicodeEncodeError:
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
312 fname = b''
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
313 flags = 0
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
314 if fname:
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
315 flags = FNAME
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
316 self.fileobj.write(chr(flags).encode('latin-1'))
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
317 mtime = self._write_mtime
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
318 if mtime is None:
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
319 mtime = time.time()
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
320 write32u(self.fileobj, int(mtime))
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
321 if compresslevel == _COMPRESS_LEVEL_BEST:
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
322 xfl = b'\002'
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
323 elif compresslevel == _COMPRESS_LEVEL_FAST:
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
324 xfl = b'\004'
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
325 else:
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
326 xfl = b'\000'
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
327 self.fileobj.write(xfl)
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
328 self.fileobj.write(b'\377')
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
329 if fname:
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
330 self.fileobj.write(fname + b'\000')
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
331
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
332 def write(self,data):
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
333 self._check_not_closed()
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
334 if self.mode != WRITE:
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
335 import errno
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
336 raise OSError(errno.EBADF, "write() on read-only GzipFile object")
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
337
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
338 if self.fileobj is None:
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
339 raise ValueError("write() on closed GzipFile object")
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
340
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
341 return self._buffer.write(data)
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
342
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
343 def _write_raw(self, data):
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
344 # Called by our self._buffer underlying WriteBufferStream.
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
345 if isinstance(data, (bytes, bytearray)):
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
346 length = len(data)
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
347 else:
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
348 # accept any data that supports the buffer protocol
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
349 data = memoryview(data)
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
350 length = data.nbytes
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
351
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
352 if length > 0:
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
353 self.fileobj.write(self.compress.compress(data))
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
354 self.size += length
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
355 self.crc = zlib.crc32(data, self.crc)
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
356 self.offset += length
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
357
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
358 return length
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
359
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
360 def read(self, size=-1):
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
361 self._check_not_closed()
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
362 if self.mode != READ:
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
363 import errno
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
364 raise OSError(errno.EBADF, "read() on write-only GzipFile object")
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
365 return self._buffer.read(size)
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
366
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
367 def read1(self, size=-1):
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
368 """Implements BufferedIOBase.read1()
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
369
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
370 Reads up to a buffer's worth of data if size is negative."""
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
371 self._check_not_closed()
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
372 if self.mode != READ:
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
373 import errno
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
374 raise OSError(errno.EBADF, "read1() on write-only GzipFile object")
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
375
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
376 if size < 0:
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
377 size = io.DEFAULT_BUFFER_SIZE
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
378 return self._buffer.read1(size)
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
379
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
380 def peek(self, n):
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
381 self._check_not_closed()
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
382 if self.mode != READ:
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
383 import errno
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
384 raise OSError(errno.EBADF, "peek() on write-only GzipFile object")
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
385 return self._buffer.peek(n)
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
386
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
387 @property
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
388 def closed(self):
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
389 return self.fileobj is None
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
390
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
391 def close(self):
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
392 fileobj = self.fileobj
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
393 if fileobj is None or self._buffer.closed:
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
394 return
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
395 try:
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
396 if self.mode == WRITE:
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
397 self._buffer.flush()
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
398 fileobj.write(self.compress.flush())
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
399 write32u(fileobj, self.crc)
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
400 # self.size may exceed 2 GiB, or even 4 GiB
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
401 write32u(fileobj, self.size & 0xffffffff)
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
402 elif self.mode == READ:
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
403 self._buffer.close()
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
404 finally:
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
405 self._close()
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
406
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
407 def _close(self):
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
408 self.fileobj = None
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
409 myfileobj = self.myfileobj
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
410 if myfileobj is not None:
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
411 self.myfileobj = None
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
412 myfileobj.close()
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
413
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
414 def flush(self,zlib_mode=zlib.Z_SYNC_FLUSH):
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
415 self._check_not_closed()
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
416 if self.mode == WRITE:
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
417 self._buffer.flush()
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
418 # Ensure the compressor's buffer is flushed
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
419 self.fileobj.write(self.compress.flush(zlib_mode))
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
420 self.fileobj.flush()
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
421
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
422 def fileno(self):
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
423 """Invoke the underlying file object's fileno() method.
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
424
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
425 This will raise AttributeError if the underlying file object
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
426 doesn't support fileno().
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
427 """
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
428 return self.fileobj.fileno()
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
429
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
430 def rewind(self):
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
431 '''Return the uncompressed stream file position indicator to the
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
432 beginning of the file'''
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
433 if self.mode != READ:
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
434 raise OSError("Can't rewind in write mode")
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
435 self._buffer.seek(0)
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
436
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
437 def readable(self):
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
438 return self.mode == READ
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
439
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
440 def writable(self):
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
441 return self.mode == WRITE
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
442
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
443 def seekable(self):
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
444 return True
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
445
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
446 def seek(self, offset, whence=io.SEEK_SET):
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
447 if self.mode == WRITE:
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
448 self._check_not_closed()
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
449 # Flush buffer to ensure validity of self.offset
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
450 self._buffer.flush()
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
451 if whence != io.SEEK_SET:
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
452 if whence == io.SEEK_CUR:
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
453 offset = self.offset + offset
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
454 else:
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
455 raise ValueError('Seek from end not supported')
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
456 if offset < self.offset:
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
457 raise OSError('Negative seek in write mode')
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
458 count = offset - self.offset
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
459 chunk = b'\0' * self._buffer_size
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
460 for i in range(count // self._buffer_size):
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
461 self.write(chunk)
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
462 self.write(b'\0' * (count % self._buffer_size))
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
463 elif self.mode == READ:
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
464 self._check_not_closed()
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
465 return self._buffer.seek(offset, whence)
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
466
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
467 return self.offset
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
468
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
469 def readline(self, size=-1):
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
470 self._check_not_closed()
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
471 return self._buffer.readline(size)
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
472
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
473
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
474 def _read_exact(fp, n):
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
475 '''Read exactly *n* bytes from `fp`
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
476
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
477 This method is required because fp may be unbuffered,
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
478 i.e. return short reads.
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
479 '''
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
480 data = fp.read(n)
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
481 while len(data) < n:
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
482 b = fp.read(n - len(data))
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
483 if not b:
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
484 raise EOFError("Compressed file ended before the "
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
485 "end-of-stream marker was reached")
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
486 data += b
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
487 return data
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
488
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
489
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
490 def _read_gzip_header(fp):
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
491 '''Read a gzip header from `fp` and progress to the end of the header.
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
492
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
493 Returns last mtime if header was present or None otherwise.
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
494 '''
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
495 magic = fp.read(2)
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
496 if magic == b'':
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
497 return None
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
498
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
499 if magic != b'\037\213':
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
500 raise BadGzipFile('Not a gzipped file (%r)' % magic)
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
501
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
502 (method, flag, last_mtime) = struct.unpack("<BBIxx", _read_exact(fp, 8))
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
503 if method != 8:
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
504 raise BadGzipFile('Unknown compression method')
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
505
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
506 if flag & FEXTRA:
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
507 # Read & discard the extra field, if present
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
508 extra_len, = struct.unpack("<H", _read_exact(fp, 2))
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
509 _read_exact(fp, extra_len)
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
510 if flag & FNAME:
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
511 # Read and discard a null-terminated string containing the filename
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
512 while True:
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
513 s = fp.read(1)
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
514 if not s or s==b'\000':
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
515 break
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
516 if flag & FCOMMENT:
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
517 # Read and discard a null-terminated string containing a comment
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
518 while True:
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
519 s = fp.read(1)
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
520 if not s or s==b'\000':
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
521 break
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
522 if flag & FHCRC:
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
523 _read_exact(fp, 2) # Read & discard the 16-bit header CRC
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
524 return last_mtime
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
525
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
526
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
527 class _GzipReader(_compression.DecompressReader):
353
6b1137bdbd0d give access to block offsets via callback
Henry S. Thompson <ht@inf.ed.ac.uk>
parents: 350
diff changeset
528 def __init__(self, fp, eob_callback):
350
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
529 super().__init__(_PaddedFile(fp), zlib._ZlibDecompressor,
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
530 wbits=-zlib.MAX_WBITS)
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
531 # Set flag indicating start of a new member
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
532 self._new_member = True
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
533 self._last_mtime = None
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
534 self._cur_block = None
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
535 self._next_block = 0
353
6b1137bdbd0d give access to block offsets via callback
Henry S. Thompson <ht@inf.ed.ac.uk>
parents: 350
diff changeset
536 self._eob_callback = eob_callback
350
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
537
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
538 def _init_read(self):
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
539 self._crc = zlib.crc32(b"")
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
540 self._stream_size = 0 # Decompressed size of unconcatenated stream
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
541
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
542 def _read_gzip_header(self):
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
543 last_mtime = _read_gzip_header(self._fp)
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
544 if last_mtime is None:
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
545 return False
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
546 self._last_mtime = last_mtime
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
547 return True
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
548
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
549 def read(self, size=-1):
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
550 if size < 0:
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
551 return self.readall()
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
552 # size=0 is special because decompress(max_length=0) is not supported
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
553 if not size:
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
554 return b""
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
555
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
556 # For certain input data, a single
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
557 # call to decompress() may not return
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
558 # any data. In this case, retry until we get some data or reach EOF.
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
559 while True:
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
560 if self._decompressor.eof:
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
561 # Ending case: we've come to the end of a member in the file,
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
562 # so finish up this member, and read a new gzip header.
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
563 # Check the CRC and file size, and set the flag so we read
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
564 # a new member
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
565 self._read_eof()
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
566 self._new_member = True
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
567 self._decompressor = self._decomp_factory(
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
568 **self._decomp_args)
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
569
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
570 if self._new_member:
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
571 # If the _new_member flag is set, we have to
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
572 # jump to the next member, if there is one.
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
573 self._init_read()
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
574 if not self._read_gzip_header():
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
575 return b""
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
576 self._new_member = False
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
577
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
578 # Read a chunk of data from the file
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
579 if self._decompressor.needs_input:
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
580 buf = self._fp.read(READ_BUFFER_SIZE)
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
581 uncompress = self._decompressor.decompress(buf, size)
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
582 else:
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
583 uncompress = self._decompressor.decompress(b"", size)
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
584
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
585 if self._decompressor.unused_data != b"":
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
586 # Prepend the already read bytes to the fileobj so they can
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
587 # be seen by _read_eof() and _read_gzip_header()
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
588 self._fp.prepend(self._decompressor.unused_data)
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
589
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
590 if uncompress != b"":
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
591 break
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
592 if buf == b"":
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
593 raise EOFError("Compressed file ended before the "
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
594 "end-of-stream marker was reached")
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
595
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
596 self._crc = zlib.crc32(uncompress, self._crc)
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
597 self._stream_size += len(uncompress)
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
598 return uncompress
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
599
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
600 def _read_eof(self):
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
601 # We've read to the end of the file
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
602 # We check that the computed CRC and size of the
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
603 # uncompressed data matches the stored values. Note that the size
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
604 # stored is the true file size mod 2**32.
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
605 crc32, isize = struct.unpack("<II", _read_exact(self._fp, 8))
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
606 if crc32 != self._crc:
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
607 raise BadGzipFile("CRC check failed %s != %s" % (hex(crc32),
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
608 hex(self._crc)))
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
609 elif isize != (self._stream_size & 0xffffffff):
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
610 raise BadGzipFile("Incorrect length of data produced")
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
611
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
612 # Gzip files can be padded with zeroes and still have archives.
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
613 # Consume all zero bytes and set the file position to the first
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
614 # non-zero byte. See http://www.gzip.org/#faq8
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
615 c = b"\x00"
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
616 while c == b"\x00":
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
617 c = self._fp.read(1)
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
618 # At this point we know how big the compressed data was:
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
619 # 2+8+[x-y]+8+(1 * nzeros), which is available via _fp.tell()
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
620 if c:
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
621 self._fp.prepend(c)
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
622
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
623 self._cur_block = self._next_block
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
624 self._next_block = self._fp.tell()
353
6b1137bdbd0d give access to block offsets via callback
Henry S. Thompson <ht@inf.ed.ac.uk>
parents: 350
diff changeset
625 if self._eob_callback is not None:
6b1137bdbd0d give access to block offsets via callback
Henry S. Thompson <ht@inf.ed.ac.uk>
parents: 350
diff changeset
626 self._eob_callback(self._cur_block, self._next_block)
350
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
627
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
628 def _rewind(self):
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
629 super()._rewind()
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
630 self._new_member = True
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
631
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
632
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
633 def compress(data, compresslevel=_COMPRESS_LEVEL_BEST, *, mtime=None):
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
634 """Compress data in one shot and return the compressed string.
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
635
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
636 compresslevel sets the compression level in range of 0-9.
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
637 mtime can be used to set the modification time. The modification time is
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
638 set to the current time by default.
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
639 """
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
640 # Wbits=31 automatically includes a gzip header and trailer.
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
641 gzip_data = zlib.compress(data, level=compresslevel, wbits=31)
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
642 if mtime is None:
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
643 mtime = time.time()
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
644 # Reuse gzip header created by zlib, replace mtime and OS byte for
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
645 # consistency.
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
646 header = struct.pack("<4sLBB", gzip_data, int(mtime), gzip_data[8], 255)
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
647 return header + gzip_data[10:]
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
648
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
649
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
650 def decompress(data):
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
651 """Decompress a gzip compressed string in one shot.
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
652 Return the decompressed string.
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
653 """
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
654 decompressed_members = []
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
655 while True:
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
656 fp = io.BytesIO(data)
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
657 if _read_gzip_header(fp) is None:
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
658 return b"".join(decompressed_members)
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
659 # Use a zlib raw deflate compressor
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
660 do = zlib.decompressobj(wbits=-zlib.MAX_WBITS)
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
661 # Read all the data except the header
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
662 decompressed = do.decompress(data[fp.tell():])
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
663 if not do.eof or len(do.unused_data) < 8:
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
664 raise EOFError("Compressed file ended before the end-of-stream "
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
665 "marker was reached")
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
666 crc, length = struct.unpack("<II", do.unused_data[:8])
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
667 if crc != zlib.crc32(decompressed):
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
668 raise BadGzipFile("CRC check failed")
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
669 if length != (len(decompressed) & 0xffffffff):
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
670 raise BadGzipFile("Incorrect length of data produced")
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
671 decompressed_members.append(decompressed)
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
672 data = do.unused_data[8:].lstrip(b"\x00")
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
673
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
674 def main():
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
675 from argparse import ArgumentParser
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
676 parser = ArgumentParser(description=
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
677 "A simple command line interface for the gzip module: act like gzip, "
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
678 "but do not delete the input file.")
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
679 group = parser.add_mutually_exclusive_group()
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
680 group.add_argument('--fast', action='store_true', help='compress faster')
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
681 group.add_argument('--best', action='store_true', help='compress better')
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
682 group.add_argument("-d", "--decompress", action="store_true",
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
683 help="act like gunzip instead of gzip")
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
684
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
685 parser.add_argument("args", nargs="*", default=["-"], metavar='file')
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
686 args = parser.parse_args()
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
687
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
688 compresslevel = _COMPRESS_LEVEL_TRADEOFF
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
689 if args.fast:
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
690 compresslevel = _COMPRESS_LEVEL_FAST
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
691 elif args.best:
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
692 compresslevel = _COMPRESS_LEVEL_BEST
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
693
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
694 for arg in args.args:
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
695 if args.decompress:
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
696 if arg == "-":
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
697 f = GzipFile(filename="", mode="rb", fileobj=sys.stdin.buffer)
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
698 g = sys.stdout.buffer
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
699 else:
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
700 if arg[-3:] != ".gz":
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
701 sys.exit(f"filename doesn't end in .gz: {arg!r}")
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
702 f = open(arg, "rb")
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
703 g = builtins.open(arg[:-3], "wb")
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
704 else:
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
705 if arg == "-":
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
706 f = sys.stdin.buffer
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
707 g = GzipFile(filename="", mode="wb", fileobj=sys.stdout.buffer,
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
708 compresslevel=compresslevel)
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
709 else:
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
710 f = builtins.open(arg, "rb")
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
711 g = open(arg + ".gz", "wb")
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
712 while True:
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
713 chunk = f.read(READ_BUFFER_SIZE)
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
714 if not chunk:
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
715 break
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
716 g.write(chunk)
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
717 if g is not sys.stdout.buffer:
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
718 g.close()
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
719 if f is not sys.stdin.buffer:
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
720 f.close()
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
721
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
722 if __name__ == '__main__':
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
723 main()