mirror of
https://github.com/Next-Flip/Momentum-Firmware.git
synced 2026-04-24 03:29:57 -07:00
Updater: resource compression (#3716)
* toolbox: compress: moved decompressor implementation to separate func * toolbox: compress: callback-based api; cli: storage unpack command * toolbox: compress: separate r/w contexts for stream api * targets: f18: sync API * compress: naming fixes & cleanup * toolbox: compress: using hs buffer size for stream buffers * toolbox: tar: heatshrink stream mode * toolbox: compress: docs & small cleanup * toolbox: tar: header support for .hs; updater: now uses .hs for resources; .hs.tar: now rewindable * toolbox: compress: fixed hs stream tail handling * updater: reworked progress for resources cleanup; rebalanced stage weights * updater: single-pass decompression; scripts: print resources compression ratio * updater: fixed warnings * toolbox: tar: doxygen * docs: update * docs: info or tarhs format; scripts: added standalone compression/decompression tool for heatshrink-formatted streams * scripts: tarhs: fixed parameter handling * cli: storage extract command; toolbox: tar: guess type based on extension * unit_tests: added test for streamed raw hs decompressor `compress_decode_streamed` * unit_tests: compress: added extraction test for .tar.hs * rpc: autodetect compressed archives * scripts: minor cleanup of common parts * scripts: update: now using in-memory intermediate tar stream * scripts: added hs.py wrapper for heatshrink-related ops (single object and directory-as-tar compression) * scripts: naming fixes * Toolbox: export compress_config_heatshrink_default as const symbol * Toolbox: fix various types naming * Toolbox: more of types naming fixes * Toolbox: use size_t in compress io callbacks and structures * UnitTests: update to match new compress API * Toolbox: proper path_extract_extension usage Co-authored-by: あく <alleteam@gmail.com>
This commit is contained in:
@@ -5,6 +5,7 @@
|
||||
#include <lib/toolbox/args.h>
|
||||
#include <lib/toolbox/md5_calc.h>
|
||||
#include <lib/toolbox/dir_walk.h>
|
||||
#include <lib/toolbox/tar/tar_archive.h>
|
||||
#include <storage/storage.h>
|
||||
#include <storage/storage_sd_api.h>
|
||||
#include <power/power_service/power.h>
|
||||
@@ -33,6 +34,7 @@ static void storage_cli_print_usage(void) {
|
||||
printf("\tmd5\t - md5 hash of the file\r\n");
|
||||
printf("\tstat\t - info about file or dir\r\n");
|
||||
printf("\ttimestamp\t - last modification timestamp\r\n");
|
||||
printf("\textract\t - extract tar archive to destination\r\n");
|
||||
};
|
||||
|
||||
static void storage_cli_print_error(FS_Error error) {
|
||||
@@ -496,6 +498,47 @@ static void storage_cli_md5(Cli* cli, FuriString* path) {
|
||||
furi_record_close(RECORD_STORAGE);
|
||||
}
|
||||
|
||||
static bool tar_extract_file_callback(const char* name, bool is_directory, void* context) {
|
||||
UNUSED(context);
|
||||
printf("\t%s %s\r\n", is_directory ? "D" : "F", name);
|
||||
return true;
|
||||
}
|
||||
|
||||
static void storage_cli_extract(Cli* cli, FuriString* old_path, FuriString* args) {
|
||||
UNUSED(cli);
|
||||
FuriString* new_path = furi_string_alloc();
|
||||
|
||||
if(!args_read_probably_quoted_string_and_trim(args, new_path)) {
|
||||
storage_cli_print_usage();
|
||||
furi_string_free(new_path);
|
||||
return;
|
||||
}
|
||||
|
||||
Storage* api = furi_record_open(RECORD_STORAGE);
|
||||
|
||||
TarArchive* archive = tar_archive_alloc(api);
|
||||
TarOpenMode tar_mode = tar_archive_get_mode_for_path(furi_string_get_cstr(old_path));
|
||||
do {
|
||||
if(!tar_archive_open(archive, furi_string_get_cstr(old_path), tar_mode)) {
|
||||
printf("Failed to open archive\r\n");
|
||||
break;
|
||||
}
|
||||
uint32_t start_tick = furi_get_tick();
|
||||
tar_archive_set_file_callback(archive, tar_extract_file_callback, NULL);
|
||||
printf("Unpacking to %s\r\n", furi_string_get_cstr(new_path));
|
||||
bool success = tar_archive_unpack_to(archive, furi_string_get_cstr(new_path), NULL);
|
||||
uint32_t end_tick = furi_get_tick();
|
||||
printf(
|
||||
"Decompression %s in %lu ticks \r\n",
|
||||
success ? "success" : "failed",
|
||||
end_tick - start_tick);
|
||||
} while(false);
|
||||
|
||||
tar_archive_free(archive);
|
||||
furi_string_free(new_path);
|
||||
furi_record_close(RECORD_STORAGE);
|
||||
}
|
||||
|
||||
void storage_cli(Cli* cli, FuriString* args, void* context) {
|
||||
UNUSED(context);
|
||||
FuriString* cmd;
|
||||
@@ -589,6 +632,11 @@ void storage_cli(Cli* cli, FuriString* args, void* context) {
|
||||
break;
|
||||
}
|
||||
|
||||
if(furi_string_cmp_str(cmd, "extract") == 0) {
|
||||
storage_cli_extract(cli, path, args);
|
||||
break;
|
||||
}
|
||||
|
||||
storage_cli_print_usage();
|
||||
} while(false);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user