diff options
author | Matthias P. Braendli <matthias.braendli@mpb.li> | 2023-11-21 22:12:14 +0100 |
---|---|---|
committer | Matthias P. Braendli <matthias.braendli@mpb.li> | 2023-11-21 22:12:14 +0100 |
commit | 5fe36a627405b8fc65bdb212a6d505b9a6c8e489 (patch) | |
tree | 8646d654e0467be8603c5ad37fb6cd89656dfd26 /lib/Json.cpp | |
parent | 477ac4639a7c7f74f07a6164096fc7de102528ff (diff) | |
parent | f84065c3cc6fff0edb771f85190f7228f4d740b6 (diff) | |
download | dabmod-5fe36a627405b8fc65bdb212a6d505b9a6c8e489.tar.gz dabmod-5fe36a627405b8fc65bdb212a6d505b9a6c8e489.tar.bz2 dabmod-5fe36a627405b8fc65bdb212a6d505b9a6c8e489.zip |
Merge branch 'dexter' into next
Diffstat (limited to 'lib/Json.cpp')
-rw-r--r-- | lib/Json.cpp | 122 |
1 files changed, 122 insertions, 0 deletions
diff --git a/lib/Json.cpp b/lib/Json.cpp new file mode 100644 index 0000000..4dc2f25 --- /dev/null +++ b/lib/Json.cpp @@ -0,0 +1,122 @@ +/* + Copyright (C) 2007, 2008, 2009, 2010, 2011, 2012 + Her Majesty the Queen in Right of Canada (Communications Research + Center Canada) + + Copyright (C) 2023 + Matthias P. Braendli, matthias.braendli@mpb.li + + http://www.opendigitalradio.org + */ +/* + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <https://www.gnu.org/licenses/>. + */ +#include <string> +#include <iostream> +#include <sstream> +#include <iomanip> +#include <string> +#include <algorithm> + +#include "Json.h" + +namespace json { + static std::string escape_json(const std::string &s) { + std::ostringstream o; + for (auto c = s.cbegin(); c != s.cend(); c++) { + switch (*c) { + case '"': o << "\\\""; break; + case '\\': o << "\\\\"; break; + case '\b': o << "\\b"; break; + case '\f': o << "\\f"; break; + case '\n': o << "\\n"; break; + case '\r': o << "\\r"; break; + case '\t': o << "\\t"; break; + default: + if ('\x00' <= *c && *c <= '\x1f') { + o << "\\u" + << std::hex << std::setw(4) << std::setfill('0') << static_cast<int>(*c); + } else { + o << *c; + } + } + } + return o.str(); + } + + std::string map_to_json(const map_t& values) { + std::ostringstream ss; + ss << "{ "; + size_t ix = 0; + for (const auto& element : values) { + if (ix > 0) { + ss << ","; + } + + ss << "\"" << escape_json(element.first) << "\": "; + ss << value_to_json(element.second); + + ix++; + } + ss << " }"; + + return ss.str(); + } + + std::string value_to_json(const value_t& value) + { + std::ostringstream ss; + + if (std::holds_alternative<std::string>(value.v)) { + ss << "\"" << escape_json(std::get<std::string>(value.v)) << "\""; + } + else if (std::holds_alternative<double>(value.v)) { + ss << std::fixed << std::get<double>(value.v); + } + else if (std::holds_alternative<ssize_t>(value.v)) { + ss << std::get<ssize_t>(value.v); + } + else if (std::holds_alternative<size_t>(value.v)) { + ss << std::get<size_t>(value.v); + } + else if (std::holds_alternative<bool>(value.v)) { + ss << (std::get<bool>(value.v) ? "true" : "false"); + } + else if (std::holds_alternative<std::nullopt_t>(value.v)) { + ss << "null"; + } + else if (std::holds_alternative<std::vector<json::value_t> >(value.v)) { + const auto& vec = std::get<std::vector<json::value_t> >(value.v); + ss << "[ "; + size_t list_ix = 0; + for (const auto& list_element : vec) { + if (list_ix > 0) { + ss << ","; + } + ss << value_to_json(list_element); + list_ix++; + } + ss << "]"; + } + else if (std::holds_alternative<std::shared_ptr<json::map_t> >(value.v)) { + const map_t& v = *std::get<std::shared_ptr<json::map_t> >(value.v); + ss << map_to_json(v); + } + else { + throw std::logic_error("variant alternative not handled"); + } + + return ss.str(); + } +} |