~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to groupcompress.py

Use the bit field to allow both lzma groups and zlib groups.
This lets 'bzr pack' decide which format to use.
Helpful for testing.

Show diffs side-by-side

added added

removed removed

Lines of Context:
21
21
from cStringIO import StringIO
22
22
import struct
23
23
import zlib
 
24
try:
 
25
    import pylzma
 
26
except ImportError:
 
27
    pylzma = None
24
28
 
25
29
from bzrlib import (
26
30
    annotate,
53
57
    )
54
58
from bzrlib.plugins.groupcompress import errors as gc_errors
55
59
 
 
60
_USE_LZMA = False and (pylzma is not None)
56
61
_NO_LABELS = False
57
62
_FAST = False
58
63
 
139
144
 
140
145
    # Group Compress Block v1 Zlib
141
146
    GCB_HEADER = 'gcb1z\n'
 
147
    GCB_LZ_HEADER = 'gcb1l\n'
142
148
 
143
149
    def __init__(self):
144
150
        # map by key? or just order in file?
155
161
    @classmethod
156
162
    def from_bytes(cls, bytes):
157
163
        out = cls()
158
 
        if bytes[:6] != cls.GCB_HEADER:
 
164
        if bytes[:6] not in (cls.GCB_HEADER, cls.GCB_LZ_HEADER):
159
165
            raise gc_errors.InvalidGroupCompressBlock(
160
166
                'bytes did not start with %r' % (cls.GCB_HEADER,))
 
167
        if bytes[4] == 'z':
 
168
            decomp = zlib.decompress
 
169
        else:
 
170
            decomp = pylzma.decompress
161
171
        pos = bytes.index('\n', 6)
162
172
        z_header_length = int(bytes[6:pos])
163
173
        pos += 1
167
177
            assert header_length == 0
168
178
            zcontent = bytes[pos2+1:]
169
179
            if zcontent:
170
 
                out._content = zlib.decompress(zcontent)
 
180
                out._content = decomp(zcontent)
171
181
                out._size = len(out._content)
172
182
            return out
173
183
        pos = pos2 + 1
174
184
        pos2 = pos + z_header_length
175
185
        z_header_bytes = bytes[pos:pos2]
176
186
        assert len(z_header_bytes) == z_header_length
177
 
        d = zlib.decompressobj()
178
 
        header_bytes = d.decompress(z_header_bytes)
 
187
        header_bytes = decomp(z_header_bytes)
179
188
        assert len(header_bytes) == header_length
180
189
        del z_header_bytes
181
190
        lines = header_bytes.split('\n')
199
208
            info_dict[key] = value
200
209
        zcontent = bytes[pos2:]
201
210
        if zcontent:
202
 
            out._content = d.decompress(zcontent)
203
 
            assert d.flush() == ''
 
211
            out._content = decomp(zcontent)
204
212
            out._size = header_len + len(out._content)
205
213
        return out
206
214
 
234
242
                assert c == 'd'
235
243
            start = entry.start
236
244
        content_len, len_len = decode_base128_int(
237
 
                                self._content[start + 1:start + 11])
 
245
                            self._content[entry.start + 1:entry.start + 11])
238
246
        assert entry.length == content_len + 1 + len_len
239
 
        content_start = start + 1 + len_len
 
247
        content_start = entry.start + 1 + len_len
240
248
        end = entry.start + entry.length
241
249
        content = self._content[content_start:end]
242
250
        if c == 'f':
264
272
 
265
273
    def to_bytes(self, content=''):
266
274
        """Encode the information into a byte stream."""
 
275
        compress = zlib.compress
 
276
        if _USE_LZMA:
 
277
            compress = pylzma.compress
267
278
        chunks = []
268
279
        for key in sorted(self._entries):
269
280
            entry = self._entries[key]
282
293
            chunks.append(chunk)
283
294
        bytes = ''.join(chunks)
284
295
        info_len = len(bytes)
285
 
        c = zlib.compressobj()
286
296
        z_bytes = []
287
 
        z_bytes.append(c.compress(bytes))
 
297
        z_bytes.append(compress(bytes))
288
298
        del bytes
289
299
        # TODO: we may want to have the header compressed in the same chain
290
300
        #       as the data, or we may not, evaulate it
293
303
        #       label in the header is duplicated in the text.
294
304
        #       For chk pages and real bytes, I would guess this is not
295
305
        #       true.
296
 
        z_bytes.append(c.flush(zlib.Z_SYNC_FLUSH))
297
306
        z_len = sum(map(len, z_bytes))
298
307
        c_len = len(content)
299
308
        if _NO_LABELS:
300
309
            z_bytes = []
301
310
            z_len = 0
302
311
            info_len = 0
303
 
            c = zlib.compressobj()
304
 
        z_bytes.append(c.compress(content))
305
 
        z_bytes.append(c.flush())
306
 
        chunks = [self.GCB_HEADER,
 
312
        z_bytes.append(compress(content))
 
313
        chunks = [self.GCB_LZ_HEADER,
307
314
                  '%d\n' % (z_len,),
308
315
                  '%d\n' % (info_len,),
309
316
                  #'%d\n' % (c_len,),