|
@@ -1061,33 +1061,48 @@ class PackData(object):
|
|
|
|
|
|
:return: Tuple with object type and contents.
|
|
:return: Tuple with object type and contents.
|
|
"""
|
|
"""
|
|
- if type not in DELTA_TYPES:
|
|
+
|
|
- return type, obj
|
|
+
|
|
-
|
|
+ base_offset = offset
|
|
- if get_ref is None:
|
|
+ base_type = type
|
|
- get_ref = self.get_ref
|
|
+ base_obj = obj
|
|
- if type == OFS_DELTA:
|
|
+ delta_stack = []
|
|
- (delta_offset, delta) = obj
|
|
+ while base_type in DELTA_TYPES:
|
|
-
|
|
+ prev_offset = base_offset
|
|
- assert isinstance(offset, int) or isinstance(offset, long)
|
|
+ if get_ref is None:
|
|
- assert isinstance(delta_offset, int) or isinstance(offset, long)
|
|
+ get_ref = self.get_ref
|
|
- base_offset = offset-delta_offset
|
|
+ if base_type == OFS_DELTA:
|
|
- type, base_obj = self.get_object_at(base_offset)
|
|
+ (delta_offset, delta) = base_obj
|
|
- assert isinstance(type, int)
|
|
+
|
|
- elif type == REF_DELTA:
|
|
+ assert (
|
|
- (basename, delta) = obj
|
|
+ isinstance(base_offset, int)
|
|
- assert isinstance(basename, bytes) and len(basename) == 20
|
|
+ or isinstance(base_offset, long))
|
|
- base_offset, type, base_obj = get_ref(basename)
|
|
+ assert (
|
|
- assert isinstance(type, int)
|
|
+ isinstance(delta_offset, int)
|
|
- type, base_chunks = self.resolve_object(base_offset, type, base_obj)
|
|
+ or isinstance(base_offset, long))
|
|
- chunks = apply_delta(base_chunks, delta)
|
|
+ base_offset = base_offset - delta_offset
|
|
-
|
|
+ base_type, base_obj = self.get_object_at(base_offset)
|
|
-
|
|
+ assert isinstance(base_type, int)
|
|
-
|
|
+ elif base_type == REF_DELTA:
|
|
-
|
|
+ (basename, delta) = base_obj
|
|
- if offset is not None:
|
|
+ assert isinstance(basename, bytes) and len(basename) == 20
|
|
- self._offset_cache[offset] = type, chunks
|
|
+ base_offset, base_type, base_obj = get_ref(basename)
|
|
- return type, chunks
|
|
+ assert isinstance(base_type, int)
|
|
|
|
+ delta_stack.append((prev_offset, base_type, delta))
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ chunks = base_obj
|
|
|
|
+ for prev_offset, delta_type, delta in reversed(delta_stack):
|
|
|
|
+ chunks = apply_delta(chunks, delta)
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ if prev_offset is not None:
|
|
|
|
+ self._offset_cache[prev_offset] = base_type, chunks
|
|
|
|
+ return base_type, chunks
|
|
|
|
|
|
def iterobjects(self, progress=None, compute_crc32=True):
|
|
def iterobjects(self, progress=None, compute_crc32=True):
|
|
self._file.seek(self._header_size)
|
|
self._file.seek(self._header_size)
|