Exemple #1
0
def pack_object_at(data, offset, as_stream):
    """
	:return: Tuple(abs_data_offset, PackInfo|PackStream)
		an object of the correct type according to the type_id  of the object.
		If as_stream is True, the object will contain a stream, allowing  the
		data to be read decompressed.
	:param data: random accessable data containing all required information
	:parma offset: offset in to the data at which the object information is located
	:param as_stream: if True, a stream object will be returned that can read 
		the data, otherwise you receive an info object only"""
    data = buffer(data, offset)
    type_id, uncomp_size, data_rela_offset = pack_object_header_info(data)
    total_rela_offset = None  # set later, actual offset until data stream begins
    delta_info = None

    # OFFSET DELTA
    if type_id == OFS_DELTA:
        i = data_rela_offset
        c = ord(data[i])
        i += 1
        delta_offset = c & 0x7f
        while c & 0x80:
            c = ord(data[i])
            i += 1
            delta_offset += 1
            delta_offset = (delta_offset << 7) + (c & 0x7f)
        # END character loop
        delta_info = delta_offset
        total_rela_offset = i
    # REF DELTA
    elif type_id == REF_DELTA:
        total_rela_offset = data_rela_offset + 20
        ref_sha = data[data_rela_offset:total_rela_offset]
        delta_info = ref_sha
    # BASE OBJECT
    else:
        # assume its a base object
        total_rela_offset = data_rela_offset
    # END handle type id

    abs_data_offset = offset + total_rela_offset
    if as_stream:
        stream = DecompressMemMapReader(buffer(data, total_rela_offset), False,
                                        uncomp_size)
        if delta_info is None:
            return abs_data_offset, OPackStream(offset, type_id, uncomp_size,
                                                stream)
        else:
            return abs_data_offset, ODeltaPackStream(offset, type_id,
                                                     uncomp_size, delta_info,
                                                     stream)
    else:
        if delta_info is None:
            return abs_data_offset, OPackInfo(offset, type_id, uncomp_size)
        else:
            return abs_data_offset, ODeltaPackInfo(offset, type_id,
                                                   uncomp_size, delta_info)
