300
300
return ''.join(chunks)
302
def _dump(self, include_text=False):
303
"""Take this block, and spit out a human-readable structure.
305
:param include_text: Inserts also include text bits, chose whether you
306
want this displayed in the dump or not.
307
:return: A dump of the given block. The layout is something like:
308
[('f', length), ('d', delta_length, text_length, [delta_info])]
309
delta_info := [('i', num_bytes, text), ('c', offset, num_bytes),
312
self._ensure_content()
315
while pos < self._content_length:
316
kind = self._content[pos]
318
if kind not in ('f', 'd'):
319
raise ValueError('invalid kind character: %r' % (kind,))
320
content_len, len_len = decode_base128_int(
321
self._content[pos:pos + 5])
323
if content_len + pos > self._content_length:
324
raise ValueError('invalid content_len %d for record @ pos %d'
325
% (content_len, pos - len_len - 1))
326
if kind == 'f': # Fulltext
327
result.append(('f', content_len))
328
elif kind == 'd': # Delta
329
delta_content = self._content[pos:pos+content_len]
331
# The first entry in a delta is the decompressed length
332
decomp_len, delta_pos = decode_base128_int(delta_content)
333
result.append(('d', content_len, decomp_len, delta_info))
335
while delta_pos < content_len:
336
c = ord(delta_content[delta_pos])
340
delta_pos) = decode_copy_instruction(delta_content, c,
342
delta_info.append(('c', offset, length))
343
measured_len += length
346
txt = delta_content[delta_pos:delta_pos+c]
349
delta_info.append(('i', c, txt))
352
if delta_pos != content_len:
353
raise ValueError('Delta consumed a bad number of bytes:'
354
' %d != %d' % (delta_pos, content_len))
355
if measured_len != decomp_len:
356
raise ValueError('Delta claimed fulltext was %d bytes, but'
357
' extraction resulted in %d bytes'
358
% (decomp_len, measured_len))
303
363
class _LazyGroupCompressFactory(object):
304
364
"""Yield content from a GroupCompressBlock on demand."""