mirror of
				https://github.com/ciphervance/supercell-wx.git
				synced 2025-10-30 06:50:06 +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; | ||||
|    size_t sitesAdded = 0; | ||||
| 
 | ||||
|    boost::json::value j = util::json::ReadJsonFile(path); | ||||
|    boost::json::value j = util::json::ReadJsonQFile(path); | ||||
| 
 | ||||
|    dataValid = j.is_array(); | ||||
| 
 | ||||
|  |  | |||
|  | @ -1,10 +1,10 @@ | |||
| #include <scwx/qt/manager/marker_manager.hpp> | ||||
| #include <scwx/qt/types/marker_types.hpp> | ||||
| #include <scwx/qt/util/color.hpp> | ||||
| #include <scwx/qt/util/json.hpp> | ||||
| #include <scwx/qt/util/texture_atlas.hpp> | ||||
| #include <scwx/qt/main/application.hpp> | ||||
| #include <scwx/qt/manager/resource_manager.hpp> | ||||
| #include <scwx/util/json.hpp> | ||||
| #include <scwx/util/logger.hpp> | ||||
| 
 | ||||
| #include <filesystem> | ||||
|  | @ -62,7 +62,7 @@ public: | |||
| 
 | ||||
|    bool markerFileRead_ {false}; | ||||
| 
 | ||||
|    void InitalizeIds(); | ||||
|    void            InitalizeIds(); | ||||
|    types::MarkerId NewId(); | ||||
|    types::MarkerId lastId_ {0}; | ||||
| }; | ||||
|  | @ -70,15 +70,9 @@ public: | |||
| class MarkerManager::Impl::MarkerRecord | ||||
| { | ||||
| public: | ||||
|    MarkerRecord(const types::MarkerInfo& info) : | ||||
|       markerInfo_ {info} | ||||
|    { | ||||
|    } | ||||
|    MarkerRecord(const types::MarkerInfo& info) : markerInfo_ {info} {} | ||||
| 
 | ||||
|    const types::MarkerInfo& toMarkerInfo() | ||||
|    { | ||||
|       return markerInfo_; | ||||
|    } | ||||
|    const types::MarkerInfo& toMarkerInfo() { return markerInfo_; } | ||||
| 
 | ||||
|    types::MarkerInfo markerInfo_; | ||||
| 
 | ||||
|  | @ -175,7 +169,7 @@ void MarkerManager::Impl::ReadMarkerSettings() | |||
|       // Determine if marker settings exists
 | ||||
|       if (std::filesystem::exists(markerSettingsPath_)) | ||||
|       { | ||||
|          markerJson = util::json::ReadJsonFile(markerSettingsPath_); | ||||
|          markerJson = scwx::util::json::ReadJsonFile(markerSettingsPath_); | ||||
|       } | ||||
| 
 | ||||
|       if (markerJson != nullptr && markerJson.is_array()) | ||||
|  | @ -224,8 +218,8 @@ void MarkerManager::Impl::WriteMarkerSettings() | |||
|    logger_->info("Saving location marker settings"); | ||||
| 
 | ||||
|    const std::shared_lock lock(markerRecordLock_); | ||||
|    auto markerJson = boost::json::value_from(markerRecords_); | ||||
|    util::json::WriteJsonFile(markerSettingsPath_, markerJson); | ||||
|    auto                   markerJson = boost::json::value_from(markerRecords_); | ||||
|    scwx::util::json::WriteJsonFile(markerSettingsPath_, markerJson); | ||||
| } | ||||
| 
 | ||||
