#include "tinyuz_port.h" #include "fal.h" #include "tuz_dec.h" #include "patch_types.h"
typedef struct TTuzListener { const hpatch_TStreamInput* input_file_stream_handle; hpatch_StreamPos_t readPos; tuz_TInputStream_read _do_read_encompress_file; }TTuzListener;
hpatch_BOOL _do_read_encompress_file(const hpatch_TStreamInput* stream, hpatch_StreamPos_t readFromPos, unsigned char* out_data, unsigned char* out_data_end) { size_t readLen = (size_t)(out_data_end - out_data); if (readLen == 0) return hpatch_TRUE;
size_t compressed_stream_size = stream->streamSize;
if ((readLen > compressed_stream_size) || (readFromPos > compressed_stream_size - readLen)) return hpatch_FALSE;
const struct fal_partition *partition = fal_partition_find("app_ziped"); int result = fal_partition_read(partition, readFromPos, out_data, readLen);
return hpatch_TRUE; }
hpatch_BOOL _do_write_decompress_file(const hpatch_TStreamOutput* stream, hpatch_StreamPos_t writeToPos, const unsigned char* data, const unsigned char* data_end) { unsigned int offset = 0;
size_t writeLen = (size_t)(data_end - data); if (writeLen == 0) return hpatch_TRUE;
size_t write_max_space = stream->streamSize;
if ((writeLen > write_max_space)||(writeToPos > write_max_space - writeLen)) return hpatch_FALSE;
const struct fal_partition *partition = fal_partition_find("app_newer"); int result = fal_partition_write(partition, offset+writeToPos, data, writeLen);
return hpatch_TRUE; }
static tuz_BOOL input_file_stream_read_function(void *listener, tuz_byte *decompressed_file_stream, tuz_size_t *code_size) { TTuzListener *self = (TTuzListener*)listener; tuz_size_t r_len = *code_size; hpatch_StreamPos_t curReadPos = self->readPos; hpatch_StreamPos_t s_size = self->input_file_stream_handle->streamSize - curReadPos;
if (r_len > s_size){ r_len = (tuz_size_t)s_size; *code_size = r_len; }
self->readPos += r_len; return self->input_file_stream_handle->read(self->input_file_stream_handle, curReadPos, decompressed_file_stream, decompressed_file_stream + r_len); }
size_t tuz_decompress(size_t compressed_file_size, size_t cache_size) { hpatch_TStreamOutput decompressed_file_stream_handle = { .streamImport = &decompressed_file_stream_handle, .streamSize = TUZ_DECOMPRESS_SPACE_SIZE, .write = _do_write_decompress_file, .read_writed = NULL, };
hpatch_TStreamInput input_file_stream_handle = { .streamImport = &input_file_stream_handle, .streamSize = compressed_file_size, .read = _do_read_encompress_file, };
TTuzListener listener = {&input_file_stream_handle, 0, input_file_stream_read_function}; tuz_TStream tuz; tuz_TResult result = tuz_OK;
tuz_size_t dictSize = tuz_TStream_read_dict_size(&listener, listener._do_read_encompress_file);
tuz_byte* decompress_buf = 0; cache_size >>= 1; decompress_buf = (tuz_byte*)tuz_malloc(dictSize + cache_size*2);
if (decompress_buf == 0) return TINYUZ_MEM_ERROR;
result = tuz_TStream_open(&tuz, &listener, listener._do_read_encompress_file, decompress_buf + cache_size, (tuz_size_t)dictSize, (tuz_size_t)cache_size);
hpatch_StreamPos_t stream_index = 0;
while (result == tuz_OK) { tuz_size_t decompress_len = (tuz_size_t)cache_size;
result = tuz_TStream_decompress_partial(&tuz, decompress_buf, &decompress_len);
if (result <= tuz_STREAM_END) { if (decompressed_file_stream_handle.write(&decompressed_file_stream_handle, stream_index, decompress_buf, decompress_buf + decompress_len)) { stream_index += decompress_len; } else { tuz_free(decompress_buf); return TINYUZ_OPENWRITE_ERROR; } } }
tuz_free(decompress_buf);
return stream_index; }
|