annotate lib/python/gzip_plus.py @ 351:444ddf704502 trim

switch to plain GzipFile for comparison purposes, lots of syntax tidying
author Henry S. Thompson <ht@inf.ed.ac.uk>
date Thu, 12 Mar 2026 18:20:01 +0000
parents 4ead0a390a29
children 6b1137bdbd0d
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
350
4ead0a390a29 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.
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
2
4ead0a390a29 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,
4ead0a390a29 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."""
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
5
4ead0a390a29 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
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
7
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
8 import _compression
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
9 import builtins
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
10 import io
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
11 import os
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
12 import struct
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
13 import sys
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
14 import time
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
15 import weakref
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
16 import zlib
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
17
4ead0a390a29 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"]
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
19
4ead0a390a29 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
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
21
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
22 READ = 'rb'
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
23 WRITE = 'wb'
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
24
4ead0a390a29 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
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
26 _COMPRESS_LEVEL_TRADEOFF = 6
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
27 _COMPRESS_LEVEL_BEST = 9
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
28
4ead0a390a29 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
4ead0a390a29 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
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
31
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
32
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
33 def open(filename, mode="rb", compresslevel=_COMPRESS_LEVEL_BEST,
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
34 encoding=None, errors=None, newline=None):
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
35 """Open a gzip-compressed file in binary or text mode.
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
36
4ead0a390a29 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
4ead0a390a29 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.
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
39
4ead0a390a29 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
4ead0a390a29 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
4ead0a390a29 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.
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
43
4ead0a390a29 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:
4ead0a390a29 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
4ead0a390a29 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.
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
47
4ead0a390a29 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
4ead0a390a29 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
4ead0a390a29 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).
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
51
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
52 """
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
53 if "t" in mode:
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
54 if "b" in mode:
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
55 raise ValueError("Invalid mode: %r" % (mode,))
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
56 else:
4ead0a390a29 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:
4ead0a390a29 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")
4ead0a390a29 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:
4ead0a390a29 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")
4ead0a390a29 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:
4ead0a390a29 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")
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
63
4ead0a390a29 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", "")
4ead0a390a29 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)):
4ead0a390a29 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)
4ead0a390a29 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"):
4ead0a390a29 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)
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
69 else:
4ead0a390a29 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")
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
71
4ead0a390a29 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:
4ead0a390a29 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)
4ead0a390a29 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)
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
75 else:
4ead0a390a29 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
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
77
4ead0a390a29 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):
4ead0a390a29 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
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
80 # or unsigned.
4ead0a390a29 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))
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
82
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
83 class _PaddedFile:
4ead0a390a29 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
4ead0a390a29 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
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
86 essential functionality."""
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
87
4ead0a390a29 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''):
4ead0a390a29 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))
4ead0a390a29 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
4ead0a390a29 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)
4ead0a390a29 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
4ead0a390a29 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
4ead0a390a29 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
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
95
4ead0a390a29 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):
4ead0a390a29 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:
4ead0a390a29 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()
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
99 else:
4ead0a390a29 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
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
101
4ead0a390a29 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):
4ead0a390a29 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)
4ead0a390a29 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:
4ead0a390a29 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)
4ead0a390a29 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)
4ead0a390a29 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)
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
108 return res
4ead0a390a29 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:
4ead0a390a29 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
4ead0a390a29 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
4ead0a390a29 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
4ead0a390a29 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)
4ead0a390a29 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]
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
115 else:
4ead0a390a29 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
4ead0a390a29 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
4ead0a390a29 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
4ead0a390a29 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
4ead0a390a29 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)
4ead0a390a29 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)
4ead0a390a29 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)
4ead0a390a29 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
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
124
4ead0a390a29 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''):
4ead0a390a29 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))
4ead0a390a29 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)
4ead0a390a29 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:
4ead0a390a29 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
4ead0a390a29 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
4ead0a390a29 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)
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
132 return
4ead0a390a29 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)
4ead0a390a29 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
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
135
4ead0a390a29 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):
4ead0a390a29 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)
4ead0a390a29 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
4ead0a390a29 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
4ead0a390a29 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)
4ead0a390a29 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
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
142
4ead0a390a29 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):
4ead0a390a29 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
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
145
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
146
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
147 class BadGzipFile(OSError):
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
148 """Exception raised in some cases for invalid gzip files."""
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
149
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
150
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
151 class _WriteBufferStream(io.RawIOBase):
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
152 """Minimal object to pass WriteBuffer flushes into GzipFile"""
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
153 def __init__(self, gzip_file):
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
154 self.gzip_file = weakref.ref(gzip_file)
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
155
4ead0a390a29 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):
4ead0a390a29 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()
4ead0a390a29 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:
4ead0a390a29 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")
4ead0a390a29 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)
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
161
4ead0a390a29 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):
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
163 return False
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
164
4ead0a390a29 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):
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
166 return True
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
167
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
168
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
169 class GzipFile(_compression.BaseStream):
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
170 """The GzipFile class simulates most of the methods of a file object with
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
171 the exception of the truncate() method.
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
172
4ead0a390a29 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
4ead0a390a29 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.
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
175
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
176 """
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
177
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
178 # Overridden with internal file object to be closed, if only a filename
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
179 # is passed in
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
180 myfileobj = None
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
181
4ead0a390a29 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,
4ead0a390a29 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):
4ead0a390a29 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.
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
185
4ead0a390a29 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
4ead0a390a29 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.
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
188
4ead0a390a29 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
4ead0a390a29 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.
4ead0a390a29 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
4ead0a390a29 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.
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
193
4ead0a390a29 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
4ead0a390a29 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
4ead0a390a29 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
4ead0a390a29 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,
4ead0a390a29 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.
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
199
4ead0a390a29 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
4ead0a390a29 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
4ead0a390a29 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'.
4ead0a390a29 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
4ead0a390a29 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'.
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
205
4ead0a390a29 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
4ead0a390a29 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,
4ead0a390a29 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
4ead0a390a29 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.
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
210
4ead0a390a29 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
4ead0a390a29 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.
4ead0a390a29 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
4ead0a390a29 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.
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
215
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
216 """
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
217
4ead0a390a29 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):
4ead0a390a29 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))
4ead0a390a29 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:
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
221 mode += 'b'
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
222
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
223 try:
4ead0a390a29 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:
4ead0a390a29 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')
4ead0a390a29 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:
4ead0a390a29 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', '')
4ead0a390a29 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)):
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
229 filename = ''
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
230 else:
4ead0a390a29 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)
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
232 origmode = mode
4ead0a390a29 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:
4ead0a390a29 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')
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
235
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
236
4ead0a390a29 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'):
4ead0a390a29 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
4ead0a390a29 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)
4ead0a390a29 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)
4ead0a390a29 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
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
242
4ead0a390a29 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')):
4ead0a390a29 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:
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
245 import warnings
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
246 warnings.warn(
4ead0a390a29 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 "
4ead0a390a29 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. "
4ead0a390a29 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.",
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
250 FutureWarning, 2)
4ead0a390a29 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
4ead0a390a29 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)
4ead0a390a29 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,
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
254 zlib.DEFLATED,
4ead0a390a29 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,
4ead0a390a29 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,
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
257 0)
4ead0a390a29 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
4ead0a390a29 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
4ead0a390a29 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),
4ead0a390a29 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)
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
262 else:
4ead0a390a29 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))
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
264
4ead0a390a29 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
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
266
4ead0a390a29 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:
4ead0a390a29 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)
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
269 except:
4ead0a390a29 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,
4ead0a390a29 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
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
272 self._close()
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
273 raise
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
274
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
275 @property
4ead0a390a29 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):
4ead0a390a29 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"""
4ead0a390a29 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
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
279
4ead0a390a29 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):
4ead0a390a29 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)
4ead0a390a29 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)) + '>'
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
283
4ead0a390a29 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):
4ead0a390a29 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
4ead0a390a29 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"")
4ead0a390a29 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
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
288 self.writebuf = []
4ead0a390a29 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
4ead0a390a29 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
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
291
4ead0a390a29 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):
4ead0a390a29 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()
4ead0a390a29 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()
4ead0a390a29 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()
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
296
4ead0a390a29 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):
4ead0a390a29 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
4ead0a390a29 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
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
300 try:
4ead0a390a29 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
4ead0a390a29 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.
4ead0a390a29 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)
4ead0a390a29 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):
4ead0a390a29 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')
4ead0a390a29 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'):
4ead0a390a29 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]
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
308 except UnicodeEncodeError:
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
309 fname = b''
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
310 flags = 0
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
311 if fname:
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
312 flags = FNAME
4ead0a390a29 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'))
4ead0a390a29 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
4ead0a390a29 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:
4ead0a390a29 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()
4ead0a390a29 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))
4ead0a390a29 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:
4ead0a390a29 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'
4ead0a390a29 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:
4ead0a390a29 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'
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
322 else:
4ead0a390a29 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'
4ead0a390a29 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)
4ead0a390a29 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')
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
326 if fname:
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
327 self.fileobj.write(fname + b'\000')
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
328
4ead0a390a29 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):
4ead0a390a29 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()
4ead0a390a29 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:
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
332 import errno
4ead0a390a29 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")
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
334
4ead0a390a29 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:
4ead0a390a29 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")
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
337
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
338 return self._buffer.write(data)
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
339
4ead0a390a29 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):
4ead0a390a29 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.
4ead0a390a29 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)):
4ead0a390a29 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)
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
344 else:
4ead0a390a29 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
4ead0a390a29 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)
4ead0a390a29 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
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
348
4ead0a390a29 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:
4ead0a390a29 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))
4ead0a390a29 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
4ead0a390a29 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)
4ead0a390a29 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
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
354
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
355 return length
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
356
4ead0a390a29 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):
4ead0a390a29 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()
4ead0a390a29 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:
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
360 import errno
4ead0a390a29 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")
4ead0a390a29 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)
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
363
4ead0a390a29 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):
4ead0a390a29 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()
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
366
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
367 Reads up to a buffer's worth of data if size is negative."""
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
368 self._check_not_closed()
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
369 if self.mode != READ:
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
370 import errno
4ead0a390a29 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")
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
372
4ead0a390a29 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:
4ead0a390a29 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
4ead0a390a29 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)
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
376
4ead0a390a29 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):
4ead0a390a29 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()
4ead0a390a29 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:
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
380 import errno
4ead0a390a29 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")
4ead0a390a29 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)
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
383
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
384 @property
4ead0a390a29 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):
4ead0a390a29 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
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
387
4ead0a390a29 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):
4ead0a390a29 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
4ead0a390a29 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:
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
391 return
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
392 try:
4ead0a390a29 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:
4ead0a390a29 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()
4ead0a390a29 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())
4ead0a390a29 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)
4ead0a390a29 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
4ead0a390a29 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)
4ead0a390a29 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:
4ead0a390a29 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()
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
401 finally:
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
402 self._close()
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
403
4ead0a390a29 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):
4ead0a390a29 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
4ead0a390a29 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
4ead0a390a29 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:
4ead0a390a29 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
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
409 myfileobj.close()
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
410
4ead0a390a29 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):
4ead0a390a29 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()
4ead0a390a29 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:
4ead0a390a29 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()
4ead0a390a29 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
4ead0a390a29 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))
4ead0a390a29 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()
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
418
4ead0a390a29 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):
4ead0a390a29 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.
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
421
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
422 This will raise AttributeError if the underlying file object
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
423 doesn't support fileno().
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
424 """
4ead0a390a29 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()
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
426
4ead0a390a29 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):
4ead0a390a29 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
4ead0a390a29 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'''
4ead0a390a29 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:
4ead0a390a29 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")
4ead0a390a29 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)
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
433
4ead0a390a29 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):
4ead0a390a29 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
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
436
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
437 def writable(self):
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
438 return self.mode == WRITE
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
439
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
440 def seekable(self):
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
441 return True
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
442
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
443 def seek(self, offset, whence=io.SEEK_SET):
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
444 if self.mode == WRITE:
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
445 self._check_not_closed()
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
446 # Flush buffer to ensure validity of self.offset
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
447 self._buffer.flush()
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
448 if whence != io.SEEK_SET:
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
449 if whence == io.SEEK_CUR:
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
450 offset = self.offset + offset
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
451 else:
4ead0a390a29 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')
4ead0a390a29 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:
4ead0a390a29 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')
4ead0a390a29 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
4ead0a390a29 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
4ead0a390a29 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):
4ead0a390a29 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)
4ead0a390a29 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))
4ead0a390a29 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:
4ead0a390a29 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()
4ead0a390a29 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)
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
463
4ead0a390a29 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
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
465
4ead0a390a29 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):
4ead0a390a29 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()
4ead0a390a29 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)
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
469
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
470
4ead0a390a29 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):
4ead0a390a29 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`
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
473
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
474 This method is required because fp may be unbuffered,
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
475 i.e. return short reads.
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
476 '''
4ead0a390a29 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)
4ead0a390a29 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:
4ead0a390a29 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))
4ead0a390a29 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:
4ead0a390a29 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 "
4ead0a390a29 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")
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
483 data += b
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
484 return data
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
485
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
486
4ead0a390a29 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):
4ead0a390a29 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.
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
489
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
490 Returns last mtime if header was present or None otherwise.
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
491 '''
4ead0a390a29 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)
4ead0a390a29 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'':
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
494 return None
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
495
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
496 if magic != b'\037\213':
4ead0a390a29 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)
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
498
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
499 (method, flag, last_mtime) = struct.unpack("<BBIxx", _read_exact(fp, 8))
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
500 if method != 8:
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
501 raise BadGzipFile('Unknown compression method')
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
502
4ead0a390a29 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:
4ead0a390a29 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
4ead0a390a29 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))
4ead0a390a29 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)
4ead0a390a29 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:
4ead0a390a29 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
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
509 while True:
4ead0a390a29 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)
4ead0a390a29 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':
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
512 break
4ead0a390a29 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:
4ead0a390a29 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
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
515 while True:
4ead0a390a29 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)
4ead0a390a29 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':
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
518 break
4ead0a390a29 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:
4ead0a390a29 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
4ead0a390a29 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
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
522
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
523
4ead0a390a29 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):
4ead0a390a29 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):
4ead0a390a29 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,
4ead0a390a29 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)
4ead0a390a29 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
4ead0a390a29 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
4ead0a390a29 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
4ead0a390a29 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
4ead0a390a29 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
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
533
4ead0a390a29 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):
4ead0a390a29 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"")
4ead0a390a29 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
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
537
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
538 def _read_gzip_header(self):
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
539 last_mtime = _read_gzip_header(self._fp)
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
540 if last_mtime is None:
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
541 return False
4ead0a390a29 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
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
543 return True
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
544
4ead0a390a29 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):
4ead0a390a29 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:
4ead0a390a29 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()
4ead0a390a29 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
4ead0a390a29 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:
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
550 return b""
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
551
4ead0a390a29 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
4ead0a390a29 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
4ead0a390a29 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.
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
555 while True:
4ead0a390a29 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:
4ead0a390a29 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,
4ead0a390a29 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.
4ead0a390a29 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
4ead0a390a29 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
4ead0a390a29 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()
4ead0a390a29 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
4ead0a390a29 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(
4ead0a390a29 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)
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
565
4ead0a390a29 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:
4ead0a390a29 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
4ead0a390a29 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.
4ead0a390a29 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()
4ead0a390a29 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():
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
571 return b""
4ead0a390a29 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
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
573
4ead0a390a29 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
4ead0a390a29 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:
4ead0a390a29 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)
4ead0a390a29 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)
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
578 else:
4ead0a390a29 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)
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
580
4ead0a390a29 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"":
4ead0a390a29 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
4ead0a390a29 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()
4ead0a390a29 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)
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
585
4ead0a390a29 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"":
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
587 break
4ead0a390a29 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"":
4ead0a390a29 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 "
4ead0a390a29 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")
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
591
4ead0a390a29 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)
4ead0a390a29 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)
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
594 return uncompress
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
595
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
596 def _read_eof(self):
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
597 # We've read to the end of the file
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
598 # We check that the computed CRC and size of the
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
599 # uncompressed data matches the stored values. Note that the size
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
600 # stored is the true file size mod 2**32.
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
601 crc32, isize = struct.unpack("<II", _read_exact(self._fp, 8))
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
602 if crc32 != self._crc:
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
603 raise BadGzipFile("CRC check failed %s != %s" % (hex(crc32),
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
604 hex(self._crc)))
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
605 elif isize != (self._stream_size & 0xffffffff):
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
606 raise BadGzipFile("Incorrect length of data produced")
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
607
4ead0a390a29 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.
4ead0a390a29 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
4ead0a390a29 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
4ead0a390a29 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"
4ead0a390a29 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":
4ead0a390a29 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)
4ead0a390a29 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:
4ead0a390a29 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()
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
616 if c:
4ead0a390a29 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)
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
618
4ead0a390a29 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
4ead0a390a29 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()
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
621
4ead0a390a29 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):
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
623 super()._rewind()
4ead0a390a29 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
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
625
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
626
4ead0a390a29 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):
4ead0a390a29 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.
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
629
4ead0a390a29 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.
4ead0a390a29 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
4ead0a390a29 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.
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
633 """
4ead0a390a29 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.
4ead0a390a29 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)
4ead0a390a29 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:
4ead0a390a29 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()
4ead0a390a29 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
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
639 # consistency.
4ead0a390a29 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)
4ead0a390a29 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:]
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
642
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
643
4ead0a390a29 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):
4ead0a390a29 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.
4ead0a390a29 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.
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
647 """
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
648 decompressed_members = []
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
649 while True:
4ead0a390a29 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)
4ead0a390a29 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:
4ead0a390a29 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)
4ead0a390a29 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
4ead0a390a29 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)
4ead0a390a29 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
4ead0a390a29 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():])
4ead0a390a29 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:
4ead0a390a29 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 "
4ead0a390a29 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")
4ead0a390a29 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])
4ead0a390a29 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):
4ead0a390a29 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")
4ead0a390a29 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):
4ead0a390a29 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")
4ead0a390a29 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)
4ead0a390a29 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")
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
667
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
668 def main():
4ead0a390a29 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
4ead0a390a29 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=
4ead0a390a29 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, "
4ead0a390a29 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.")
4ead0a390a29 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()
4ead0a390a29 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')
4ead0a390a29 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')
4ead0a390a29 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",
4ead0a390a29 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")
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
678
4ead0a390a29 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')
4ead0a390a29 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()
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
681
4ead0a390a29 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
4ead0a390a29 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:
4ead0a390a29 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
4ead0a390a29 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:
4ead0a390a29 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
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
687
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
688 for arg in args.args:
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
689 if args.decompress:
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
690 if arg == "-":
4ead0a390a29 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)
4ead0a390a29 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
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
693 else:
4ead0a390a29 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":
4ead0a390a29 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}")
4ead0a390a29 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")
4ead0a390a29 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")
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
698 else:
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
699 if arg == "-":
4ead0a390a29 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
4ead0a390a29 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,
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
702 compresslevel=compresslevel)
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
703 else:
4ead0a390a29 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")
4ead0a390a29 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")
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
706 while True:
4ead0a390a29 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)
4ead0a390a29 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:
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
709 break
4ead0a390a29 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)
4ead0a390a29 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:
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
712 g.close()
4ead0a390a29 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:
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
714 f.close()
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
715
4ead0a390a29 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__':
4ead0a390a29 from python3.13 with block boundary tracking added by HST
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
diff changeset
717 main()