1185.1.29
by Robert Collins
merge merge tweaks from aaron, which includes latest .dev |
1 |
# $Id: gzip_consumer.py 271 2004-10-09 10:50:59Z fredrik $
|
2 |
# gzip consumer
|
|
3 |
#
|
|
4 |
# Copyright (c) 2001-2004 by Fredrik Lundh. All rights reserved.
|
|
5 |
#
|
|
6 |
||
7 |
##
|
|
8 |
# Consumer wrapper for GZIP streams.
|
|
9 |
||
10 |
class GzipConsumer: |
|
11 |
||
12 |
def __init__(self, consumer): |
|
13 |
self.__consumer = consumer |
|
14 |
self.__decoder = None |
|
15 |
self.__data = "" |
|
16 |
||
17 |
def __getattr__(self, key): |
|
18 |
return getattr(self.__consumer, key) |
|
19 |
||
20 |
def feed(self, data): |
|
21 |
if self.__decoder is None: |
|
22 |
# check if we have a full gzip header
|
|
23 |
data = self.__data + data |
|
24 |
try: |
|
25 |
i = 10 |
|
26 |
flag = ord(data[3]) |
|
27 |
if flag & 4: # extra |
|
28 |
x = ord(data[i]) + 256*ord(data[i+1]) |
|
29 |
i = i + 2 + x |
|
30 |
if flag & 8: # filename |
|
31 |
while ord(data[i]): |
|
32 |
i = i + 1 |
|
33 |
i = i + 1 |
|
34 |
if flag & 16: # comment |
|
35 |
while ord(data[i]): |
|
36 |
i = i + 1 |
|
37 |
i = i + 1 |
|
38 |
if flag & 2: # crc |
|
39 |
i = i + 2 |
|
40 |
if len(data) < i: |
|
41 |
raise IndexError("not enough data") |
|
42 |
if data[:3] != "\x1f\x8b\x08": |
|
43 |
raise IOError("invalid gzip data") |
|
44 |
data = data[i:] |
|
45 |
except IndexError: |
|
46 |
self.__data = data |
|
47 |
return # need more data |
|
48 |
import zlib |
|
49 |
self.__data = "" |
|
50 |
self.__decoder = zlib.decompressobj(-zlib.MAX_WBITS) |
|
51 |
data = self.__decoder.decompress(data) |
|
52 |
if data: |
|
53 |
self.__consumer.feed(data) |
|
54 |
||
55 |
def close(self): |
|
56 |
if self.__decoder: |
|
57 |
data = self.__decoder.flush() |
|
58 |
if data: |
|
59 |
self.__consumer.feed(data) |
|
60 |
self.__consumer.close() |