|
6 | 6 |
|
7 | 7 | # implements a python function that reads and writes a gzipped file |
8 | 8 | # the user of the file doesn't have to worry about the compression, |
9 | | -# but sequential access is not allowed |
| 9 | +# but random access is not allowed |
10 | 10 |
|
11 | 11 | # based on Andrew Kuchling's minigzip.py distributed with the zlib module |
12 | 12 |
|
@@ -52,7 +52,7 @@ def __init__(self, filename=None, mode=None, |
52 | 52 | fileobj = self.myfileobj = __builtin__.open(filename, mode or 'r') |
53 | 53 | if filename is None: |
54 | 54 | if hasattr(fileobj, 'name'): filename = fileobj.name |
55 | | - else: filename = 'GzippedFile' |
| 55 | + else: filename = '' |
56 | 56 | if mode is None: |
57 | 57 | if hasattr(fileobj, 'mode'): mode = fileobj.mode |
58 | 58 | else: mode = 'r' |
@@ -98,11 +98,16 @@ def _init_write(self, filename): |
98 | 98 | def _write_gzip_header(self): |
99 | 99 | self.fileobj.write('\037\213') # magic header |
100 | 100 | self.fileobj.write('\010') # compression method |
101 | | - self.fileobj.write(chr(FNAME)) |
| 101 | + fname = self.filename[:-3] |
| 102 | + flags = 0 |
| 103 | + if fname: |
| 104 | + flags = FNAME |
| 105 | + self.fileobj.write(chr(flags)) |
102 | 106 | write32(self.fileobj, int(time.time())) |
103 | 107 | self.fileobj.write('\002') |
104 | 108 | self.fileobj.write('\377') |
105 | | - self.fileobj.write(self.filename[:-3] + '\000') |
| 109 | + if fname: |
| 110 | + self.fileobj.write(fname + '\000') |
106 | 111 |
|
107 | 112 | def _init_read(self): |
108 | 113 | self.crc = zlib.crc32("") |
@@ -132,12 +137,12 @@ def _read_gzip_header(self): |
132 | 137 | # Read and discard a null-terminated string containing the filename |
133 | 138 | while (1): |
134 | 139 | s=self.fileobj.read(1) |
135 | | - if s=='\000': break |
| 140 | + if not s or s=='\000': break |
136 | 141 | if flag & FCOMMENT: |
137 | 142 | # Read and discard a null-terminated string containing a comment |
138 | 143 | while (1): |
139 | 144 | s=self.fileobj.read(1) |
140 | | - if s=='\000': break |
| 145 | + if not s or s=='\000': break |
141 | 146 | if flag & FHCRC: |
142 | 147 | self.fileobj.read(2) # Read & discard the 16-bit header CRC |
143 | 148 |
|
@@ -251,3 +256,46 @@ def readlines(self): |
251 | 256 | def writelines(self, L): |
252 | 257 | for line in L: |
253 | 258 | self.write(line) |
| 259 | + |
| 260 | + |
| 261 | +def _test(): |
| 262 | + # Act like gzip; with -d, act like gunzip. |
| 263 | + # The input file is not deleted, however, nor are any other gzip |
| 264 | + # options or features supported. |
| 265 | + import sys |
| 266 | + args = sys.argv[1:] |
| 267 | + decompress = args and args[0] == "-d" |
| 268 | + if decompress: |
| 269 | + args = args[1:] |
| 270 | + if not args: |
| 271 | + args = ["-"] |
| 272 | + for arg in args: |
| 273 | + if decompress: |
| 274 | + if arg == "-": |
| 275 | + f = GzipFile(filename="", mode="rb", fileobj=sys.stdin) |
| 276 | + g = sys.stdout |
| 277 | + else: |
| 278 | + if arg[-3:] != ".gz": |
| 279 | + print "filename doesn't end in .gz:", `arg` |
| 280 | + continue |
| 281 | + f = open(arg, "rb") |
| 282 | + g = __builtin__.open(arg[:-3], "wb") |
| 283 | + else: |
| 284 | + if arg == "-": |
| 285 | + f = sys.stdin |
| 286 | + g = GzipFile(filename="", mode="wb", fileobj=sys.stdout) |
| 287 | + else: |
| 288 | + f = __builtin__.open(arg, "rb") |
| 289 | + g = open(arg + ".gz", "wb") |
| 290 | + while 1: |
| 291 | + chunk = f.read(1024) |
| 292 | + if not chunk: |
| 293 | + break |
| 294 | + g.write(chunk) |
| 295 | + if g is not sys.stdout: |
| 296 | + g.close() |
| 297 | + if f is not sys.stdin: |
| 298 | + f.close() |
| 299 | + |
| 300 | +if __name__ == '__main__': |
| 301 | + _test() |
0 commit comments