refactor: split up the utilities file into smaller modules

This commit is contained in:
lisk77 2025-09-19 03:48:08 +02:00
parent abaa6e12fc
commit ff71a92249
13 changed files with 572 additions and 488 deletions

117
src/object.c Normal file
View file

@ -0,0 +1,117 @@
#include "object.h"
char* get_object(char* hash, size_t* size_out) {
char dir_path[PATH_MAX];
char repo_path[PATH_MAX];
char file_path[PATH_MAX];
snprintf(dir_path, sizeof(dir_path), ".merk/objects/%.2s", hash);
snprintf(repo_path, sizeof(repo_path), "%s/%s", dir_path, hash+2);
realpath(repo_path, file_path);
size_t compressed_size;
unsigned char* compressed_data = (unsigned char*)get_file_content_with_size(file_path, &compressed_size);
if (!compressed_data || compressed_size == 0) {
free(compressed_data);
return NULL;
}
size_t idx = 0;
while (idx < compressed_size && IS_DIGIT(compressed_data[idx])) {
idx++;
}
if (idx == 0) {
perror("ERROR: no length found at start of object!");
free(compressed_data);
return NULL;
}
char* size_str = calloc(idx + 1, sizeof(char));
if (!size_str) {
free(compressed_data);
return NULL;
}
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 get_object!");
free(size_str);
free(compressed_data);
return NULL;
}
free(size_str);
if (idx < compressed_size && compressed_data[idx] == ' ') {
idx++;
}
char* decompressed = malloc(original_size + 1);
if (!decompressed) {
free(compressed_data);
return NULL;
}
uLongf decompressed_size = original_size;
if (uncompress((Bytef*)decompressed, &decompressed_size, compressed_data + idx, compressed_size - idx) != Z_OK) {
perror("ERROR: decompression failed in get_object!");
free(decompressed);
free(compressed_data);
return NULL;
}
free(compressed_data);
decompressed[decompressed_size] = '\0';
if (size_out) {
*size_out = decompressed_size;
}
return decompressed;
}
void* parse_object(char* hash, ObjectType type, size_t* size_out) {
size_t line_count;
char* content = get_object(hash, &line_count);
if (!content) return NULL;
if (line_count == 0) {
free(content);
return NULL;
}
switch (type) {
case BaseFileObject: {
File* file = from_string(content);
if (!file) {
free(content);
return NULL;
}
free(content);
return file;
}
case TreeObject: {
FileInfoBuffer* buffer = file_info_buffer_new();
if (!buffer) {
free(content);
return NULL;
}
if (read_tree(buffer, hash) < 0) {
file_info_buffer_free(buffer);
free(content);
return NULL;
}
free(content);
return buffer;
}
case FileDiffObject: {
}
default: free(content); return NULL;
}
}