The JSON encode routines convert STL structures into JSON formatted strings. Using polymorphism and recursion, the function for each data-type is called, writing out finer and finer detail until raw data-types are written. Strings are URL encoded prior to writing to the file in order to handle special characters and internal quotes.
The source files for my encoder follows.
#pragma once
#include <json/json.h>
#include <map>
#include <ostream>
#include <set>
#include <sstream>
#include <string>
#include <tuple>
#include <unordered_map>
#include <vector>
namespace UJSON {
template <typename T> std::string encode(const T &t);
template <typename T> std::string raw(const T &val) {
std::ostringstream ss;
ss << val;
return ss.str();
}
std::string raw(const std::string &val);
std::string raw(const std::u16string &val);
void encodeJSON(std::ostream &ss, int val);
void encodeJSON(std::ostream &ss, unsigned int val);
void encodeJSON(std::ostream &ss, float val);
void encodeJSON(std::ostream &ss, double val);
void encodeJSON(std::ostream &ss, long double val);
void encodeJSON(std::ostream &ss, const std::string &val);
void encodeJSON(std::ostream &ss, const std::u16string &val);
template <typename T>
void encodeJSON(std::ostream &ss, const std::vector<T> &t) {
ss << "[";
for (unsigned int i = 0; i < t.size(); i++) {
ss << encode(t[i]);
if (i < (t.size() - 1))
ss << ",";
}
ss << "]";
}
template <typename T> void encodeJSON(std::ostream &ss, const std::set<T> &t) {
ss << "[";
unsigned int i = 0;
for (auto v : t) {
ss << encode(v);
if (i < (t.size() - 1))
ss << ",";
i++;
}
ss << "]";
}
template <typename T, typename U>
void encodeJSON(std::ostream &ss, const std::map<T, U> &t) {
ss << "{";
unsigned int i = 0;
for (auto v : t) {
ss << encode(v.first);
ss << ":";
ss << encode(v.second);
if (i < (t.size() - 1))
ss << ",";
i++;
}
ss << "}";
}
template <typename T, typename U>
void encodeJSON(std::ostream &ss, const std::pair<T, U> &t) {
ss << "[";
ss << encode(t.first);
ss << ",";
ss << encode(t.second);
ss << "]";
}
template <typename T, typename U>
void encodeJSON(std::ostream &ss, const std::unordered_map<T, U> &t) {
ss << "{";
unsigned int i = 0;
for (auto v : t) {
ss << encode(v.first);
ss << ":";
ss << encode(v.second);
if (i < (t.size() - 1))
ss << ",";
i++;
}
ss << "}";
}
template <typename... Ts>
void encodeJSON(std::ostream &ss, const std::tuple<Ts...> &t) {
std::apply(
[&ss](Ts const &...args) {
ss << '[';
std::size_t n{0};
((ss << encode(args) << (++n != sizeof...(Ts) ? "," : "")), ...);
ss << ']';
},
t);
}
template <typename T> std::string encode(const T &t) {
std::ostringstream ss;
encodeJSON(ss, t);
return ss.str();
}
template <typename T> std::string encode(const std::string &label, const T &t) {
std::ostringstream ss;
ss << "\"" << label << "\":" << encode(t);
return ss.str();
}
} // namespace UJSON
#include "u_json_encode.h"
#include "u_log.h"
void UJSON::encodeJSON(std::ostream &ss, int val) {
ss << raw(val);
}
void UJSON::encodeJSON(std::ostream &ss, unsigned int val) {
ss << raw(val);
}
void UJSON::encodeJSON(std::ostream &ss, float val) {
ss << raw(val);
}
void UJSON::encodeJSON(std::ostream &ss, double val) {
ss << raw(val);
}
void UJSON::encodeJSON(std::ostream &ss, long double val) {
ss << raw(val);
}
void UJSON::encodeJSON(std::ostream &ss, const std::string &val) {
ss << raw(val);
}
void UJSON::encodeJSON(std::ostream &ss, const std::u16string &val) {
ss << raw(val);
}
std::string UJSON::raw(const std::string &val) {
std::ostringstream ss;
ss << "\"" << mystd::urlEncode(val) << "\"";
return ss.str();
}
std::string UJSON::raw(const std::u16string &val) {
std::ostringstream ss;
std::string wip = mystd::toUTF8(val);
ss << "\"" << mystd::urlEncode(wip) << "\"";
return ss.str();
}