mirror of https://gitlab.com/cppit/jucipp
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
102 lines
2.7 KiB
102 lines
2.7 KiB
|
5 years ago
|
#include "json.hpp"
|
||
|
|
#include <algorithm>
|
||
|
|
#include <fstream>
|
||
|
|
#include <iostream>
|
||
|
|
#include <sstream>
|
||
|
|
|
||
|
|
void JSON::write_json_internal(std::ostream &stream, const boost::property_tree::ptree &pt, bool pretty, const std::vector<std::string> ¬_string_keys, size_t column, const std::string &key) {
|
||
|
|
// Based on boost::property_tree::json_parser::write_json_helper()
|
||
|
|
|
||
|
|
if(pt.empty()) { // Value
|
||
|
|
auto value = pt.get_value<std::string>();
|
||
|
|
if(std::any_of(not_string_keys.begin(), not_string_keys.end(), [&key](const std::string ¬_string_key) {
|
||
|
|
return key == not_string_key;
|
||
|
|
}))
|
||
|
|
stream << value;
|
||
|
|
else
|
||
|
|
stream << '"' << escape_string(value) << '"';
|
||
|
|
}
|
||
|
|
else if(pt.count(std::string{}) == pt.size()) { // Array
|
||
|
|
stream << '[';
|
||
|
|
if(pretty)
|
||
|
|
stream << '\n';
|
||
|
|
|
||
|
|
for(auto it = pt.begin(); it != pt.end(); ++it) {
|
||
|
|
if(pretty)
|
||
|
|
stream << std::string((column + 1) * 2, ' ');
|
||
|
|
|
||
|
|
write_json_internal(stream, it->second, pretty, not_string_keys, column + 1, key);
|
||
|
|
|
||
|
|
if(std::next(it) != pt.end())
|
||
|
|
stream << ',';
|
||
|
|
if(pretty)
|
||
|
|
stream << '\n';
|
||
|
|
}
|
||
|
|
|
||
|
|
if(pretty)
|
||
|
|
stream << std::string(column * 2, ' ');
|
||
|
|
stream << ']';
|
||
|
|
}
|
||
|
|
else { // Object
|
||
|
|
stream << '{';
|
||
|
|
if(pretty)
|
||
|
|
stream << '\n';
|
||
|
|
|
||
|
|
for(auto it = pt.begin(); it != pt.end(); ++it) {
|
||
|
|
if(pretty)
|
||
|
|
stream << std::string((column + 1) * 2, ' ');
|
||
|
|
|
||
|
|
stream << '"' << escape_string(it->first) << "\":";
|
||
|
|
if(pretty)
|
||
|
|
stream << ' ';
|
||
|
|
write_json_internal(stream, it->second, pretty, not_string_keys, column + 1, it->first);
|
||
|
|
|
||
|
|
if(std::next(it) != pt.end())
|
||
|
|
stream << ',';
|
||
|
|
if(pretty)
|
||
|
|
stream << '\n';
|
||
|
|
}
|
||
|
|
|
||
|
|
if(pretty)
|
||
|
|
stream << std::string(column * 2, ' ');
|
||
|
|
stream << '}';
|
||
|
|
}
|
||
|
|
}
|
||
|
|
void JSON::write(std::ostream &stream, const boost::property_tree::ptree &pt, bool pretty, const std::vector<std::string> ¬_string_keys) {
|
||
|
|
write_json_internal(stream, pt, pretty, not_string_keys, 0, "");
|
||
|
|
}
|
||
|
|
|
||
|
|
std::string JSON::escape_string(std::string string) {
|
||
|
|
for(size_t c = 0; c < string.size(); ++c) {
|
||
|
|
if(string[c] == '\b') {
|
||
|
|
string.replace(c, 1, "\\b");
|
||
|
|
++c;
|
||
|
|
}
|
||
|
|
else if(string[c] == '\f') {
|
||
|
|
string.replace(c, 1, "\\f");
|
||
|
|
++c;
|
||
|
|
}
|
||
|
|
else if(string[c] == '\n') {
|
||
|
|
string.replace(c, 1, "\\n");
|
||
|
|
++c;
|
||
|
|
}
|
||
|
|
else if(string[c] == '\r') {
|
||
|
|
string.replace(c, 1, "\\r");
|
||
|
|
++c;
|
||
|
|
}
|
||
|
|
else if(string[c] == '\t') {
|
||
|
|
string.replace(c, 1, "\\t");
|
||
|
|
++c;
|
||
|
|
}
|
||
|
|
else if(string[c] == '"') {
|
||
|
|
string.replace(c, 1, "\\\"");
|
||
|
|
++c;
|
||
|
|
}
|
||
|
|
else if(string[c] == '\\') {
|
||
|
|
string.replace(c, 1, "\\\\");
|
||
|
|
++c;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
return string;
|
||
|
|
}
|