feat(basefiles): added utility to convert a BaseFileBuffer into a FileInfoBuffer

This commit is contained in:
lisk77 2025-09-05 21:15:42 +02:00
parent 315e37b643
commit b4dff29a5c
2 changed files with 114 additions and 12 deletions

View file

@ -21,5 +21,6 @@ BaseFileInfo* base_file_buffer_search(BaseFileBuffer*, char*);
int base_file_buffer_remove(BaseFileBuffer*, char*);
int read_base_file_list(BaseFileBuffer*, char*);
int write_base_file_list(BaseFileBuffer*, char*);
FileInfoBuffer* basefilebuffer_to_fileinfobuffer(BaseFileBuffer*);
#endif // BASE_FILE_BUFFER_H

View file

@ -57,23 +57,66 @@ int read_base_file_list(BaseFileBuffer* buffer, char* base_file_list_path) {
return 1;
}
char base_file_list[4096];
uLongf dest_len = sizeof(base_file_list) - 1;
size_t idx = 0;
while (idx < compressed_size && IS_DIGIT(compressed_data[idx])) {
idx++;
}
int result = uncompress((unsigned char*)base_file_list, &dest_len, compressed_data, compressed_size);
if (idx == 0) {
perror("ERROR: no length found at start of base file list!");
free(compressed_data);
return 0;
}
char* size_str = calloc(idx + 1, sizeof(char));
if (!size_str) {
free(compressed_data);
return 0;
}
memcpy(size_str, compressed_data, idx);
size_str[idx] = '\0';
char* end;
long original_size = strtol(size_str, &end, 10);
if (end == size_str || *end != '\0') {
perror("ERROR: invalid length in read_base_file_list!");
free(size_str);
free(compressed_data);
return 0;
}
free(size_str);
if (idx < compressed_size && compressed_data[idx] == ' ') {
idx++;
}
char* base_file_list = calloc(original_size + 1, sizeof(char));
if (!base_file_list) {
free(compressed_data);
return 0;
}
uLongf dest_len = (uLongf)original_size;
int result = uncompress((unsigned char*)base_file_list, &dest_len, compressed_data + idx, compressed_size - idx);
free(compressed_data);
if (result != Z_OK) {
perror("ERROR: decompression of the base file list failed!");
free(base_file_list);
return 0;
}
base_file_list[dest_len] = '\0';
size_t list_len = strlen(base_file_list);
if (list_len == 0) return 1;
size_t idx = 0;
char current;
if (list_len == 0) {
free(base_file_list);
return 1;
}
idx = 0;
while (idx < list_len && IS_DIGIT(base_file_list[idx])) {
idx++;
@ -81,6 +124,7 @@ int read_base_file_list(BaseFileBuffer* buffer, char* base_file_list_path) {
if (idx == 0) {
perror("ERROR: no length found at start of base_file_list!");
free(base_file_list);
return 0;
}
@ -88,11 +132,11 @@ int read_base_file_list(BaseFileBuffer* buffer, char* base_file_list_path) {
memcpy(len_str, base_file_list, idx);
len_str[idx] = '\0';
char* end;
long len = strtol(len_str, &end, 10);
if (end == len_str || *end != '\0') {
perror("ERROR: invalid length in read_base_file_list!");
free(len_str);
free(base_file_list);
return 0;
}
free(len_str);
@ -111,6 +155,7 @@ int read_base_file_list(BaseFileBuffer* buffer, char* base_file_list_path) {
if (idx == name_start) {
perror("ERROR: empty filename in base_file_list!");
free(base_file_list);
return 0;
}
@ -132,6 +177,7 @@ int read_base_file_list(BaseFileBuffer* buffer, char* base_file_list_path) {
if (idx == base_start) {
perror("ERROR: no base_num found in base_file_list!");
free(file_name);
free(base_file_list);
return 0;
}
@ -145,6 +191,7 @@ int read_base_file_list(BaseFileBuffer* buffer, char* base_file_list_path) {
perror("ERROR: invalid base_num in base_file_list!");
free(file_name);
free(base_num_str);
free(base_file_list);
return 0;
}
info.base_num = base_num;
@ -162,6 +209,7 @@ int read_base_file_list(BaseFileBuffer* buffer, char* base_file_list_path) {
if (idx == diff_start) {
perror("ERROR: no diff_num found in base_file_list!");
free(file_name);
free(base_file_list);
return 0;
}
@ -175,6 +223,7 @@ int read_base_file_list(BaseFileBuffer* buffer, char* base_file_list_path) {
perror("ERROR: invalid diff_num in base_file_list!");
free(file_name);
free(diff_num_str);
free(base_file_list);
return 0;
}
info.diff_num = diff_num;
@ -187,12 +236,25 @@ int read_base_file_list(BaseFileBuffer* buffer, char* base_file_list_path) {
base_file_buffer_push(buffer, info);
}
free(base_file_list);
return 1;
}
int write_base_file_list(BaseFileBuffer* buffer, char* info_file) {
base_file_buffer_sort(buffer);
char tmp[1024];
size_t buffer_size = 1;
buffer_size += snprintf(NULL, 0, "%d ", buffer->len);
for (size_t idx = 0; idx < buffer->len; idx++) {
BaseFileInfo* info = (BaseFileInfo*)buffer->items + idx;
buffer_size += 3 +
strlen(info->name) +
snprintf(NULL, 0, "%zu", info->base_num) +
snprintf(NULL, 0, "%zu", info->diff_num);
}
char tmp[buffer_size];
size_t offset = 0;
offset += snprintf(tmp + offset, sizeof(tmp) - offset, "%d ", buffer->len);
@ -209,19 +271,58 @@ int write_base_file_list(BaseFileBuffer* buffer, char* info_file) {
FILE* fp = fopen(info_file, "wb");
if (!fp) { perror("ERROR: cannot open path in snapshot_tree!\n"); return 0; }
uLong originalLen = strlen(tmp) + 1;
uLong originalLen = strlen(tmp);
uLong compressedLen = compressBound(originalLen);
Bytef compressed[compressedLen];
if (compress(compressed, &compressedLen, (const Bytef*)tmp, originalLen) != Z_OK) {
perror("ERROR: compression failed in snapshot_tree!");
Bytef* compressed = malloc(compressedLen);
if (!compressed) {
fclose(fp);
return 0;
}
fwrite(compressed, sizeof(Bytef), compressedLen, fp);
if (compress(compressed, &compressedLen, (const Bytef*)tmp, originalLen) != Z_OK) {
perror("ERROR: compression failed in snapshot_tree!");
free(compressed);
fclose(fp);
return 0;
}
fprintf(fp, "%lu ", originalLen);
fwrite(compressed, sizeof(Bytef), compressedLen, fp);
fclose(fp);
free(compressed);
return 1;
}
FileInfoBuffer* basefilebuffer_to_fileinfobuffer(BaseFileBuffer* base_buffer) {
if (!base_buffer) return NULL;
FileInfoBuffer* file_buffer = file_info_buffer_new();
if (!file_buffer) return NULL;
for (size_t i = 0; i < base_buffer->len; i++) {
BaseFileInfo* base_info = (BaseFileInfo*)base_buffer->items + i;
struct stat st;
if (stat(base_info->name, &st) != 0) {
continue;
}
FileInfo file_info;
file_info.name = strdup(base_info->name);
if (!file_info.name) {
file_info_buffer_free(file_buffer);
return NULL;
}
file_info.mode = st.st_mode;
if (!file_info_buffer_push(file_buffer, file_info)) {
free(file_info.name);
file_info_buffer_free(file_buffer);
return NULL;
}
}
return file_buffer;
}