def save(self, io=None): # load all file data. self.load_all() files = self._files if io is None: io = self._io # clean file. io.seek(0) io.truncate() head_data = b'' # build head in memory. with BytesIO() as io_head: IOHelper.write_ascii_string(io_head, FILE_MAGIC) count = len(files) IOHelper.write_struct(io_head, 'i', count) # count file offset. # magic(16) + count(4) + info(264 * n) + hash(32) offset = 52 + count * 264 for file in files: file['offset'] = offset file['size'] = len(file['data']) IOHelper.write_struct(io_head, '<2i', file['offset'], file['size']) if isinstance(file['name'], str): name_data = file['name'].encode(encoding='euc_kr') elif isinstance(file['name'], bytes): name_data = file['name'] else: raise Exception('Filename type Error: %s(%s)' % (file['name'], type(file['name']))) name = NPK._decrypt_name(name_data) io_head.write(name) offset += file['size'] head_data = IOHelper.read_range(io_head) io.write(head_data) # write hash. io.write( hashlib.sha256(head_data[:len(head_data) // 17 * 17]).digest()) for file in files: io.seek(file['offset']) io.write(file['data'])
def save(self, io=None): # load all file data. self.load_all() files = self._files if io is None: io = self._io # clean file. io.seek(0) io.truncate() # build head in memory. with BytesIO() as io_head: IOHelper.write_ascii_string(io_head, FILE_MAGIC) count = len(files) IOHelper.write_struct(io_head, 'i', count) # count file offset. # magic(16) + count(4) + info(264 * n) + hash(32) offset = 52 + count * 264 for file in files: IOHelper.write_struct(io_head, '<2i', file['offset'], file['size']) name = NPK._decrypt_name(file['name'].encode(encoding='ascii')) io_head.write(name) offset += file['size'] head_data = IOHelper.read_range(io_head) io.write(head_data) # write hash. io.write( hashlib.sha256(head_data[:len(head_data) // 17 * 17]).digest()) for file in files: io.seek(file['offset']) io.write(file['data'])
def save(self, io=None): self.load_all() images = self._images color_board = self._color_board color_boards = self._color_boards map_images = self._map_images version = self._version images_data = [] # compress data, get size, add to data_list. if version == FILE_VERSION_5: for map_image in sorted(map_images): data = map_image['data'] map_image['raw_size'] = len(data) data = zlib.compress(data) map_image['data_size'] = len(data) images_data.append(data) else: for image in images: if image['format'] != IMAGE_FORMAT_LINK: data = image['data'] if image['extra'] == IMAGE_EXTRA_ZLIB or image[ 'extra'] == IMAGE_EXTRA_MAP_ZLIB: data = zlib.compress(data) image['size'] = len(data) images_data.append(data) images_size = self._save_count_images_size() file_size = self._save_count_file_size(images_size, images_data) if io is None: io = self._io io.seek(0) io.truncate() with BytesIO() as io_head: if version == FILE_VERSION_1: IOHelper.write_ascii_string(io_head, FILE_MAGIC_OLD) # TODO: unknown, now be zero. IOHelper.write_struct(io_head, 'h', 0) else: # images_size IOHelper.write_ascii_string(io_head, FILE_MAGIC) IOHelper.write_struct(io_head, 'i', images_size) # keep, version, img_count IOHelper.write_struct(io_head, '<3i', 0, version, len(images)) is_ver5 = version == FILE_VERSION_5 if is_ver5: # map_count, file_size IOHelper.write_struct(io_head, '<2i', len(map_images), file_size) if version == FILE_VERSION_4 or is_ver5: # color_count IOHelper.write_struct(io_head, 'i', len(color_board)) for color in color_board: # color IOHelper.write_struct(io_head, '<4B', *color) if is_ver5: for map_image in map_images: IOHelper.write_struct(io_head, '<7i', map_image['keep'], map_image['format'], map_image['index'], map_image['data_size'], map_image['raw_size'], map_image['w'], map_image['h']) if version == FILE_VERSION_6: # color_board count. IOHelper.write_struct(io_head, 'i', len(color_boards)) for color_board_v6 in color_boards: # color_count IOHelper.write_struct(io_head, 'i', len(color_board_v6)) for color in color_board_v6: # color IOHelper.write_struct(io_head, '<4B', *color) for image in images: # format IOHelper.write_struct(io_head, 'i', image['format']) if image['format'] == IMAGE_FORMAT_LINK: # link IOHelper.write_struct(io_head, 'i', image['link']) else: # extra, w, h, size, x, y, mw, mh IOHelper.write_struct(io_head, '<8i', image['extra'], image['w'], image['h'], image['size'], image['x'], image['y'], image['mw'], image['mh']) if image['extra'] == IMAGE_EXTRA_MAP_ZLIB: # keep_1, map_index, left, top, right, bottom, rotate IOHelper.write_struct(io_head, '<7i', image['keep_1'], image['map_index'], image['left'], image['top'], image['right'], image['bottom'], image['rotate']) head_data = IOHelper.read_range(io_head) io.write(head_data) for data in images_data: io.write(data)