mirror of
https://github.com/ciphervance/supercell-wx.git
synced 2025-10-30 17:20:04 +00:00
Refactor json utility to wxdata, add ReadJsonString function
This commit is contained in:
parent
895e760fee
commit
9f33189c18
12 changed files with 245 additions and 228 deletions
|
|
@ -245,7 +245,7 @@ size_t RadarSite::ReadConfig(const std::string& path)
|
||||||
bool dataValid = true;
|
bool dataValid = true;
|
||||||
size_t sitesAdded = 0;
|
size_t sitesAdded = 0;
|
||||||
|
|
||||||
boost::json::value j = util::json::ReadJsonFile(path);
|
boost::json::value j = util::json::ReadJsonQFile(path);
|
||||||
|
|
||||||
dataValid = j.is_array();
|
dataValid = j.is_array();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,10 @@
|
||||||
#include <scwx/qt/manager/marker_manager.hpp>
|
#include <scwx/qt/manager/marker_manager.hpp>
|
||||||
#include <scwx/qt/types/marker_types.hpp>
|
#include <scwx/qt/types/marker_types.hpp>
|
||||||
#include <scwx/qt/util/color.hpp>
|
#include <scwx/qt/util/color.hpp>
|
||||||
#include <scwx/qt/util/json.hpp>
|
|
||||||
#include <scwx/qt/util/texture_atlas.hpp>
|
#include <scwx/qt/util/texture_atlas.hpp>
|
||||||
#include <scwx/qt/main/application.hpp>
|
#include <scwx/qt/main/application.hpp>
|
||||||
#include <scwx/qt/manager/resource_manager.hpp>
|
#include <scwx/qt/manager/resource_manager.hpp>
|
||||||
|
#include <scwx/util/json.hpp>
|
||||||
#include <scwx/util/logger.hpp>
|
#include <scwx/util/logger.hpp>
|
||||||
|
|
||||||
#include <filesystem>
|
#include <filesystem>
|
||||||
|
|
@ -62,7 +62,7 @@ public:
|
||||||
|
|
||||||
bool markerFileRead_ {false};
|
bool markerFileRead_ {false};
|
||||||
|
|
||||||
void InitalizeIds();
|
void InitalizeIds();
|
||||||
types::MarkerId NewId();
|
types::MarkerId NewId();
|
||||||
types::MarkerId lastId_ {0};
|
types::MarkerId lastId_ {0};
|
||||||
};
|
};
|
||||||
|
|
@ -70,15 +70,9 @@ public:
|
||||||
class MarkerManager::Impl::MarkerRecord
|
class MarkerManager::Impl::MarkerRecord
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
MarkerRecord(const types::MarkerInfo& info) :
|
MarkerRecord(const types::MarkerInfo& info) : markerInfo_ {info} {}
|
||||||
markerInfo_ {info}
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
const types::MarkerInfo& toMarkerInfo()
|
const types::MarkerInfo& toMarkerInfo() { return markerInfo_; }
|
||||||
{
|
|
||||||
return markerInfo_;
|
|
||||||
}
|
|
||||||
|
|
||||||
types::MarkerInfo markerInfo_;
|
types::MarkerInfo markerInfo_;
|
||||||
|
|
||||||
|
|
@ -175,7 +169,7 @@ void MarkerManager::Impl::ReadMarkerSettings()
|
||||||
// Determine if marker settings exists
|
// Determine if marker settings exists
|
||||||
if (std::filesystem::exists(markerSettingsPath_))
|
if (std::filesystem::exists(markerSettingsPath_))
|
||||||
{
|
{
|
||||||
markerJson = util::json::ReadJsonFile(markerSettingsPath_);
|
markerJson = scwx::util::json::ReadJsonFile(markerSettingsPath_);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (markerJson != nullptr && markerJson.is_array())
|
if (markerJson != nullptr && markerJson.is_array())
|
||||||
|
|
@ -224,8 +218,8 @@ void MarkerManager::Impl::WriteMarkerSettings()
|
||||||
logger_->info("Saving location marker settings");
|
logger_->info("Saving location marker settings");
|
||||||
|
|
||||||
const std::shared_lock lock(markerRecordLock_);
|
const std::shared_lock lock(markerRecordLock_);
|
||||||
auto markerJson = boost::json::value_from(markerRecords_);
|
auto markerJson = boost::json::value_from(markerRecords_);
|
||||||
util::json::WriteJsonFile(markerSettingsPath_, markerJson);
|
scwx::util::json::WriteJsonFile(markerSettingsPath_, markerJson);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<MarkerManager::Impl::MarkerRecord>
|
std::shared_ptr<MarkerManager::Impl::MarkerRecord>
|
||||||
|
|
@ -357,10 +351,11 @@ types::MarkerId MarkerManager::add_marker(const types::MarkerInfo& marker)
|
||||||
types::MarkerId id;
|
types::MarkerId id;
|
||||||
{
|
{
|
||||||
const std::unique_lock lock(p->markerRecordLock_);
|
const std::unique_lock lock(p->markerRecordLock_);
|
||||||
id = p->NewId();
|
id = p->NewId();
|
||||||
size_t index = p->markerRecords_.size();
|
size_t index = p->markerRecords_.size();
|
||||||
p->idToIndex_.emplace(id, index);
|
p->idToIndex_.emplace(id, index);
|
||||||
p->markerRecords_.emplace_back(std::make_shared<Impl::MarkerRecord>(marker));
|
p->markerRecords_.emplace_back(
|
||||||
|
std::make_shared<Impl::MarkerRecord>(marker));
|
||||||
p->markerRecords_[index]->markerInfo_.id = id;
|
p->markerRecords_[index]->markerInfo_.id = id;
|
||||||
|
|
||||||
add_icon(marker.iconName);
|
add_icon(marker.iconName);
|
||||||
|
|
@ -499,7 +494,6 @@ void MarkerManager::set_marker_settings_path(const std::string& path)
|
||||||
p->markerSettingsPath_ = path;
|
p->markerSettingsPath_ = path;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
std::shared_ptr<MarkerManager> MarkerManager::Instance()
|
std::shared_ptr<MarkerManager> MarkerManager::Instance()
|
||||||
{
|
{
|
||||||
static std::weak_ptr<MarkerManager> markerManagerReference_ {};
|
static std::weak_ptr<MarkerManager> markerManagerReference_ {};
|
||||||
|
|
|
||||||
|
|
@ -2,10 +2,10 @@
|
||||||
#include <scwx/qt/manager/font_manager.hpp>
|
#include <scwx/qt/manager/font_manager.hpp>
|
||||||
#include <scwx/qt/manager/resource_manager.hpp>
|
#include <scwx/qt/manager/resource_manager.hpp>
|
||||||
#include <scwx/qt/main/application.hpp>
|
#include <scwx/qt/main/application.hpp>
|
||||||
#include <scwx/qt/util/json.hpp>
|
|
||||||
#include <scwx/qt/util/network.hpp>
|
#include <scwx/qt/util/network.hpp>
|
||||||
#include <scwx/gr/placefile.hpp>
|
#include <scwx/gr/placefile.hpp>
|
||||||
#include <scwx/network/cpr.hpp>
|
#include <scwx/network/cpr.hpp>
|
||||||
|
#include <scwx/util/json.hpp>
|
||||||
#include <scwx/util/logger.hpp>
|
#include <scwx/util/logger.hpp>
|
||||||
|
|
||||||
#include <shared_mutex>
|
#include <shared_mutex>
|
||||||
|
|
@ -385,7 +385,7 @@ void PlacefileManager::Impl::ReadPlacefileSettings()
|
||||||
// Determine if placefile settings exists
|
// Determine if placefile settings exists
|
||||||
if (std::filesystem::exists(placefileSettingsPath_))
|
if (std::filesystem::exists(placefileSettingsPath_))
|
||||||
{
|
{
|
||||||
placefileJson = util::json::ReadJsonFile(placefileSettingsPath_);
|
placefileJson = scwx::util::json::ReadJsonFile(placefileSettingsPath_);
|
||||||
}
|
}
|
||||||
|
|
||||||
// If placefile settings was successfully read
|
// If placefile settings was successfully read
|
||||||
|
|
@ -428,7 +428,7 @@ void PlacefileManager::Impl::WritePlacefileSettings()
|
||||||
|
|
||||||
std::shared_lock lock {placefileRecordLock_};
|
std::shared_lock lock {placefileRecordLock_};
|
||||||
auto placefileJson = boost::json::value_from(placefileRecords_);
|
auto placefileJson = boost::json::value_from(placefileRecords_);
|
||||||
util::json::WriteJsonFile(placefileSettingsPath_, placefileJson);
|
scwx::util::json::WriteJsonFile(placefileSettingsPath_, placefileJson);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PlacefileManager::SetRadarSite(
|
void PlacefileManager::SetRadarSite(
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@
|
||||||
#include <scwx/qt/settings/text_settings.hpp>
|
#include <scwx/qt/settings/text_settings.hpp>
|
||||||
#include <scwx/qt/settings/ui_settings.hpp>
|
#include <scwx/qt/settings/ui_settings.hpp>
|
||||||
#include <scwx/qt/settings/unit_settings.hpp>
|
#include <scwx/qt/settings/unit_settings.hpp>
|
||||||
#include <scwx/qt/util/json.hpp>
|
#include <scwx/util/json.hpp>
|
||||||
#include <scwx/util/logger.hpp>
|
#include <scwx/util/logger.hpp>
|
||||||
|
|
||||||
#include <filesystem>
|
#include <filesystem>
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
#include <scwx/qt/manager/update_manager.hpp>
|
#include <scwx/qt/manager/update_manager.hpp>
|
||||||
|
#include <scwx/util/json.hpp>
|
||||||
#include <scwx/util/logger.hpp>
|
#include <scwx/util/logger.hpp>
|
||||||
|
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
|
|
@ -29,8 +30,7 @@ public:
|
||||||
|
|
||||||
~Impl() {}
|
~Impl() {}
|
||||||
|
|
||||||
static std::string GetVersionString(const std::string& releaseName);
|
static std::string GetVersionString(const std::string& releaseName);
|
||||||
static boost::json::value ParseResponseText(const std::string& s);
|
|
||||||
|
|
||||||
size_t PopulateReleases();
|
size_t PopulateReleases();
|
||||||
size_t AddReleases(const boost::json::value& json);
|
size_t AddReleases(const boost::json::value& json);
|
||||||
|
|
@ -70,28 +70,6 @@ UpdateManager::Impl::GetVersionString(const std::string& releaseName)
|
||||||
return versionString;
|
return versionString;
|
||||||
}
|
}
|
||||||
|
|
||||||
boost::json::value UpdateManager::Impl::ParseResponseText(const std::string& s)
|
|
||||||
{
|
|
||||||
boost::json::stream_parser p;
|
|
||||||
boost::system::error_code ec;
|
|
||||||
|
|
||||||
p.write(s, ec);
|
|
||||||
if (ec)
|
|
||||||
{
|
|
||||||
logger_->warn("{}", ec.message());
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
p.finish(ec);
|
|
||||||
if (ec)
|
|
||||||
{
|
|
||||||
logger_->warn("{}", ec.message());
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
return p.release();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool UpdateManager::CheckForUpdates(const std::string& currentVersion)
|
bool UpdateManager::CheckForUpdates(const std::string& currentVersion)
|
||||||
{
|
{
|
||||||
std::unique_lock lock(p->updateMutex_);
|
std::unique_lock lock(p->updateMutex_);
|
||||||
|
|
@ -148,7 +126,7 @@ size_t UpdateManager::Impl::PopulateReleases()
|
||||||
// Successful REST API query
|
// Successful REST API query
|
||||||
if (r.status_code == 200)
|
if (r.status_code == 200)
|
||||||
{
|
{
|
||||||
boost::json::value json = Impl::ParseResponseText(r.text);
|
boost::json::value json = util::json::ReadJsonString(r.text);
|
||||||
if (json == nullptr)
|
if (json == nullptr)
|
||||||
{
|
{
|
||||||
logger_->warn("Response not JSON: {}", r.header["content-type"]);
|
logger_->warn("Response not JSON: {}", r.header["content-type"]);
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
#include <scwx/qt/model/layer_model.hpp>
|
#include <scwx/qt/model/layer_model.hpp>
|
||||||
#include <scwx/qt/manager/placefile_manager.hpp>
|
#include <scwx/qt/manager/placefile_manager.hpp>
|
||||||
#include <scwx/qt/types/qt_types.hpp>
|
#include <scwx/qt/types/qt_types.hpp>
|
||||||
#include <scwx/qt/util/json.hpp>
|
#include <scwx/util/json.hpp>
|
||||||
#include <scwx/util/logger.hpp>
|
#include <scwx/util/logger.hpp>
|
||||||
|
|
||||||
#include <filesystem>
|
#include <filesystem>
|
||||||
|
|
|
||||||
|
|
@ -4,8 +4,8 @@
|
||||||
#include <scwx/qt/types/qt_types.hpp>
|
#include <scwx/qt/types/qt_types.hpp>
|
||||||
#include <scwx/qt/types/unit_types.hpp>
|
#include <scwx/qt/types/unit_types.hpp>
|
||||||
#include <scwx/qt/util/geographic_lib.hpp>
|
#include <scwx/qt/util/geographic_lib.hpp>
|
||||||
#include <scwx/qt/util/json.hpp>
|
|
||||||
#include <scwx/common/geographic.hpp>
|
#include <scwx/common/geographic.hpp>
|
||||||
|
#include <scwx/util/json.hpp>
|
||||||
#include <scwx/util/logger.hpp>
|
#include <scwx/util/logger.hpp>
|
||||||
|
|
||||||
#include <filesystem>
|
#include <filesystem>
|
||||||
|
|
@ -117,7 +117,7 @@ void RadarSiteModelImpl::ReadPresets()
|
||||||
// Determine if presets exists
|
// Determine if presets exists
|
||||||
if (std::filesystem::exists(presetsPath_))
|
if (std::filesystem::exists(presetsPath_))
|
||||||
{
|
{
|
||||||
presetsJson = util::json::ReadJsonFile(presetsPath_);
|
presetsJson = scwx::util::json::ReadJsonFile(presetsPath_);
|
||||||
}
|
}
|
||||||
|
|
||||||
// If presets was successfully read
|
// If presets was successfully read
|
||||||
|
|
@ -160,7 +160,7 @@ void RadarSiteModelImpl::WritePresets()
|
||||||
logger_->info("Saving presets");
|
logger_->info("Saving presets");
|
||||||
|
|
||||||
auto presetsJson = boost::json::value_from(presets_);
|
auto presetsJson = boost::json::value_from(presets_);
|
||||||
util::json::WriteJsonFile(presetsPath_, presetsJson);
|
scwx::util::json::WriteJsonFile(presetsPath_, presetsJson);
|
||||||
}
|
}
|
||||||
|
|
||||||
int RadarSiteModel::rowCount(const QModelIndex& parent) const
|
int RadarSiteModel::rowCount(const QModelIndex& parent) const
|
||||||
|
|
|
||||||
|
|
@ -1,41 +1,19 @@
|
||||||
#include <scwx/qt/util/json.hpp>
|
#include <scwx/qt/util/json.hpp>
|
||||||
|
#include <scwx/util/json.hpp>
|
||||||
#include <scwx/util/logger.hpp>
|
#include <scwx/util/logger.hpp>
|
||||||
|
|
||||||
#include <fstream>
|
|
||||||
|
|
||||||
#include <boost/json.hpp>
|
|
||||||
#include <fmt/ranges.h>
|
|
||||||
#include <QFile>
|
#include <QFile>
|
||||||
#include <QTextStream>
|
#include <QTextStream>
|
||||||
|
|
||||||
namespace scwx
|
namespace scwx::qt::util::json
|
||||||
{
|
|
||||||
namespace qt
|
|
||||||
{
|
|
||||||
namespace util
|
|
||||||
{
|
|
||||||
namespace json
|
|
||||||
{
|
{
|
||||||
|
|
||||||
static const std::string logPrefix_ = "scwx::qt::util::json";
|
static const std::string logPrefix_ = "scwx::qt::util::json";
|
||||||
static const auto logger_ = scwx::util::Logger::Create(logPrefix_);
|
static const auto logger_ = scwx::util::Logger::Create(logPrefix_);
|
||||||
|
|
||||||
/* Adapted from:
|
|
||||||
* https://www.boost.org/doc/libs/1_77_0/libs/json/doc/html/json/examples.html#json.examples.pretty
|
|
||||||
*
|
|
||||||
* Copyright (c) 2019, 2020 Vinnie Falco
|
|
||||||
* Copyright (c) 2020 Krystian Stasiowski
|
|
||||||
* Distributed under the Boost Software License, Version 1.0. (See
|
|
||||||
* http://www.boost.org/LICENSE_1_0.txt)
|
|
||||||
*/
|
|
||||||
static void PrettyPrintJson(std::ostream& os,
|
|
||||||
boost::json::value const& jv,
|
|
||||||
std::string* indent = nullptr);
|
|
||||||
|
|
||||||
static boost::json::value ReadJsonFile(QFile& file);
|
static boost::json::value ReadJsonFile(QFile& file);
|
||||||
static boost::json::value ReadJsonStream(std::istream& is);
|
|
||||||
|
|
||||||
boost::json::value ReadJsonFile(const std::string& path)
|
boost::json::value ReadJsonQFile(const std::string& path)
|
||||||
{
|
{
|
||||||
boost::json::value json;
|
boost::json::value json;
|
||||||
|
|
||||||
|
|
@ -46,8 +24,7 @@ boost::json::value ReadJsonFile(const std::string& path)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
std::ifstream ifs {path};
|
json = ::scwx::util::json::ReadJsonFile(path);
|
||||||
json = ReadJsonStream(ifs);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return json;
|
return json;
|
||||||
|
|
@ -65,7 +42,7 @@ static boost::json::value ReadJsonFile(QFile& file)
|
||||||
std::string jsonSource = jsonStream.readAll().toStdString();
|
std::string jsonSource = jsonStream.readAll().toStdString();
|
||||||
std::istringstream is {jsonSource};
|
std::istringstream is {jsonSource};
|
||||||
|
|
||||||
json = ReadJsonStream(is);
|
json = ::scwx::util::json::ReadJsonStream(is);
|
||||||
|
|
||||||
file.close();
|
file.close();
|
||||||
}
|
}
|
||||||
|
|
@ -78,147 +55,4 @@ static boost::json::value ReadJsonFile(QFile& file)
|
||||||
return json;
|
return json;
|
||||||
}
|
}
|
||||||
|
|
||||||
static boost::json::value ReadJsonStream(std::istream& is)
|
} // namespace scwx::qt::util::json
|
||||||
{
|
|
||||||
std::string line;
|
|
||||||
|
|
||||||
boost::json::stream_parser p;
|
|
||||||
boost::system::error_code ec;
|
|
||||||
|
|
||||||
while (std::getline(is, line))
|
|
||||||
{
|
|
||||||
p.write(line, ec);
|
|
||||||
if (ec)
|
|
||||||
{
|
|
||||||
logger_->warn("{}", ec.message());
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
p.finish(ec);
|
|
||||||
if (ec)
|
|
||||||
{
|
|
||||||
logger_->warn("{}", ec.message());
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
return p.release();
|
|
||||||
}
|
|
||||||
|
|
||||||
void WriteJsonFile(const std::string& path,
|
|
||||||
const boost::json::value& json,
|
|
||||||
bool prettyPrint)
|
|
||||||
{
|
|
||||||
std::ofstream ofs {path};
|
|
||||||
|
|
||||||
if (!ofs.is_open())
|
|
||||||
{
|
|
||||||
logger_->warn("Cannot write JSON file: \"{}\"", path);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (prettyPrint)
|
|
||||||
{
|
|
||||||
PrettyPrintJson(ofs, json);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ofs << json;
|
|
||||||
}
|
|
||||||
ofs.close();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void PrettyPrintJson(std::ostream& os,
|
|
||||||
boost::json::value const& jv,
|
|
||||||
std::string* indent)
|
|
||||||
{
|
|
||||||
std::string indent_;
|
|
||||||
if (!indent)
|
|
||||||
indent = &indent_;
|
|
||||||
switch (jv.kind())
|
|
||||||
{
|
|
||||||
case boost::json::kind::object:
|
|
||||||
{
|
|
||||||
os << "{\n";
|
|
||||||
indent->append(4, ' ');
|
|
||||||
auto const& obj = jv.get_object();
|
|
||||||
if (!obj.empty())
|
|
||||||
{
|
|
||||||
auto it = obj.begin();
|
|
||||||
for (;;)
|
|
||||||
{
|
|
||||||
os << *indent << boost::json::serialize(it->key()) << " : ";
|
|
||||||
PrettyPrintJson(os, it->value(), indent);
|
|
||||||
if (++it == obj.end())
|
|
||||||
break;
|
|
||||||
os << ",\n";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
os << "\n";
|
|
||||||
indent->resize(indent->size() - 4);
|
|
||||||
os << *indent << "}";
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case boost::json::kind::array:
|
|
||||||
{
|
|
||||||
os << "[\n";
|
|
||||||
indent->append(4, ' ');
|
|
||||||
auto const& arr = jv.get_array();
|
|
||||||
if (!arr.empty())
|
|
||||||
{
|
|
||||||
auto it = arr.begin();
|
|
||||||
for (;;)
|
|
||||||
{
|
|
||||||
os << *indent;
|
|
||||||
PrettyPrintJson(os, *it, indent);
|
|
||||||
if (++it == arr.end())
|
|
||||||
break;
|
|
||||||
os << ",\n";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
os << "\n";
|
|
||||||
indent->resize(indent->size() - 4);
|
|
||||||
os << *indent << "]";
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case boost::json::kind::string:
|
|
||||||
{
|
|
||||||
os << boost::json::serialize(jv.get_string());
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case boost::json::kind::uint64:
|
|
||||||
os << jv.get_uint64();
|
|
||||||
break;
|
|
||||||
|
|
||||||
case boost::json::kind::int64:
|
|
||||||
os << jv.get_int64();
|
|
||||||
break;
|
|
||||||
|
|
||||||
case boost::json::kind::double_:
|
|
||||||
os << jv.get_double();
|
|
||||||
break;
|
|
||||||
|
|
||||||
case boost::json::kind::bool_:
|
|
||||||
if (jv.get_bool())
|
|
||||||
os << "true";
|
|
||||||
else
|
|
||||||
os << "false";
|
|
||||||
break;
|
|
||||||
|
|
||||||
case boost::json::kind::null:
|
|
||||||
os << "null";
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (indent->empty())
|
|
||||||
os << "\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace json
|
|
||||||
} // namespace util
|
|
||||||
} // namespace qt
|
|
||||||
} // namespace scwx
|
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,5 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <optional>
|
|
||||||
|
|
||||||
#include <boost/json/value.hpp>
|
#include <boost/json/value.hpp>
|
||||||
|
|
||||||
namespace scwx
|
namespace scwx
|
||||||
|
|
@ -13,10 +11,7 @@ namespace util
|
||||||
namespace json
|
namespace json
|
||||||
{
|
{
|
||||||
|
|
||||||
boost::json::value ReadJsonFile(const std::string& path);
|
boost::json::value ReadJsonQFile(const std::string& path);
|
||||||
void WriteJsonFile(const std::string& path,
|
|
||||||
const boost::json::value& json,
|
|
||||||
bool prettyPrint = true);
|
|
||||||
|
|
||||||
} // namespace json
|
} // namespace json
|
||||||
} // namespace util
|
} // namespace util
|
||||||
|
|
|
||||||
15
wxdata/include/scwx/util/json.hpp
Normal file
15
wxdata/include/scwx/util/json.hpp
Normal file
|
|
@ -0,0 +1,15 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <boost/json/value.hpp>
|
||||||
|
|
||||||
|
namespace scwx::util::json
|
||||||
|
{
|
||||||
|
|
||||||
|
boost::json::value ReadJsonFile(const std::string& path);
|
||||||
|
boost::json::value ReadJsonStream(std::istream& is);
|
||||||
|
boost::json::value ReadJsonString(std::string_view sv);
|
||||||
|
void WriteJsonFile(const std::string& path,
|
||||||
|
const boost::json::value& json,
|
||||||
|
bool prettyPrint = true);
|
||||||
|
|
||||||
|
} // namespace scwx::util::json
|
||||||
199
wxdata/source/scwx/util/json.cpp
Normal file
199
wxdata/source/scwx/util/json.cpp
Normal file
|
|
@ -0,0 +1,199 @@
|
||||||
|
#include <scwx/util/json.hpp>
|
||||||
|
#include <scwx/util/logger.hpp>
|
||||||
|
|
||||||
|
#include <fstream>
|
||||||
|
|
||||||
|
#include <boost/json.hpp>
|
||||||
|
#include <fmt/ranges.h>
|
||||||
|
|
||||||
|
namespace scwx::util::json
|
||||||
|
{
|
||||||
|
|
||||||
|
static const std::string logPrefix_ = "scwx::util::json";
|
||||||
|
static const auto logger_ = scwx::util::Logger::Create(logPrefix_);
|
||||||
|
|
||||||
|
/* Adapted from:
|
||||||
|
* https://www.boost.org/doc/libs/1_77_0/libs/json/doc/html/json/examples.html#json.examples.pretty
|
||||||
|
*
|
||||||
|
* Copyright (c) 2019, 2020 Vinnie Falco
|
||||||
|
* Copyright (c) 2020 Krystian Stasiowski
|
||||||
|
* Distributed under the Boost Software License, Version 1.0. (See
|
||||||
|
* http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
*/
|
||||||
|
static void PrettyPrintJson(std::ostream& os,
|
||||||
|
boost::json::value const& jv,
|
||||||
|
std::string* indent = nullptr);
|
||||||
|
|
||||||
|
boost::json::value ReadJsonFile(const std::string& path)
|
||||||
|
{
|
||||||
|
boost::json::value json;
|
||||||
|
|
||||||
|
std::ifstream ifs {path};
|
||||||
|
json = ReadJsonStream(ifs);
|
||||||
|
|
||||||
|
return json;
|
||||||
|
}
|
||||||
|
|
||||||
|
boost::json::value ReadJsonStream(std::istream& is)
|
||||||
|
{
|
||||||
|
std::string line;
|
||||||
|
|
||||||
|
boost::json::stream_parser p;
|
||||||
|
boost::system::error_code ec;
|
||||||
|
|
||||||
|
while (std::getline(is, line))
|
||||||
|
{
|
||||||
|
p.write(line, ec);
|
||||||
|
if (ec)
|
||||||
|
{
|
||||||
|
logger_->warn("{}", ec.message());
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
p.finish(ec);
|
||||||
|
if (ec)
|
||||||
|
{
|
||||||
|
logger_->warn("{}", ec.message());
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
return p.release();
|
||||||
|
}
|
||||||
|
|
||||||
|
boost::json::value ReadJsonString(std::string_view sv)
|
||||||
|
{
|
||||||
|
boost::json::stream_parser p;
|
||||||
|
boost::system::error_code ec;
|
||||||
|
|
||||||
|
p.write(sv, ec);
|
||||||
|
if (ec)
|
||||||
|
{
|
||||||
|
logger_->warn("{}", ec.message());
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
p.finish(ec);
|
||||||
|
if (ec)
|
||||||
|
{
|
||||||
|
logger_->warn("{}", ec.message());
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
return p.release();
|
||||||
|
}
|
||||||
|
|
||||||
|
void WriteJsonFile(const std::string& path,
|
||||||
|
const boost::json::value& json,
|
||||||
|
bool prettyPrint)
|
||||||
|
{
|
||||||
|
std::ofstream ofs {path};
|
||||||
|
|
||||||
|
if (!ofs.is_open())
|
||||||
|
{
|
||||||
|
logger_->warn("Cannot write JSON file: \"{}\"", path);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (prettyPrint)
|
||||||
|
{
|
||||||
|
PrettyPrintJson(ofs, json);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ofs << json;
|
||||||
|
}
|
||||||
|
ofs.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void PrettyPrintJson(std::ostream& os,
|
||||||
|
boost::json::value const& jv,
|
||||||
|
std::string* indent)
|
||||||
|
{
|
||||||
|
std::string indent_;
|
||||||
|
if (!indent)
|
||||||
|
indent = &indent_;
|
||||||
|
switch (jv.kind())
|
||||||
|
{
|
||||||
|
case boost::json::kind::object:
|
||||||
|
{
|
||||||
|
os << "{\n";
|
||||||
|
indent->append(4, ' ');
|
||||||
|
auto const& obj = jv.get_object();
|
||||||
|
if (!obj.empty())
|
||||||
|
{
|
||||||
|
auto it = obj.begin();
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
os << *indent << boost::json::serialize(it->key()) << " : ";
|
||||||
|
PrettyPrintJson(os, it->value(), indent);
|
||||||
|
if (++it == obj.end())
|
||||||
|
break;
|
||||||
|
os << ",\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
os << "\n";
|
||||||
|
indent->resize(indent->size() - 4);
|
||||||
|
os << *indent << "}";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case boost::json::kind::array:
|
||||||
|
{
|
||||||
|
os << "[\n";
|
||||||
|
indent->append(4, ' ');
|
||||||
|
auto const& arr = jv.get_array();
|
||||||
|
if (!arr.empty())
|
||||||
|
{
|
||||||
|
auto it = arr.begin();
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
os << *indent;
|
||||||
|
PrettyPrintJson(os, *it, indent);
|
||||||
|
if (++it == arr.end())
|
||||||
|
break;
|
||||||
|
os << ",\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
os << "\n";
|
||||||
|
indent->resize(indent->size() - 4);
|
||||||
|
os << *indent << "]";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case boost::json::kind::string:
|
||||||
|
{
|
||||||
|
os << boost::json::serialize(jv.get_string());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case boost::json::kind::uint64:
|
||||||
|
os << jv.get_uint64();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case boost::json::kind::int64:
|
||||||
|
os << jv.get_int64();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case boost::json::kind::double_:
|
||||||
|
os << jv.get_double();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case boost::json::kind::bool_:
|
||||||
|
if (jv.get_bool())
|
||||||
|
os << "true";
|
||||||
|
else
|
||||||
|
os << "false";
|
||||||
|
break;
|
||||||
|
|
||||||
|
case boost::json::kind::null:
|
||||||
|
os << "null";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (indent->empty())
|
||||||
|
os << "\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace scwx::util::json
|
||||||
|
|
@ -78,6 +78,7 @@ set(HDR_UTIL include/scwx/util/digest.hpp
|
||||||
include/scwx/util/float.hpp
|
include/scwx/util/float.hpp
|
||||||
include/scwx/util/hash.hpp
|
include/scwx/util/hash.hpp
|
||||||
include/scwx/util/iterator.hpp
|
include/scwx/util/iterator.hpp
|
||||||
|
include/scwx/util/json.hpp
|
||||||
include/scwx/util/logger.hpp
|
include/scwx/util/logger.hpp
|
||||||
include/scwx/util/map.hpp
|
include/scwx/util/map.hpp
|
||||||
include/scwx/util/rangebuf.hpp
|
include/scwx/util/rangebuf.hpp
|
||||||
|
|
@ -90,6 +91,7 @@ set(SRC_UTIL source/scwx/util/digest.cpp
|
||||||
source/scwx/util/environment.cpp
|
source/scwx/util/environment.cpp
|
||||||
source/scwx/util/float.cpp
|
source/scwx/util/float.cpp
|
||||||
source/scwx/util/hash.cpp
|
source/scwx/util/hash.cpp
|
||||||
|
source/scwx/util/json.cpp
|
||||||
source/scwx/util/logger.cpp
|
source/scwx/util/logger.cpp
|
||||||
source/scwx/util/rangebuf.cpp
|
source/scwx/util/rangebuf.cpp
|
||||||
source/scwx/util/streams.cpp
|
source/scwx/util/streams.cpp
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue