From 048f9332ea3414af925e10e41c5bec34cc95c3bd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Franti=C5=A1ek=20Boh=C3=A1=C4=8Dek?= Date: Thu, 24 Jun 2021 09:31:47 +0200 Subject: [PATCH] feat: add mime type options --- file-browser/include/options.h | 31 ++++++++ file-browser/src/options.c | 136 +++++++++++++++++++++++++++++++++ 2 files changed, 167 insertions(+) create mode 100644 file-browser/include/options.h create mode 100644 file-browser/src/options.c diff --git a/file-browser/include/options.h b/file-browser/include/options.h new file mode 100644 index 0000000..b69983b --- /dev/null +++ b/file-browser/include/options.h @@ -0,0 +1,31 @@ +#include "file_access.h" +#include +#include + +typedef struct { + uint16_t length; + uint16_t mime_length; + uint16_t program_length; + char *mime; + char *program; +} __attribute__((__packed__)) exec_option_t; + +typedef struct { + uint32_t bytes_size; + uint16_t options_count; + exec_option_t *options; +} __attribute__((__packed__)) exec_options_t; + +typedef struct { + char *options_filename; + uint32_t bytes_size; + exec_options_t *exec_options; +} exec_options_loader_t; + +exec_options_loader_t exec_options_loader_create(char *filename); + +file_operation_error_t exec_options_loader_get_size(exec_options_loader_t *loader); +file_operation_error_t exec_options_loader_load(exec_options_loader_t *loader, char *buffer); + +file_operation_error_t exec_options_save(exec_options_t *options, char *filename); +char *exec_options_get_program(exec_options_t *options, char *mime); diff --git a/file-browser/src/options.c b/file-browser/src/options.c new file mode 100644 index 0000000..db373cb --- /dev/null +++ b/file-browser/src/options.c @@ -0,0 +1,136 @@ +#include "options.h" +#include "file_access.h" +#include +#include +#include +#include + +exec_options_loader_t exec_options_loader_create(char *filename) { + exec_options_loader_t loader = { + .options_filename = filename, + .bytes_size = 0, + .exec_options = NULL, + }; + + return loader; +} + +file_operation_error_t exec_options_loader_get_size(exec_options_loader_t *loader) { + FILE *file = fopen(loader->options_filename, "r"); + if (file == NULL) { + return file_operation_error_from_errno(errno); + } + int read = fread(&loader->bytes_size, sizeof(loader->bytes_size), 1, file); + if (read < 1 && ferror(file)) { + fclose(file); + return file_operation_error_from_errno(errno); + } + + fclose(file); + return FILOPER_SUCCESS; +} + +file_operation_error_t exec_options_loader_load(exec_options_loader_t *loader, + char *buffer) { + FILE *file = fopen(loader->options_filename, "r"); + if (file == NULL) { + return file_operation_error_from_errno(errno); + } + + fread(buffer, sizeof(char), loader->bytes_size, file); + + if (ferror(file)) { + fclose(file); + return file_operation_error_from_errno(errno); + } + + fclose(file); + loader->exec_options = (exec_options_t*)buffer; + + uint64_t buffer_ptr = (uint64_t)buffer; + loader->exec_options->options += buffer_ptr; + + for (int i = 0; i < loader->exec_options->options_count; i++) { + exec_option_t option = loader->exec_options->options[i]; + + option.mime += buffer_ptr; + option.program += buffer_ptr; + loader->exec_options->options[i] = option; + } + + return FILOPER_SUCCESS; +} + +file_operation_error_t exec_options_save(exec_options_t *options, char *filename) { + uint32_t length = sizeof(uint32_t); + for (int i = 0; i < options->options_count; i++) { + exec_option_t option = options->options[i]; + option.mime_length = strlen(option.mime); + option.program_length = strlen(option.program); + option.length = (option.mime_length + option.program_length) * sizeof(char) + + sizeof(uint16_t) * 2; + length += option.length; + + options->options[i] = option; + } + options->bytes_size = length; + + FILE *file = fopen(filename, "w"); + if (file == NULL) { + return file_operation_error_from_errno(errno); + } + + fwrite(&options->bytes_size, sizeof(options->bytes_size), 1, file); + fwrite(&options->options_count, sizeof(options->options_count), 1, file); + + uint64_t offset = 1; + fwrite(&offset, sizeof(offset), 1, file); + + if (ferror(file)) { + fclose(file); + return file_operation_error_from_errno(errno); + } + + uint64_t chars_offset = sizeof(exec_option_t) * options->options_count; + file_operation_error_t error = FILOPER_SUCCESS; + for (int i = 0; i < options->options_count; i++) { + exec_option_t option = options->options[i]; + fwrite(&option, sizeof(option.mime_length) + sizeof(option.length) + sizeof(option.program_length), 1, file); + + fwrite(&chars_offset, sizeof(chars_offset), 1, file); + chars_offset += option.program_length + 1; + + fwrite(&chars_offset, sizeof(chars_offset), 1, file); + chars_offset += option.mime_length + 1; + + if (ferror(file)) { + fclose(file); + return file_operation_error_from_errno(errno); + } + } + + for (int i = 0; i < options->options_count; i++) { + exec_option_t option = options->options[i]; + fwrite(option.program, option.program_length + 1, 1, file); + fwrite(option.mime, option.mime_length + 1, 1, file); + + if (ferror(file)) { + fclose(file); + return file_operation_error_from_errno(errno); + } + } + + fclose(file); + return error; +} + +char *exec_options_get_program(exec_options_t *options, char *mime) { + for (int i = 0; i < options->options_count; i++) { + exec_option_t option = options->options[i]; + if (strcmp(option.mime, mime) == 0) { + return option.program; + } + } + + return NULL; +} -- 2.48.1