- [WIP] Config files
This commit is contained in:
115
jfile.cpp
115
jfile.cpp
@@ -3,9 +3,18 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include "jfile.h"
|
#include "jfile.h"
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#ifndef _WIN32
|
||||||
|
#include <pwd.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#define DEFAULT_FILENAME "data.jrf"
|
#define DEFAULT_FILENAME "data.jrf"
|
||||||
#define DEFAULT_FOLDER "data/"
|
#define DEFAULT_FOLDER "data/"
|
||||||
|
#define CONFIG_FILENAME "config.txt"
|
||||||
|
|
||||||
#pragma pack(push,1)
|
#pragma pack(push,1)
|
||||||
struct DATA_Header {
|
struct DATA_Header {
|
||||||
@@ -31,11 +40,18 @@ struct DATA_File {
|
|||||||
|
|
||||||
#pragma pack(pop)
|
#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_filename = NULL;
|
||||||
char *resource_folder = NULL;
|
char *resource_folder = NULL;
|
||||||
DATA_File *data_file = NULL;
|
DATA_File *data_file = NULL;
|
||||||
int file_source = SOURCE_FILE;
|
int file_source = SOURCE_FILE;
|
||||||
char scratch[255];
|
char scratch[255];
|
||||||
|
std::string config_folder = NULL;
|
||||||
|
std::vector<keyvalue_t> config;
|
||||||
|
|
||||||
void file_setresourcefilename(const char *str) {
|
void file_setresourcefilename(const char *str) {
|
||||||
if (resource_filename != NULL) free(resource_filename);
|
if (resource_filename != NULL) free(resource_filename);
|
||||||
@@ -121,3 +137,102 @@ char *file_getfilebuffer(const char *resourcename, int& filesize) {
|
|||||||
fclose(f);
|
fclose(f);
|
||||||
return buffer;
|
return buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 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;
|
||||||
|
}
|
||||||
|
|||||||
3
jfile.h
3
jfile.h
@@ -10,3 +10,6 @@ void file_setsource(const int src);
|
|||||||
|
|
||||||
FILE *file_getfilepointer(const char *resourcename, int& filesize, const bool binary=false);
|
FILE *file_getfilepointer(const char *resourcename, int& filesize, const bool binary=false);
|
||||||
char *file_getfilebuffer(const char *resourcename, int& filesize);
|
char *file_getfilebuffer(const char *resourcename, int& filesize);
|
||||||
|
|
||||||
|
const char* file_getconfigvalue(const char *key);
|
||||||
|
void file_setconfigvalue(const char* key, const char* value);
|
||||||
|
|||||||
Reference in New Issue
Block a user