def CompressData(self, indata): """Compress data according to the entry's compression method Args: indata: Data to compress Returns: Compressed data (first word is the compressed size) """ self.uncomp_data = indata if self.compress != 'none': self.uncomp_size = len(indata) data = comp_util.compress(indata, self.compress) return data
def get_data_and_offset(self, offset=None, pad_byte=None): """Obtain the contents of the file, in CBFS format and the offset of the data within the file Returns: tuple: bytes representing the contents of this file, packed and aligned for directly inserting into the final CBFS output offset to the file data from the start of the returned data. """ name = _pack_string(self.name) hdr_len = len(name) + FILE_HEADER_LEN attr_pos = 0 content = b'' attr = b'' pad = b'' data = self.data if self.ftype == TYPE_STAGE: elf_data = elf.DecodeElf(data, self.base_address) content = struct.pack(STAGE_FORMAT, self.compress, elf_data.entry, elf_data.load, len(elf_data.data), elf_data.memsize) data = elf_data.data elif self.ftype == TYPE_RAW: orig_data = data if self.compress == COMPRESS_LZ4: data = comp_util.compress(orig_data, 'lz4', with_header=False) elif self.compress == COMPRESS_LZMA: data = comp_util.compress(orig_data, 'lzma', with_header=False) self.memlen = len(orig_data) self.data_len = len(data) attr = struct.pack(ATTR_COMPRESSION_FORMAT, FILE_ATTR_TAG_COMPRESSION, ATTR_COMPRESSION_LEN, self.compress, self.memlen) elif self.ftype == TYPE_EMPTY: data = tools.GetBytes(self.erase_byte, self.size) else: raise ValueError('Unknown type %#x when writing\n' % self.ftype) if attr: attr_pos = hdr_len hdr_len += len(attr) if self.cbfs_offset is not None: pad_len = self.cbfs_offset - offset - hdr_len if pad_len < 0: # pragma: no cover # Test coverage of this is not available since this should never # happen. It indicates that get_header_len() provided an # incorrect value (too small) so that we decided that we could # put this file at the requested place, but in fact a previous # file extends far enough into the CBFS that this is not # possible. raise ValueError( "Internal error: CBFS file '%s': Requested offset %#x but current output position is %#x" % (self.name, self.cbfs_offset, offset)) pad = tools.GetBytes(pad_byte, pad_len) hdr_len += pad_len # This is the offset of the start of the file's data, size = len(content) + len(data) hdr = struct.pack(FILE_HEADER_FORMAT, FILE_MAGIC, size, self.ftype, attr_pos, hdr_len) # Do a sanity check of the get_header_len() function, to ensure that it # stays in lockstep with this function expected_len = self.get_header_len() actual_len = len(hdr + name + attr) if expected_len != actual_len: # pragma: no cover # Test coverage of this is not available since this should never # happen. It probably indicates that get_header_len() is broken. raise ValueError( "Internal error: CBFS file '%s': Expected headers of %#x bytes, got %#d" % (self.name, expected_len, actual_len)) return hdr + name + attr + pad + content + data, hdr_len