Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Storage: unzip tests #3158

Draft
wants to merge 3 commits into
base: dev
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,10 @@
url = https://github.com/STMicroelectronics/stm32wbxx_hal_driver
[submodule "lib/stm32wb_copro"]
path = lib/stm32wb_copro
url = https://github.com/flipperdevices/stm32wb_copro.git
url = https://github.com/flipperdevices/stm32wb_copro.git
[submodule "lib/uzlib"]
path = lib/uzlib
url = https://github.com/pfalcon/uzlib.git
[submodule "documentation/doxygen/doxygen-awesome-css"]
path = documentation/doxygen/doxygen-awesome-css
url = https://github.com/jothepro/doxygen-awesome-css.git
145 changes: 145 additions & 0 deletions applications/services/storage/storage_cli.c
Original file line number Diff line number Diff line change
Expand Up @@ -443,6 +443,146 @@ static void storage_cli_remove(Cli* cli, FuriString* path) {
furi_record_close(RECORD_STORAGE);
}

#include <lib/uzlib/src/uzlib.h>

typedef struct {
File* file;
uint8_t* buffer;
size_t buffer_size;
uint8_t* dict;
size_t dict_size;
struct uzlib_uncomp uzlib;

bool eof;
} UnZipData;

typedef int (*UnizpDataReadCb)(struct uzlib_uncomp* uncomp);

UnZipData* unzip_data_alloc(size_t dict_size, size_t buffer_size, UnizpDataReadCb cb, File* file) {
UnZipData* data = malloc(sizeof(UnZipData));
data->file = file;
data->buffer_size = buffer_size;
data->buffer = malloc(buffer_size);
data->dict_size = dict_size;
data->dict = malloc(dict_size);

uzlib_uncompress_init(&data->uzlib, data->dict, data->dict_size);

data->uzlib.source = 0;
data->uzlib.source_limit = 0;
data->uzlib.source_read_cb = cb;
data->eof = false;

return data;
}

void unzip_data_free(UnZipData* uzlib) {
free(uzlib->buffer);
free(uzlib->dict);
free(uzlib);
}

int unzip_read_cb(struct uzlib_uncomp* uncomp) {
void* data_p = uncomp;
data_p -= offsetof(UnZipData, uzlib);
UnZipData* data = data_p;

uint16_t read_size = storage_file_read(data->file, data->buffer, data->buffer_size);
data->uzlib.source = &data->buffer[1]; // we will return buffer[0] at exit
data->uzlib.source_limit = data->buffer + read_size;

if(read_size == 0) {
return -1;
}

return data->buffer[0];
}

int32_t unzip_get_data(UnZipData* data, void* out, size_t out_len) {
if(data->eof) {
return 0;
}

data->uzlib.dest = out;
data->uzlib.dest_limit = (uint8_t*)out + out_len;

int status = uzlib_uncompress_chksum(&data->uzlib);

if(status == TINF_DONE) {
data->eof = true;
}
if(status < 0) {
return status;
}
return data->uzlib.dest - (uint8_t*)out;
}

#include <lib/toolbox/profiler.h>

static void storage_cli_unzip(Cli* cli, FuriString* path) {
UNUSED(cli);
UNUSED(path);
Storage* api = furi_record_open(RECORD_STORAGE);
File* in_file = storage_file_alloc(api);
File* out_file = storage_file_alloc(api);
UnZipData* data = unzip_data_alloc(32 * 1024, 10 * 1024, unzip_read_cb, in_file);
Profiler* profiler = profiler_alloc();

int res;

const size_t out_size = 10 * 1024;
uint8_t* out = malloc(out_size);

profiler_start(profiler, "unzip");

do {
if(!storage_file_open(in_file, furi_string_get_cstr(path), FSAM_READ, FSOM_OPEN_EXISTING)) {
storage_cli_print_error(storage_file_get_error(in_file));
break;
}

if(!storage_file_open(out_file, "/ext/out.txt", FSAM_WRITE, FSOM_CREATE_ALWAYS)) {
storage_cli_print_error(storage_file_get_error(out_file));
break;
}

res = uzlib_gzip_parse_header(&data->uzlib);
if(res != TINF_OK) {
printf("Error parsing header: %d\n", res);
break;
}

while(true) {
res = unzip_get_data(data, out, out_size);
if(res < 0) {
printf("Error during decompression: %d\n", res);
break;
}
if(res == 0) {
printf("End\n");
break;
}

uint16_t written_size = storage_file_write(out_file, out, res);
if(written_size != res) {
storage_cli_print_error(storage_file_get_error(out_file));
break;
}
}
} while(false);

profiler_stop(profiler, "unzip");

profiler_dump(profiler);

profiler_free(profiler);
storage_file_free(in_file);
storage_file_free(out_file);
unzip_data_free(data);
free(out);
furi_record_close(RECORD_STORAGE);
}

static void storage_cli_rename(Cli* cli, FuriString* old_path, FuriString* args) {
UNUSED(cli);
Storage* api = furi_record_open(RECORD_STORAGE);
Expand Down Expand Up @@ -564,6 +704,11 @@ void storage_cli(Cli* cli, FuriString* args, void* context) {
break;
}

if(furi_string_cmp_str(cmd, "unzip") == 0) {
storage_cli_unzip(cli, path);
break;
}

if(furi_string_cmp_str(cmd, "rename") == 0) {
storage_cli_rename(cli, path, args);
break;
Expand Down
1 change: 1 addition & 0 deletions lib/SConscript
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ libs = env.BuildModules(
"ble_profile",
"bit_lib",
"datetime",
"uzlib",
],
)

Expand Down
1 change: 1 addition & 0 deletions lib/uzlib
Submodule uzlib added at 6d60d6
34 changes: 34 additions & 0 deletions lib/uzlib.scons
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
Import("env")

env.Append(
# CPPPATH=[
# "#/lib/subghz",
# ],
# SDK_HEADERS=[
# File("environment.h"),
# ],
)

libenv = env.Clone(FW_LIB_NAME="uzlib")
libenv.ApplyLibFlags()

libenv.AppendUnique(
CCFLAGS=[
"-Wno-redundant-decls",
"-Wno-sign-compare",
],
)

sources = [
"uzlib/src/adler32.c",
"uzlib/src/crc32.c",
"uzlib/src/defl_static.c",
"uzlib/src/genlz77.c",
"uzlib/src/tinfgzip.c",
"uzlib/src/tinflate.c",
"uzlib/src/tinfzlib.c",
]

lib = libenv.StaticLibrary("${FW_LIB_NAME}", sources)
libenv.Install("${LIB_DIST_DIR}", lib)
Return("lib")
1 change: 1 addition & 0 deletions targets/f18/target.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
"usb_stm32",
"appframe",
"assets",
"uzlib",
"one_wire",
"music_worker",
"mjs",
Expand Down
1 change: 1 addition & 0 deletions targets/f7/target.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
"toolbox",
"nfc",
"digital_signal",
"uzlib",
"pulse_reader",
"signal_reader",
"microtar",
Expand Down
Loading