~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to effbot/org/gzip_consumer.py

  • Committer: Martin Pool
  • Date: 2005-05-03 07:48:54 UTC
  • Revision ID: mbp@sourcefrog.net-20050503074854-adb6f9d6382e27a9
- sketchy experiments in bash and zsh completion

Show diffs side-by-side

added added

removed removed

Lines of Context:
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()