refactor(tree)!: changed the api of the PathBuffer and generalized it to a List of char*
This commit is contained in:
parent
7113b53caa
commit
8efadf051c
2 changed files with 60 additions and 55 deletions
|
|
@ -11,19 +11,26 @@
|
||||||
#include <zlib.h>
|
#include <zlib.h>
|
||||||
|
|
||||||
#include "utilities.h"
|
#include "utilities.h"
|
||||||
|
#include "hash.h"
|
||||||
|
#include "file.h"
|
||||||
|
|
||||||
|
typedef List PathBuffer;
|
||||||
|
typedef List Tree;
|
||||||
|
typedef List FileInfoBuffer;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
char** paths;
|
char* dir;
|
||||||
|
FileInfoBuffer* files;
|
||||||
size_t len;
|
size_t len;
|
||||||
size_t capacity;
|
size_t capacity;
|
||||||
} PathBuffer;
|
} TreeEntry;
|
||||||
|
|
||||||
PathBuffer* new_path_buffer();
|
PathBuffer* path_buffer_new();
|
||||||
void add_path(PathBuffer*, char*);
|
void path_buffer_push(PathBuffer*, char*);
|
||||||
void sort_path_buffer(PathBuffer*);
|
void path_buffer_sort(PathBuffer*);
|
||||||
void free_path_buffer(PathBuffer*);
|
void path_buffer_free(PathBuffer*);
|
||||||
char* find_root(char*);
|
char* find_root(char*);
|
||||||
void walk(char*, char*, char*, PathBuffer*, int, char*);
|
void walk(char*, char*, char*, PathBuffer*, int, char*);
|
||||||
void save_tree(const char*, PathBuffer*);
|
void save_tree(PathBuffer*);
|
||||||
|
|
||||||
#endif // TREE_H
|
#endif // TREE_H
|
||||||
|
|
|
||||||
94
src/tree.c
94
src/tree.c
|
|
@ -1,43 +1,16 @@
|
||||||
#include "tree.h"
|
#include "tree.h"
|
||||||
|
|
||||||
PathBuffer* new_path_buffer() {
|
PathBuffer* path_buffer_new() {
|
||||||
PathBuffer* buffer = calloc(1, sizeof(PathBuffer));
|
return list_new(sizeof(char*));
|
||||||
if (!buffer) {
|
|
||||||
perror("ERROR: Failed to allocate PathBuffer");
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
buffer->capacity = 10;
|
|
||||||
buffer->len = 0;
|
|
||||||
|
|
||||||
buffer->paths = calloc(buffer->capacity, sizeof(char*));
|
|
||||||
if (!buffer->paths) {
|
|
||||||
perror("ERROR: Failed to allocate paths array");
|
|
||||||
free(buffer);
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
return buffer;
|
|
||||||
}
|
|
||||||
|
|
||||||
void add_path(PathBuffer* buffer, char* path) {
|
|
||||||
if (buffer->len >= buffer->capacity) {
|
|
||||||
buffer->capacity *= 2;
|
|
||||||
char** new_paths = realloc(buffer->paths, buffer->capacity * sizeof(char*));
|
|
||||||
if (!new_paths) {
|
|
||||||
perror("ERROR: PathBuffer realloc failed!");
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
buffer->paths = new_paths;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void path_buffer_push(PathBuffer* buffer, char* path) {
|
||||||
char* path_copy = strdup(path);
|
char* path_copy = strdup(path);
|
||||||
if (!path_copy) {
|
if (!path_copy) {
|
||||||
perror("ERROR: strdup failed in add_path!");
|
perror("ERROR: strdup failed in add_path");
|
||||||
exit(1);
|
return;
|
||||||
}
|
}
|
||||||
|
list_push(buffer, &path_copy);
|
||||||
buffer->paths[buffer->len++] = path_copy;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int compare_paths(const void* a, const void* b) {
|
int compare_paths(const void* a, const void* b) {
|
||||||
|
|
@ -46,20 +19,20 @@ int compare_paths(const void* a, const void* b) {
|
||||||
return strcmp(s1,s2);
|
return strcmp(s1,s2);
|
||||||
}
|
}
|
||||||
|
|
||||||
void sort_path_buffer(PathBuffer* buffer) {
|
void path_buffer_sort(PathBuffer* buffer) {
|
||||||
if (!buffer || buffer->len <= 1) {
|
if (!buffer || buffer->len <= 1) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
qsort(buffer->paths, buffer->len, sizeof(char*), compare_paths);
|
qsort(buffer->items, buffer->len, sizeof(char*), compare_paths);
|
||||||
}
|
}
|
||||||
|
|
||||||
void free_path_buffer(PathBuffer* buffer) {
|
void path_buffer_free(PathBuffer* buffer) {
|
||||||
if (buffer) {
|
if (buffer) {
|
||||||
for (size_t i = 0; i < buffer->len; i++) {
|
for (size_t i = 0; i < buffer->len; i++) {
|
||||||
free(buffer->paths[i]);
|
free(buffer->items[i]);
|
||||||
}
|
}
|
||||||
free(buffer->paths);
|
free(buffer->items);
|
||||||
free(buffer);
|
free(buffer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -238,13 +211,13 @@ void walk(char* base, char* base_rel, char* rel, PathBuffer* paths, int full_rep
|
||||||
|
|
||||||
if (!full_repo_path) {
|
if (!full_repo_path) {
|
||||||
normalize_path(relative_path, base_rel);
|
normalize_path(relative_path, base_rel);
|
||||||
add_path(paths, relative_path);
|
path_buffer_push(paths, relative_path);
|
||||||
free(relative_path);
|
free(relative_path);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
char* real_path = realpath(relative_path, NULL);
|
char* real_path = realpath(relative_path, NULL);
|
||||||
cut_path(repo_root_path, real_path);
|
cut_path(repo_root_path, real_path);
|
||||||
add_path(paths, real_path);
|
path_buffer_push(paths, real_path);
|
||||||
free(relative_path);
|
free(relative_path);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -255,28 +228,53 @@ void walk(char* base, char* base_rel, char* rel, PathBuffer* paths, int full_rep
|
||||||
closedir(dir);
|
closedir(dir);
|
||||||
}
|
}
|
||||||
|
|
||||||
void save_tree(const char* path, PathBuffer* tree) {
|
void save_tree(PathBuffer* tree) {
|
||||||
|
PathBuffer* files = path_buffer_new();
|
||||||
|
char relative[PATH_MAX] = "";
|
||||||
|
char* root = find_root(relative);
|
||||||
|
if (!root) {
|
||||||
|
perror("ERROR: unable to find root directory of the repository!");
|
||||||
|
path_buffer_free(files);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
walk(root, relative, relative, files, 1, root);
|
||||||
|
path_buffer_sort(files);
|
||||||
|
|
||||||
char tmp[1024];
|
char tmp[1024];
|
||||||
size_t offset = 0;
|
size_t offset = 0;
|
||||||
|
|
||||||
FILE* fp = fopen(path, "wb");
|
offset += snprintf(tmp, sizeof(tmp), "%zu:", files->len);
|
||||||
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 < files->len; idx++) {
|
||||||
|
|
||||||
for (size_t idx = 0; idx < tree->len; idx++) {
|
|
||||||
size_t remaining = sizeof(tmp) - offset;
|
size_t remaining = sizeof(tmp) - offset;
|
||||||
|
|
||||||
int written = snprintf(tmp + offset, remaining, "%s:", tree->paths[idx]);
|
int written = snprintf(tmp + offset, remaining, "%s:", files->items[idx]);
|
||||||
if (written < 0 || (size_t)written >= remaining) {
|
if (written < 0 || (size_t)written >= remaining) {
|
||||||
perror("ERROR: buffer overflow in save_tree!\n");
|
perror("ERROR: buffer overflow in save_tree!\n");
|
||||||
fclose(fp);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
offset += (size_t)written;
|
offset += (size_t)written;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
char hash[41];
|
||||||
|
object_hash(TreeObject, tmp, hash);
|
||||||
|
|
||||||
|
printf("hash: %s\n", hash);
|
||||||
|
|
||||||
|
char dir_path[PATH_MAX];
|
||||||
|
char file_path[PATH_MAX];
|
||||||
|
|
||||||
|
snprintf(dir_path, sizeof(dir_path), "%s/.merk/objects/%.2s", root, hash);
|
||||||
|
mkdir(dir_path, 0755);
|
||||||
|
|
||||||
|
snprintf(file_path, sizeof(file_path), "%s/%s", dir_path, hash+2);
|
||||||
|
|
||||||
|
FILE* fp = fopen(file_path, "wb");
|
||||||
|
if (!fp) { perror("ERROR: cannot open path in save_tree!\n"); return; }
|
||||||
|
|
||||||
|
|
||||||
uLong originalLen = strlen(tmp) + 1;
|
uLong originalLen = strlen(tmp) + 1;
|
||||||
|
|
||||||
uLong compressedLen = compressBound(originalLen);
|
uLong compressedLen = compressBound(originalLen);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue