/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar

« back to all changes in this revision

Viewing changes to dulwich/dulwich/pack.py

Fix branch cloning.

Show diffs side-by-side

added added

removed removed

Lines of Context:
45
45
 
46
46
from objects import (
47
47
        ShaFile,
48
 
        hex_to_sha,
49
 
        sha_to_hex,
50
48
        )
51
49
from errors import ApplyDeltaError
52
50
 
83
81
    return sha.hexdigest()
84
82
 
85
83
 
 
84
def hex_to_sha(hex):
 
85
  """Convert a hex string to a binary sha string."""
 
86
  ret = ""
 
87
  for i in range(0, len(hex), 2):
 
88
    ret += chr(int(hex[i:i+2], 16))
 
89
  return ret
 
90
 
 
91
 
 
92
def sha_to_hex(sha):
 
93
  """Convert a binary sha string to a hex sha string."""
 
94
  ret = ""
 
95
  for i in sha:
 
96
      ret += "%02x" % ord(i)
 
97
  return ret
 
98
 
 
99
 
86
100
MAX_MMAP_SIZE = 256 * 1024 * 1024
87
101
 
88
102
def simple_mmap(f, offset, size, access=mmap.ACCESS_READ):
311
325
      return None
312
326
 
313
327
 
314
 
def read_pack_header(f):
315
 
    header = f.read(12)
316
 
    assert header[:4] == "PACK"
317
 
    (version,) = struct.unpack_from(">L", header, 4)
318
 
    assert version in (2, 3), "Version was %d" % version
319
 
    (num_objects,) = struct.unpack_from(">L", header, 8)
320
 
    return (version, num_objects)
321
 
 
322
 
 
323
 
def read_pack_tail(f):
324
 
    return (f.read(20),)
325
 
 
326
 
 
327
 
def unpack_object(map):
328
 
    bytes = take_msb_bytes(map, 0)
329
 
    type = (bytes[0] >> 4) & 0x07
330
 
    size = bytes[0] & 0x0f
331
 
    for i, byte in enumerate(bytes[1:]):
332
 
      size += (byte & 0x7f) << ((i * 7) + 4)
333
 
    raw_base = len(bytes)
334
 
    if type == 6: # offset delta
335
 
        bytes = take_msb_bytes(map, raw_base)
336
 
        assert not (bytes[-1] & 0x80)
337
 
        delta_base_offset = bytes[0] & 0x7f
338
 
        for byte in bytes[1:]:
339
 
            delta_base_offset += 1
340
 
            delta_base_offset <<= 7
341
 
            delta_base_offset += (byte & 0x7f)
342
 
        raw_base+=len(bytes)
343
 
        uncomp, comp_len = read_zlib(map, raw_base, size)
344
 
        assert size == len(uncomp)
345
 
        return type, (delta_base_offset, uncomp), comp_len+raw_base
346
 
    elif type == 7: # ref delta
347
 
        basename = map[raw_base:raw_base+20]
348
 
        uncomp, comp_len = read_zlib(map, raw_base+20, size)
349
 
        assert size == len(uncomp)
350
 
        return type, (basename, uncomp), comp_len+raw_base+20
351
 
    else:
352
 
        uncomp, comp_len = read_zlib(map, raw_base, size)
353
 
        assert len(uncomp) == size
354
 
        return type, uncomp, comp_len+raw_base
355
 
 
356
 
 
357
328
class PackData(object):
358
329
  """The data contained in a packfile.
359
330
 
400
371
  def _read_header(self):
401
372
    f = open(self._filename, 'rb')
402
373
    try:
403
 
        (version, self._num_objects) = \
404
 
                read_pack_header(f)
 
374
        header = f.read(12)
405
375
        f.seek(self._size-20)
406
 
        (self._stored_checksum,) = read_pack_tail(f)
 
376
        self._stored_checksum = f.read(20)
407
377
    finally:
408
378
        f.close()
 
379
    assert header[:4] == "PACK"
 
380
    (version,) = struct.unpack_from(">L", header, 4)
 
381
    assert version in (2, 3), "Version was %d" % version
 
382
    (self._num_objects,) = struct.unpack_from(">L", header, 8)
409
383
 
410
384
  def __len__(self):
411
385
      """Returns the number of objects in this pack."""
424
398
    f = open(self._filename, 'rb')
425
399
    for i in range(len(self)):
426
400
        map = simple_mmap(f, offset, self._size-offset)
427
 
        (type, obj, total_size) = unpack_object(map)
 
401
        (type, obj, total_size) = self._unpack_object(map)
428
402
        yield offset, type, obj
429
403
        offset += total_size
430
404
    f.close()
501
475
    f = open(self._filename, 'rb')
502
476
    try:
503
477
      map = simple_mmap(f, offset, size-offset)
504
 
      return unpack_object(map)[:2]
 
478
      return self._unpack_object(map)[:2]
505
479
    finally:
506
480
      f.close()
507
481
 
 
482
  def _unpack_object(self, map):
 
483
    bytes = take_msb_bytes(map, 0)
 
484
    type = (bytes[0] >> 4) & 0x07
 
485
    size = bytes[0] & 0x0f
 
486
    for i, byte in enumerate(bytes[1:]):
 
487
      size += (byte & 0x7f) << ((i * 7) + 4)
 
488
    raw_base = len(bytes)
 
489
    if type == 6: # offset delta
 
490
        bytes = take_msb_bytes(map, raw_base)
 
491
        assert not (bytes[-1] & 0x80)
 
492
        delta_base_offset = bytes[0] & 0x7f
 
493
        for byte in bytes[1:]:
 
494
            delta_base_offset += 1
 
495
            delta_base_offset <<= 7
 
496
            delta_base_offset += (byte & 0x7f)
 
497
        raw_base+=len(bytes)
 
498
        uncomp, comp_len = read_zlib(map, raw_base, size)
 
499
        assert size == len(uncomp)
 
500
        return type, (delta_base_offset, uncomp), comp_len+raw_base
 
501
    elif type == 7: # ref delta
 
502
        basename = map[raw_base:raw_base+20]
 
503
        uncomp, comp_len = read_zlib(map, raw_base+20, size)
 
504
        assert size == len(uncomp)
 
505
        return type, (basename, uncomp), comp_len+raw_base+20
 
506
    else:
 
507
        uncomp, comp_len = read_zlib(map, raw_base, size)
 
508
        assert len(uncomp) == size
 
509
        return type, uncomp, comp_len+raw_base
 
510
 
508
511
 
509
512
class SHA1Writer(object):
510
513