9#include <nlohmann/json.hpp>
13namespace Vkm::Engine::detail {
25inline bool readJsonFile(
const std::filesystem::path& path, nlohmann::json& out,
const char* what) {
26 std::ifstream in(path);
28 LOG_ERROR_C(
"IO",
"%s: cannot open '%s'", what, path.string().c_str());
33 }
catch (
const nlohmann::json::exception& e) {
34 LOG_ERROR_C(
"IO",
"%s: malformed JSON in '%s': %s", what, path.string().c_str(), e.what());
50inline void writeNonFiniteAsZero(nlohmann::json& node,
const char* what, std::string& path) {
51 if (node.is_object()) {
52 const std::size_t parent = path.size();
53 for (
auto& field : node.items()) {
56 writeNonFiniteAsZero(field.value(), what, path);
61 if (node.is_array()) {
62 const std::size_t parent = path.size();
63 for (std::size_t i = 0; i < node.size(); ++i) {
65 path += std::to_string(i);
66 writeNonFiniteAsZero(node[i], what, path);
71 if (!node.is_number_float() || std::isfinite(node.get<
double>()))
return;
73 LOG_WARNING_C(
"IO",
"%s: %s is not a finite number; written as 0", what, path.c_str());
83inline void writeNonFiniteAsZero(nlohmann::json& doc,
const char* what) {
85 writeNonFiniteAsZero(doc, what, path);
99inline bool writeJsonFile(
const std::filesystem::path& path, nlohmann::json& doc,
const char* what) {
100 writeNonFiniteAsZero(doc, what);
103 if (!path.parent_path().empty()) std::filesystem::create_directories(path.parent_path(), ec);
105 const std::filesystem::path tmp = std::filesystem::path(path).concat(
".tmp");
107 std::ofstream out(tmp);
109 LOG_ERROR_C(
"IO",
"%s: cannot open '%s' for writing", what, tmp.string().c_str());
113 out << doc.dump(2) <<
'\n';
116 LOG_ERROR_C(
"IO",
"%s: write to '%s' failed", what, tmp.string().c_str());
117 std::filesystem::remove(tmp, ec);
121 std::filesystem::rename(tmp, path, ec);
125 "%s: rename '%s' -> '%s' failed: %s",
127 tmp.string().c_str(),
128 path.string().c_str(),
131 std::filesystem::remove(tmp, ec);