/***************************************************************************** * Copyright (c) 2014-2025 OpenRCT2 developers * * For a complete list of all authors, please refer to contributors.md * Interested in contributing? Visit https://github.com/OpenRCT2/OpenRCT2 * * OpenRCT2 is licensed under the GNU General Public License version 3. *****************************************************************************/ #include "Json.hpp" #include "../Diagnostic.h" #include "FileStream.h" #include "Memory.hpp" #include "String.hpp" namespace OpenRCT2::Json { json_t ReadFromFile(u8string_view path, size_t maxSize) { auto fs = OpenRCT2::FileStream(path, OpenRCT2::FileMode::open); size_t fileLength = static_cast(fs.GetLength()); if (fileLength > maxSize) { throw IOException("Json file too large."); } auto fileData = std::string(static_cast(fileLength) + 1, '\0'); fs.Read(static_cast(fileData.data()), fileLength); json_t json; try { json = json_t::parse(fileData, /* callback */ nullptr, /* allow_exceptions */ true, /* ignore_comments */ true); } catch (const json_t::exception& e) { throw JsonException( String::stdFormat( "Unable to parse JSON file (%.*s)\n\t%s", static_cast(path.length()), path.data(), e.what())); } return json; } void WriteToFile(u8string_view path, const json_t& jsonData, int indentSize) { // Serialise JSON std::string jsonOutput = jsonData.dump(indentSize); // Write to file auto fs = OpenRCT2::FileStream(path, OpenRCT2::FileMode::write); fs.Write(jsonOutput.data(), jsonOutput.size()); } json_t FromString(std::string_view raw) { json_t json; try { json = json_t::parse(raw, /* callback */ nullptr, /* allow_exceptions */ true, /* ignore_comments */ true); } catch (const json_t::exception& e) { LOG_ERROR("Unable to parse JSON string (%.*s)\n\t%s", static_cast(raw.length()), raw.data(), e.what()); } return json; } json_t FromVector(const std::vector& vec) { json_t json; try { json = json_t::parse( vec.begin(), vec.end(), /* callback */ nullptr, /* allow_exceptions */ true, /* ignore_comments */ true); } catch (const json_t::exception& e) { LOG_ERROR("Unable to parse JSON vector (%.*s)\n\t%s", static_cast(vec.size()), vec.data(), e.what()); } return json; } std::string GetString(const json_t& jsonObj, const std::string& defaultValue) { return jsonObj.is_string() ? jsonObj.get() : defaultValue; } bool GetBoolean(const json_t& jsonObj, bool defaultValue) { return jsonObj.is_boolean() ? jsonObj.get() : defaultValue; } json_t AsObject(const json_t& jsonObj) { return jsonObj.is_object() ? jsonObj : json_t::object(); } json_t AsArray(const json_t& jsonObj) { if (jsonObj.is_array()) { return jsonObj; } json_t retVal = json_t::array(); if (jsonObj.is_object()) { for (const auto& jItem : jsonObj) { retVal.push_back(jItem); } } else if (!jsonObj.is_null()) { retVal.push_back(jsonObj); } return retVal; } } // namespace OpenRCT2::Json