The JSON decode routines use External link jsoncpp to interpret JSON data. Using polymorphism and recursion, the function for each data-type is called, reading in finer and finer detail until raw data-types are read. Strings are URL decoded.
The source files for my decoder follows.
#pragma once
#include <json/json.h>
#include <cstddef>
#include <iostream>
#include <map>
#include <set>
#include <sstream>
#include <string>
#include <tuple>
#include <type_traits>
#include <unordered_map>
#include <vector>
namespace UJSON {
template <typename T> void decode(const Json::Value &value, T &t);
void decodeJSON(const Json::Value &value, int &ret);
void decodeJSON(const Json::Value &value, unsigned int &ret);
void decodeJSON(const Json::Value &value, float &ret);
void decodeJSON(const Json::Value &value, double &ret);
void decodeJSON(const Json::Value &value, long double &ret);
void decodeJSON(const Json::Value &value, std::string &ret);
void decodeJSON(const Json::Value &value, std::u16string &ret);
template <typename T>
void decodeJSON(const Json::Value &value, std::vector<T> &ret) {
if (value.isArray()) {
for (unsigned int i = 0; i < value.size(); i++) {
T t;
decode(value[i], t);
ret.push_back(t);
}
}
}
template <typename T>
void decodeJSON(const Json::Value &value, std::set<T> &ret) {
if (value.isArray()) {
for (unsigned int i = 0; i < value.size(); i++) {
T t;
decode(value[i], t);
ret.insert(t);
}
}
}
template <typename T, typename U>
void decodeJSON(const Json::Value &value, std::map<T, U> &ret) {
if (value.isObject()) {
for (unsigned int i = 0; i < value.size(); i++) {
if (value[i].isArray()) {
T t;
U u;
decode(value[i][0], t);
decode(value[i][1], u);
ret[t] = u;
}
}
}
}
template <typename T, typename U>
void decodeJSON(const Json::Value &value, std::pair<T, U> &ret) {
if (value.isArray()) {
T t;
U u;
decode(value[0], t);
decode(value[1], u);
ret.first = t;
ret.second = u;
}
}
template <typename T, typename U>
void decodeJSON(const Json::Value &value, std::unordered_map<T, U> &ret) {
if (value.isObject()) {
Json::Value::Members members = value.getMemberNames();
for (auto t : members) {
U u;
decode(value[t], u);
ret[t] = u;
}
}
}
template <typename... Ts>
void decodeJSON(const Json::Value &value, std::tuple<Ts...> &t) {
if (value.isArray()) {
int n = 0;
std::apply([&value, &n](Ts &...args) { (..., decode(value[n++], args)); },
t);
}
}
template <typename T> void decode(const Json::Value &value, T &t) {
decodeJSON(value, t);
}
} // namespace UJSON
#include "u_json_decode.h"
#include "u_log.h"
namespace UJSON {
void decodeJSON(const Json::Value &value, int &ret) { ret = value.asInt(); }
void decodeJSON(const Json::Value &value, unsigned int &ret) {
ret = value.asUInt();
}
void decodeJSON(const Json::Value &value, float &ret) { ret = value.asFloat(); }
void decodeJSON(const Json::Value &value, double &ret) {
ret = value.asDouble();
}
void decodeJSON(const Json::Value &value, long double &ret) {
ret = value.asDouble();
}
void decodeJSON(const Json::Value &value, std::string &ret) {
ret = mystd::urlDecode(value.asString());
}
void decodeJSON(const Json::Value &value, std::u16string &ret) {
std::string wip = mystd::urlDecode(value.asString());
fromUTF8(wip, ret);
}
} // namespace UJSON