From b7710d02a98d10f2e8d8e522abe8be0b60118657 Mon Sep 17 00:00:00 2001 From: lisk77 Date: Sun, 24 Aug 2025 23:52:06 +0200 Subject: [PATCH] feat(tree): added a simple function to save tree snapshots compressed to the disk --- CMakeLists.txt | 4 ++++ include/tree.h | 3 +++ src/tree.c | 36 ++++++++++++++++++++++++++++++++++++ 3 files changed, 43 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 1e253b9..20d189c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -54,3 +54,7 @@ set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin) set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib) set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib) +# Find and link zlib +find_package(ZLIB REQUIRED) +target_link_libraries(${TARGET_NAME} PRIVATE ZLIB::ZLIB) + diff --git a/include/tree.h b/include/tree.h index e5276da..f54509f 100644 --- a/include/tree.h +++ b/include/tree.h @@ -8,6 +8,8 @@ #include #include #include +#include + typedef struct { char** paths; @@ -20,5 +22,6 @@ void add_path(PathBuffer*, char*); void free_path_buffer(PathBuffer*); char* find_root(char*); void walk(const char*, const char*, const char*, PathBuffer*); +void save_tree(const char*, PathBuffer*); #endif // TREE_H diff --git a/src/tree.c b/src/tree.c index 2b6b674..e544fdd 100644 --- a/src/tree.c +++ b/src/tree.c @@ -231,3 +231,39 @@ void walk(const char* base, const char* base_rel, const char* rel, PathBuffer* p closedir(dir); } + +void save_tree(const char* path, PathBuffer* tree) { + char tmp[1024]; + size_t offset = 0; + + FILE* fp = fopen(path, "wb"); + if (!fp) { perror("ERROR: cannot open path in save_tree!\n"); return; } + + offset += snprintf(tmp, sizeof(tmp), "%zu:", tree->len); + + for (size_t idx = 0; idx < tree->len; idx++) { + size_t remaining = sizeof(tmp) - offset; + + int written = snprintf(tmp + offset, remaining, "%s:", tree->paths[idx]); + if (written < 0 || (size_t)written >= remaining) { + perror("ERROR: buffer overflow in save_tree!\n"); + fclose(fp); + return; + } + + offset += (size_t)written; + } + + uLong originalLen = strlen(tmp) + 1; + + uLong compressedLen = compressBound(originalLen); + Bytef compressed[compressedLen]; + + if (compress(compressed, &compressedLen, (const Bytef*)tmp, originalLen) != Z_OK) { + perror("ERROR: compression failed in save_tree!"); + return; + } + + fwrite(compressed, sizeof(Bytef), compressedLen, fp); + fclose(fp); +}