~ruther/CTU-FEE-B0B35APO-Semestral-project

048f9332ea3414af925e10e41c5bec34cc95c3bd — František Boháček 3 years ago 57bf90d
feat: add mime type options
2 files changed, 167 insertions(+), 0 deletions(-)

A file-browser/include/options.h
A file-browser/src/options.c
A file-browser/include/options.h => file-browser/include/options.h +31 -0
@@ 0,0 1,31 @@
#include "file_access.h"
#include <stdint.h>
#include <stdlib.h>

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);

A file-browser/src/options.c => file-browser/src/options.c +136 -0
@@ 0,0 1,136 @@
#include "options.h"
#include "file_access.h"
#include <bits/stdint-uintn.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>

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;
}

Do not follow this link