Add file wrapper
This commit is contained in:
parent
46389de61f
commit
d4e6d72a18
|
@ -16,7 +16,7 @@ set(INCLUDES "")
|
||||||
set(SOURCES "")
|
set(SOURCES "")
|
||||||
set(IMGUI_SOURCES "")
|
set(IMGUI_SOURCES "")
|
||||||
set(DEFINITIONS "")
|
set(DEFINITIONS "")
|
||||||
# imgui include because <GH ISSUE LINK HERE>
|
# imgui include because https://github.com/ocornut/imgui/issues/6184#issuecomment-1439570929
|
||||||
list(APPEND INCLUDES thirdparty thirdparty/imgui /usr/include/SDL2)
|
list(APPEND INCLUDES thirdparty thirdparty/imgui /usr/include/SDL2)
|
||||||
list(APPEND SOURCES main.cpp event_loop.cpp logcat_thread.cpp logcat_entry.cpp log.cpp config.cpp filters.cpp misc.cpp pcre2_wrapper.cpp
|
list(APPEND SOURCES main.cpp event_loop.cpp logcat_thread.cpp logcat_entry.cpp log.cpp config.cpp filters.cpp misc.cpp pcre2_wrapper.cpp
|
||||||
group_panel.cpp fragments/filters.cpp windows/logs.cpp windows/settings.cpp windows/main.cpp)
|
group_panel.cpp fragments/filters.cpp windows/logs.cpp windows/settings.cpp windows/main.cpp)
|
||||||
|
|
39
config.cpp
39
config.cpp
|
@ -1,29 +1,13 @@
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
#include <cstring>
|
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <nlohmann/json.hpp>
|
#include <nlohmann/json.hpp>
|
||||||
|
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
|
#include "file.h"
|
||||||
#include "misc.h"
|
#include "misc.h"
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
|
||||||
static FILE* fopen_or_raise(const char* __restrict path, const char* __restrict mode, bool ignore_enoent) {
|
|
||||||
FILE* file = fopen(path, mode);
|
|
||||||
if (!file && !(ignore_enoent && errno == ENOENT)) {
|
|
||||||
throw_system_error(std::string("fopen(") + quote(path) + ')');
|
|
||||||
}
|
|
||||||
return file;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void fclose_and_log(FILE* file) {
|
|
||||||
if (!fclose(file)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
log(std::string("Failed to close a file: fclose(): ") + strerror(errno));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
std::string get_config_folder() {
|
std::string get_config_folder() {
|
||||||
const char* path;
|
const char* path;
|
||||||
|
|
||||||
|
@ -76,13 +60,15 @@ void from_json(const nlohmann::json& j, Config& config) {
|
||||||
|
|
||||||
Config load_config() {
|
Config load_config() {
|
||||||
std::string config_file_path = get_config_file_path();
|
std::string config_file_path = get_config_file_path();
|
||||||
std::unique_ptr<FILE, decltype(&fclose_and_log)> config_file(fopen_or_raise(config_file_path.c_str(), "r", true), fclose_and_log);
|
try {
|
||||||
|
File config_file(config_file_path.c_str(), "r");
|
||||||
if (!config_file) {
|
return nlohmann::json::parse(config_file.get());
|
||||||
|
} catch (const std::system_error& e) {
|
||||||
|
if (e.code().value() != ENOENT) {
|
||||||
|
throw;
|
||||||
|
}
|
||||||
return Config();
|
return Config();
|
||||||
}
|
}
|
||||||
|
|
||||||
return nlohmann::json::parse(config_file.get()).get<Config>();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -98,10 +84,11 @@ void write_config(const Config& config) {
|
||||||
std::string config_file_path = get_config_file_path();
|
std::string config_file_path = get_config_file_path();
|
||||||
std::string tmp_config_file_path = config_file_path + ".tmp";
|
std::string tmp_config_file_path = config_file_path + ".tmp";
|
||||||
|
|
||||||
std::unique_ptr<FILE, decltype(&fclose_and_log)> config_file(fopen_or_raise(tmp_config_file_path.c_str(), "w", false), fclose_and_log);
|
{
|
||||||
std::string str_config = nlohmann::json(config).dump(4);
|
File config_file(tmp_config_file_path.c_str(), "w");
|
||||||
fwrite(str_config.data(), sizeof(char), str_config.size(), config_file.get());
|
std::string str_config = nlohmann::json(config).dump(4);
|
||||||
config_file.reset();
|
config_file.write(std::move(str_config));
|
||||||
|
}
|
||||||
|
|
||||||
if (!rename(tmp_config_file_path.c_str(), config_file_path.c_str())) {
|
if (!rename(tmp_config_file_path.c_str(), config_file_path.c_str())) {
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -0,0 +1,65 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <cstdio>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include "../log.h"
|
||||||
|
#include "../misc.h"
|
||||||
|
|
||||||
|
static void try_close(FILE* file);
|
||||||
|
|
||||||
|
// Not usable for logcat thread!
|
||||||
|
class File {
|
||||||
|
public:
|
||||||
|
// https://stackoverflow.com/a/2173764
|
||||||
|
File(const File&) = delete;
|
||||||
|
File& operator=(const File&) = delete;
|
||||||
|
|
||||||
|
inline constexpr File(File&& other) {
|
||||||
|
try_close(this->_file);
|
||||||
|
this->_file = other._file;
|
||||||
|
other._file = nullptr;
|
||||||
|
}
|
||||||
|
inline constexpr File& operator=(File&& other) {
|
||||||
|
if (this == &other) {
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
try_close(this->_file);
|
||||||
|
this->_file = other._file;
|
||||||
|
other._file = nullptr;
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
File(const char* __restrict path, const char* __restrict mode) {
|
||||||
|
this->_file = fopen(path, mode);
|
||||||
|
if (!this->_file) {
|
||||||
|
throw_system_error(std::string("fopen(") + quote(path) + ')');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
~File() {
|
||||||
|
try_close(this->_file);
|
||||||
|
}
|
||||||
|
|
||||||
|
void write(const char* data, size_t length) {
|
||||||
|
if (fwrite(data, 1, length, this->_file) != length) {
|
||||||
|
throw_system_error("fwrite()");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
inline constexpr void write(const std::string& str) {
|
||||||
|
this->write(str.data(), str.size());
|
||||||
|
}
|
||||||
|
inline constexpr FILE* get() const noexcept {
|
||||||
|
return this->_file;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
FILE* _file = nullptr;
|
||||||
|
};
|
||||||
|
|
||||||
|
static void try_close(FILE* file) {
|
||||||
|
if (file && fclose(file)) {
|
||||||
|
log(std::string("Failed to close a file: fclose(): ") + strerror(errno));
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue