From 4c0cf979d3d3ab922689431a47501e3f2219e345 Mon Sep 17 00:00:00 2001 From: JailDoctor Date: Tue, 17 Jan 2023 20:04:01 +0100 Subject: [PATCH] - [WIP] Config files --- jfile.cpp | 117 +++++++++++++++++++++++++++++++++++++++++++++++++++++- jfile.h | 3 ++ 2 files changed, 119 insertions(+), 1 deletion(-) diff --git a/jfile.cpp b/jfile.cpp index 94f5df1..56fdfae 100644 --- a/jfile.cpp +++ b/jfile.cpp @@ -3,9 +3,18 @@ #include #include #include "jfile.h" +#include +#include +#include +#include + +#ifndef _WIN32 +#include +#endif #define DEFAULT_FILENAME "data.jrf" #define DEFAULT_FOLDER "data/" +#define CONFIG_FILENAME "config.txt" #pragma pack(push,1) struct DATA_Header { @@ -31,11 +40,18 @@ struct DATA_File { #pragma pack(pop) +/* El std::map me fa coses rares, vaig a usar un good old std::vector amb una estructura key,value propia i au, que sempre funciona */ +struct keyvalue_t { + std::string key, value; +}; + char *resource_filename = NULL; char *resource_folder = NULL; DATA_File *data_file = NULL; int file_source = SOURCE_FILE; char scratch[255]; +std::string config_folder = NULL; +std::vector config; void file_setresourcefilename(const char *str) { if (resource_filename != NULL) free(resource_filename); @@ -120,4 +136,103 @@ char *file_getfilebuffer(const char *resourcename, int& filesize) { fread(buffer, filesize, 1, f); fclose(f); return buffer; -} \ No newline at end of file +} + +// Crea la carpeta del sistema donde guardar datos +void createSystemFolder(const char *foldername) +{ +#ifdef _WIN32 + config_folder = std::string(getenv("APPDATA")) + "/" + foldername; +#elif __APPLE__ + struct passwd *pw = getpwuid(getuid()); + const char *homedir = pw->pw_dir; + config_folder = std::string(homedir) + "/Library/Application Support/" + foldername; +#elif __linux__ + struct passwd *pw = getpwuid(getuid()); + const char *homedir = pw->pw_dir; + config_folder = std::string(homedir) + "/." + foldername; +#endif + + struct stat st = {0}; + if (stat(config_folder.c_str(), &st) == -1) + { + errno = 0; +#ifdef _WIN32 + int ret = mkdir(config_folder.c_str()); +#else + int ret = mkdir(config_folder.c_str(), S_IRWXU); +#endif + + if (ret == -1) + { + switch (errno) + { + case EACCES: + printf("the parent directory does not allow write"); + exit(EXIT_FAILURE); + + case EEXIST: + printf("pathname already exists"); + exit(EXIT_FAILURE); + + case ENAMETOOLONG: + printf("pathname is too long"); + exit(EXIT_FAILURE); + + default: + perror("mkdir"); + exit(EXIT_FAILURE); + } + } + } +} + +void file_loadconfigvalues() { + config.clear(); + std::string config_file = config_folder + "/config.txt"; + FILE *f = fopen(config_file.c_str(), "r"); + if (f) { + while (!feof(f)) { + char key[100], value[100]; + fscanf(f, "%s = %S", key, value); + config.push_back({key, value}); + } + fclose(f); + } +} + +void file_saveconfigvalues() { + std::string config_file = config_folder + "/config.txt"; + FILE *f = fopen(config_file.c_str(), "w"); + if (f) { + for (auto pair : config) { + fprintf(f, "%s = %s\n", pair.key.c_str(), pair.value.c_str()); + } + fclose(f); + } +} + +const char* file_getconfigvalue(const char *key) { + if (config.empty()) file_loadconfigvalues(); + for (auto pair : config) { + if (pair.key == std::string(key)) { + strcpy(scratch, pair.value.c_str()); + return scratch; + } + } + return NULL; +} + +void file_setconfigvalue(const char* key, const char* value) { + if (config.empty()) file_loadconfigvalues(); + for (auto pair : config) { + if (pair.key == std::string(key)) { + pair.value = value; + file_saveconfigvalues(); + return; + } + } + config.push_back({key, value}); + file_saveconfigvalues(); + return; +} diff --git a/jfile.h b/jfile.h index 3c6f765..22b93f1 100644 --- a/jfile.h +++ b/jfile.h @@ -10,3 +10,6 @@ void file_setsource(const int src); FILE *file_getfilepointer(const char *resourcename, int& filesize, const bool binary=false); char *file_getfilebuffer(const char *resourcename, int& filesize); + +const char* file_getconfigvalue(const char *key); +void file_setconfigvalue(const char* key, const char* value);