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