diff options
Diffstat (limited to 'src/Storage.cpp')
-rw-r--r-- | src/Storage.cpp | 31 |
1 files changed, 29 insertions, 2 deletions
diff --git a/src/Storage.cpp b/src/Storage.cpp index c9dfb17..a1dc777 100644 --- a/src/Storage.cpp +++ b/src/Storage.cpp @@ -5,6 +5,8 @@ #include <assert.h> #include <json/reader.h> #include <json/writer.h> +#include <rapidjson/writer.h> +#include <rapidjson/stringbuffer.h> #include <unordered_set> #if OS_FAMILY == OS_FAMILY_POSIX @@ -137,12 +139,12 @@ namespace QuickMedia { return -1; } - int file_overwrite(const Path &path, const std::string &data) { + static int file_overwrite(const Path &path, const char *str, size_t size) { FILE *file = fopen(path.data.c_str(), "wb"); if(!file) return -1; - if(fwrite(data.data(), 1, data.size(), file) != data.size()) { + if(fwrite(str, 1, size, file) != size) { fclose(file); return -1; } @@ -150,6 +152,10 @@ namespace QuickMedia { return fclose(file); } + int file_overwrite(const Path &path, const std::string &data) { + return file_overwrite(path, data.c_str(), data.size()); + } + void for_files_in_dir(const Path &path, FileIteratorCallback callback) { try { for(auto &p : std::filesystem::directory_iterator(path.data)) { @@ -226,6 +232,27 @@ namespace QuickMedia { return true; } + bool save_json_to_file_atomic(const Path &path, const rapidjson::Value &json) { + Path tmp_path = path; + tmp_path.append(".tmp"); + + rapidjson::StringBuffer buffer; + rapidjson::Writer<rapidjson::StringBuffer> writer(buffer); + json.Accept(writer); + + Json::StreamWriterBuilder json_builder; + if(file_overwrite(tmp_path, buffer.GetString(), buffer.GetSize()) != 0) + return false; + + // Rename is atomic under posix! + if(rename(tmp_path.data.c_str(), path.data.c_str()) != 0) { + perror("save_json_to_file_atomic rename"); + return false; + } + + return true; + } + bool is_program_executable_by_name(const char *name) { // TODO: Implement for Windows. Windows also uses semicolon instead of colon as a separator char *env = getenv("PATH"); |