| std::shared_ptr<MarkerManager::Impl::MarkerRecord> | ||||
|  | @ -357,10 +351,11 @@ types::MarkerId MarkerManager::add_marker(const types::MarkerInfo& marker) | |||
|    types::MarkerId id; | ||||
|    { | ||||
|       const std::unique_lock lock(p->markerRecordLock_); | ||||
|       id = p->NewId(); | ||||
|       id           = p->NewId(); | ||||
|       size_t index = p->markerRecords_.size(); | ||||
|       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; | ||||
| 
 | ||||
|       add_icon(marker.iconName); | ||||
|  | @ -499,7 +494,6 @@ void MarkerManager::set_marker_settings_path(const std::string& path) | |||
|    p->markerSettingsPath_ = path; | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| std::shared_ptr<MarkerManager> MarkerManager::Instance() | ||||
| { | ||||
|    static std::weak_ptr<MarkerManager> markerManagerReference_ {}; | ||||
|  |  | |||
|  | @ -2,10 +2,10 @@ | |||
| #include <scwx/qt/manager/font_manager.hpp> | ||||
| #include <scwx/qt/manager/resource_manager.hpp> | ||||
| #include <scwx/qt/main/application.hpp> | ||||
| #include <scwx/qt/util/json.hpp> | ||||
| #include <scwx/qt/util/network.hpp> | ||||
| #include <scwx/gr/placefile.hpp> | ||||
| #include <scwx/network/cpr.hpp> | ||||
| #include <scwx/util/json.hpp> | ||||
| #include <scwx/util/logger.hpp> | ||||
| 
 | ||||
| #include <shared_mutex> | ||||
|  | @ -385,7 +385,7 @@ void PlacefileManager::Impl::ReadPlacefileSettings() | |||
|    // Determine if placefile settings exists
 | ||||
|    if (std::filesystem::exists(placefileSettingsPath_)) | ||||
|    { | ||||
|       placefileJson = util::json::ReadJsonFile(placefileSettingsPath_); | ||||
|       placefileJson = scwx::util::json::ReadJsonFile(placefileSettingsPath_); | ||||
|    } | ||||
| 
 | ||||
|    // If placefile settings was successfully read
 | ||||
|  | @ -428,7 +428,7 @@ void PlacefileManager::Impl::WritePlacefileSettings() | |||
| 
 | ||||
|    std::shared_lock lock {placefileRecordLock_}; | ||||
|    auto             placefileJson = boost::json::value_from(placefileRecords_); | ||||
|    util::json::WriteJsonFile(placefileSettingsPath_, placefileJson); | ||||
|    scwx::util::json::WriteJsonFile(placefileSettingsPath_, placefileJson); | ||||
| } | ||||
| 
 | ||||
| void PlacefileManager::SetRadarSite( | ||||
|  |  | |||
|  | @ -9,7 +9,7 @@ | |||
| #include <scwx/qt/settings/text_settings.hpp> | ||||
| #include <scwx/qt/settings/ui_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 <filesystem> | ||||
|  |  | |||
|  | @ -1,4 +1,5 @@ | |||
| #include <scwx/qt/manager/update_manager.hpp> | ||||
| #include <scwx/util/json.hpp> | ||||
| #include <scwx/util/logger.hpp> | ||||
| 
 | ||||
| #include <mutex> | ||||
|  | @ -29,8 +30,7 @@ public: | |||
| 
 | ||||
|    ~Impl() {} | ||||
| 
 | ||||
|    static std::string        GetVersionString(const std::string& releaseName); | ||||
|    static boost::json::value ParseResponseText(const std::string& s); | ||||
|    static std::string GetVersionString(const std::string& releaseName); | ||||
| 
 | ||||
|    size_t PopulateReleases(); | ||||
|    size_t AddReleases(const boost::json::value& json); | ||||
|  | @ -70,28 +70,6 @@ UpdateManager::Impl::GetVersionString(const std::string& releaseName) | |||
|    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) | ||||
| { | ||||
|    std::unique_lock lock(p->updateMutex_); | ||||
|  | @ -148,7 +126,7 @@ size_t UpdateManager::Impl::PopulateReleases() | |||
|       // Successful REST API query
 | ||||
|       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) | ||||
|          { | ||||
|             logger_->warn("Response not JSON: {}", r.header["content-type"]); | ||||
|  |  | |||
|  | @ -1,7 +1,7 @@ | |||
| #include <scwx/qt/model/layer_model.hpp> | ||||
| #include <scwx/qt/manager/placefile_manager.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 <filesystem> | ||||
|  |  | |||
|  | @ -4,8 +4,8 @@ | |||
| #include <scwx/qt/types/qt_types.hpp> | ||||
| #include <scwx/qt/types/unit_types.hpp> | ||||
| #include <scwx/qt/util/geographic_lib.hpp> | ||||
| #include <scwx/qt/util/json.hpp> | ||||
| #include <scwx/common/geographic.hpp> | ||||
| #include <scwx/util/json.hpp> | ||||
| #include <scwx/util/logger.hpp> | ||||
| 
 | ||||
| #include <filesystem> | ||||
|  | @ -117,7 +117,7 @@ void RadarSiteModelImpl::ReadPresets() | |||
|    // Determine if presets exists
 | ||||
|    if (std::filesystem::exists(presetsPath_)) | ||||
|    { | ||||
|       presetsJson = util::json::ReadJsonFile(presetsPath_); | ||||
|       presetsJson = scwx::util::json::ReadJsonFile(presetsPath_); | ||||
|    } | ||||
| 
 | ||||
|    // If presets was successfully read
 | ||||
|  | @ -160,7 +160,7 @@ void RadarSiteModelImpl::WritePresets() | |||
|    logger_->info("Saving 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 | ||||
|  |  | |||
|  | @ -1,41 +1,19 @@ | |||
| #include <scwx/qt/util/json.hpp> | ||||
| #include <scwx/util/json.hpp> | ||||
| #include <scwx/util/logger.hpp> | ||||
| 
 | ||||
| #include <fstream> | ||||
| 
 | ||||
| #include <boost/json.hpp> | ||||
| #include <fmt/ranges.h> | ||||
| #include <QFile> | ||||
| #include <QTextStream> | ||||
| 
 | ||||
| namespace scwx | ||||
| { | ||||
| namespace qt | ||||
| { | ||||
| namespace util | ||||
| { | ||||
| namespace json | ||||
| namespace scwx::qt::util::json | ||||
| { | ||||
| 
 | ||||
| static const std::string logPrefix_ = "scwx::qt::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); | ||||
| 
 | ||||
| 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; | ||||
| 
 | ||||
|  | @ -46,8 +24,7 @@ boost::json::value ReadJsonFile(const std::string& path) | |||
|    } | ||||
|    else | ||||
|    { | ||||
|       std::ifstream ifs {path}; | ||||
|       json = ReadJsonStream(ifs); | ||||
|       json = ::scwx::util::json::ReadJsonFile(path); | ||||
|    } | ||||
| 
 | ||||
|    return json; | ||||
|  | @ -65,7 +42,7 @@ static boost::json::value ReadJsonFile(QFile& file) | |||
|       std::string        jsonSource = jsonStream.readAll().toStdString(); | ||||
|       std::istringstream is {jsonSource}; | ||||
| 
 | ||||
|       json = ReadJsonStream(is); | ||||
|       json = ::scwx::util::json::ReadJsonStream(is); | ||||
| 
 | ||||
|       file.close(); | ||||
|    } | ||||
|  | @ -78,147 +55,4 @@ static boost::json::value ReadJsonFile(QFile& file) | |||
|    return json; | ||||
| } | ||||
| 
 | ||||
| static 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(); | ||||
| } | ||||
| 
 | ||||
| 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
 | ||||
| } // namespace scwx::qt::util::json
 | ||||
|  |  | |||
|  | @ -1,7 +1,5 @@ | |||
| #pragma once | ||||
| 
 | ||||
| #include <optional> | ||||
| 
 | ||||
| #include <boost/json/value.hpp> | ||||
| 
 | ||||
| namespace scwx | ||||
|  | @ -13,10 +11,7 @@ namespace util | |||
| namespace json | ||||
| { | ||||
| 
 | ||||
| boost::json::value ReadJsonFile(const std::string& path); | ||||
| void               WriteJsonFile(const std::string&        path, | ||||
|                                  const boost::json::value& json, | ||||
|                                  bool                      prettyPrint = true); | ||||
| boost::json::value ReadJsonQFile(const std::string& path); | ||||
| 
 | ||||
| } // namespace json
 | ||||
| } // 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/hash.hpp | ||||
|              include/scwx/util/iterator.hpp | ||||
|              include/scwx/util/json.hpp | ||||
|              include/scwx/util/logger.hpp | ||||
|              include/scwx/util/map.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/float.cpp | ||||
|              source/scwx/util/hash.cpp | ||||
|              source/scwx/util/json.cpp | ||||
|              source/scwx/util/logger.cpp | ||||
|              source/scwx/util/rangebuf.cpp | ||||
|              source/scwx/util/streams.cpp | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Dan Paulat
						Dan Paulat