annotate gzip_plus.py @ 77:9619ed725a9c default tip

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