Exemple #2
0
def pack_object_at(data, offset, as_stream):
	"""
	:return: Tuple(abs_data_offset, PackInfo|PackStream)
		an object of the correct type according to the type_id  of the object.
		If as_stream is True, the object will contain a stream, allowing  the
		data to be read decompressed.
	:param data: random accessable data containing all required information
	:parma offset: offset in to the data at which the object information is located
	:param as_stream: if True, a stream object will be returned that can read 
		the data, otherwise you receive an info object only"""
	data = buffer(data, offset)
	type_id, uncomp_size, data_rela_offset = pack_object_header_info(data)
	total_rela_offset = None				# set later, actual offset until data stream begins
	delta_info = None
	
	# OFFSET DELTA
	if type_id == OFS_DELTA:
		i = data_rela_offset
		c = ord(data[i])
		i += 1
		delta_offset = c & 0x7f
		while c & 0x80:
			c = ord(data[i])
			i += 1
			delta_offset += 1
			delta_offset = (delta_offset << 7) + (c & 0x7f)
		# END character loop
		delta_info = delta_offset
		total_rela_offset = i
	# REF DELTA
	elif type_id == REF_DELTA:
		total_rela_offset = data_rela_offset+20
		ref_sha = data[data_rela_offset:total_rela_offset]
		delta_info = ref_sha
	# BASE OBJECT
	else:
		# assume its a base object
		total_rela_offset = data_rela_offset
	# END handle type id
	
	abs_data_offset = offset + total_rela_offset
	if as_stream:
		stream = DecompressMemMapReader(buffer(data, total_rela_offset), False, uncomp_size)
		if delta_info is None:
			return abs_data_offset, OPackStream(offset, type_id, uncomp_size, stream)
		else:
			return abs_data_offset, ODeltaPackStream(offset, type_id, uncomp_size, delta_info, stream)
	else:
		if delta_info is None:
			return abs_data_offset, OPackInfo(offset, type_id, uncomp_size)
		else:
			return abs_data_offset, ODeltaPackInfo(offset, type_id, uncomp_size, delta_info)
    def _object(self, sha, as_stream, index=-1):
        """:return: OInfo or OStream object providing information about the given sha
		:param index: if not -1, its assumed to be the sha's index in the IndexFile"""
        # its a little bit redundant here, but it needs to be efficient
        if index < 0:
            index = self._sha_to_index(sha)
        if sha is None:
            sha = self._index.sha(index)
        # END assure sha is present ( in output )
        offset = self._index.offset(index)
        type_id, uncomp_size, data_rela_offset = pack_object_header_info(
            buffer(self._pack._data, offset))
        if as_stream:
            if type_id not in delta_types:
                packstream = self._pack.stream(offset)
                return OStream(sha, packstream.type, packstream.size,
                               packstream.stream)
            # END handle non-deltas

            # produce a delta stream containing all info
            # To prevent it from applying the deltas when querying the size,
            # we extract it from the delta stream ourselves
            streams = self.collect_streams_at_offset(offset)
            buf = streams[0].read(512)
            offset, src_size = msb_size(buf)
            offset, target_size = msb_size(buf, offset)

            streams[0].stream.seek(
                0)  # assure it can be read by the delta reader
            dstream = DeltaApplyReader.new(streams)

            return OStream(sha, dstream.type, target_size, dstream)
        else:
            if type_id not in delta_types:
                return OInfo(sha, type_id_to_type_map[type_id], uncomp_size)
            # END handle non-deltas

            # deltas are a little tougher - unpack the first bytes to obtain
            # the actual target size, as opposed to the size of the delta data
            streams = self.collect_streams_at_offset(offset)
            buf = streams[0].read(512)
            offset, src_size = msb_size(buf)
            offset, target_size = msb_size(buf, offset)

            # collect the streams to obtain the actual object type
            if streams[-1].type_id in delta_types:
                raise BadObject(sha, "Could not resolve delta object")
            return OInfo(sha, streams[-1].type, target_size)
Exemple #4
0
	def _object(self, sha, as_stream, index=-1):
		""":return: OInfo or OStream object providing information about the given sha
		:param index: if not -1, its assumed to be the sha's index in the IndexFile"""
		# its a little bit redundant here, but it needs to be efficient
		if index < 0:
			index = self._sha_to_index(sha)
		if sha is None:
			sha = self._index.sha(index)
		# END assure sha is present ( in output )
		offset = self._index.offset(index)
		type_id, uncomp_size, data_rela_offset = pack_object_header_info(buffer(self._pack._data, offset))
		if as_stream:
			if type_id not in delta_types:
				packstream = self._pack.stream(offset)
				return OStream(sha, packstream.type, packstream.size, packstream.stream)
			# END handle non-deltas
			
			# produce a delta stream containing all info
			# To prevent it from applying the deltas when querying the size, 
			# we extract it from the delta stream ourselves
			streams = self.collect_streams_at_offset(offset)
			buf = streams[0].read(512)
			offset, src_size = msb_size(buf)
			offset, target_size = msb_size(buf, offset)
			
			streams[0].stream.seek(0)				# assure it can be read by the delta reader
			dstream = DeltaApplyReader.new(streams)
			
			return OStream(sha, dstream.type, target_size, dstream) 
		else:
			if type_id not in delta_types:
				return OInfo(sha, type_id_to_type_map[type_id], uncomp_size)
			# END handle non-deltas
			
			# deltas are a little tougher - unpack the first bytes to obtain
			# the actual target size, as opposed to the size of the delta data
			streams = self.collect_streams_at_offset(offset)
			buf = streams[0].read(512)
			offset, src_size = msb_size(buf)
			offset, target_size = msb_size(buf, offset)
			
			# collect the streams to obtain the actual object type
			if streams[-1].type_id in delta_types:
				raise BadObject(sha, "Could not resolve delta object")
			return OInfo(sha, streams[-1].type, target_size)