add util/json to repo
This commit is contained in:
parent
dfce1a44fc
commit
18c00718f6
2 changed files with 281 additions and 0 deletions
173
src/util/json/Writer.cpp
Normal file
173
src/util/json/Writer.cpp
Normal file
|
@ -0,0 +1,173 @@
|
||||||
|
// Copyright 2018, University of Freiburg,
|
||||||
|
// Chair of Algorithms and Data Structures.
|
||||||
|
// Authors: Patrick Brosi <brosi@informatik.uni-freiburg.de>
|
||||||
|
|
||||||
|
#include <iomanip>
|
||||||
|
#include "Writer.h"
|
||||||
|
#include "util/String.h"
|
||||||
|
using namespace util;
|
||||||
|
using namespace json;
|
||||||
|
|
||||||
|
using std::ostream;
|
||||||
|
using std::string;
|
||||||
|
using std::map;
|
||||||
|
|
||||||
|
// _____________________________________________________________________________
|
||||||
|
Writer::Writer(std::ostream* out)
|
||||||
|
: _out(out), _pretty(false), _indent(2), _floatPrec(10) {}
|
||||||
|
|
||||||
|
// _____________________________________________________________________________
|
||||||
|
Writer::Writer(std::ostream* out, size_t prec)
|
||||||
|
: _out(out), _pretty(false), _indent(2), _floatPrec(prec) {}
|
||||||
|
|
||||||
|
// _____________________________________________________________________________
|
||||||
|
Writer::Writer(std::ostream* out, size_t prec, bool pret)
|
||||||
|
: _out(out), _pretty(pret), _indent(2), _floatPrec(prec) {}
|
||||||
|
|
||||||
|
// _____________________________________________________________________________
|
||||||
|
Writer::Writer(std::ostream* out, size_t prec, bool pret, size_t indent)
|
||||||
|
: _out(out), _pretty(pret), _indent(indent), _floatPrec(prec) {}
|
||||||
|
|
||||||
|
// _____________________________________________________________________________
|
||||||
|
void Writer::obj() {
|
||||||
|
if (!_stack.empty() && _stack.top().type == OBJ)
|
||||||
|
throw WriterException("Object not allowed as key");
|
||||||
|
if (!_stack.empty() && _stack.top().type == KEY) _stack.pop();
|
||||||
|
if (!_stack.empty() && _stack.top().type == ARR) valCheck();
|
||||||
|
if (_stack.size() && _stack.top().type == ARR) prettor();
|
||||||
|
*_out << "{";
|
||||||
|
_stack.push({OBJ, 1});
|
||||||
|
}
|
||||||
|
|
||||||
|
// _____________________________________________________________________________
|
||||||
|
void Writer::key(const std::string& k) {
|
||||||
|
if (_stack.empty() || _stack.top().type != OBJ)
|
||||||
|
throw WriterException("Keys only allowed in objects.");
|
||||||
|
if (!_stack.top().empty) (*_out) << "," << (_pretty ? " " : "");
|
||||||
|
_stack.top().empty = 0;
|
||||||
|
prettor();
|
||||||
|
*_out << "\"" << k << "\""
|
||||||
|
<< ":" << (_pretty ? " " : "");
|
||||||
|
_stack.push({KEY, 1});
|
||||||
|
}
|
||||||
|
|
||||||
|
// _____________________________________________________________________________
|
||||||
|
void Writer::valCheck() {
|
||||||
|
if (_stack.empty() || (_stack.top().type != KEY && _stack.top().type != ARR))
|
||||||
|
throw WriterException("Value not allowed here.");
|
||||||
|
if (!_stack.empty() && _stack.top().type == KEY) _stack.pop();
|
||||||
|
if (!_stack.empty() && _stack.top().type == ARR) {
|
||||||
|
if (!_stack.top().empty) (*_out) << "," << (_pretty ? " " : "");
|
||||||
|
_stack.top().empty = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// _____________________________________________________________________________
|
||||||
|
void Writer::val(const std::string& v) {
|
||||||
|
valCheck();
|
||||||
|
*_out << "\"" << util::jsonStringEscape(v) << "\"";
|
||||||
|
}
|
||||||
|
|
||||||
|
// _____________________________________________________________________________
|
||||||
|
void Writer::val(const char* v) {
|
||||||
|
valCheck();
|
||||||
|
*_out << "\"" << util::jsonStringEscape(v) << "\"";
|
||||||
|
}
|
||||||
|
|
||||||
|
// _____________________________________________________________________________
|
||||||
|
void Writer::val(bool v) {
|
||||||
|
valCheck();
|
||||||
|
*_out << (v ? "true" : "false");
|
||||||
|
}
|
||||||
|
|
||||||
|
// _____________________________________________________________________________
|
||||||
|
void Writer::val(int v) {
|
||||||
|
valCheck();
|
||||||
|
*_out << v;
|
||||||
|
}
|
||||||
|
|
||||||
|
// _____________________________________________________________________________
|
||||||
|
void Writer::val(double v) {
|
||||||
|
valCheck();
|
||||||
|
*_out << std::fixed << std::setprecision(_floatPrec) << v;
|
||||||
|
}
|
||||||
|
|
||||||
|
// _____________________________________________________________________________
|
||||||
|
void Writer::val(Null) {
|
||||||
|
valCheck();
|
||||||
|
*_out << "null";
|
||||||
|
}
|
||||||
|
|
||||||
|
// _____________________________________________________________________________
|
||||||
|
void Writer::val(const Val& v) {
|
||||||
|
switch (v.type) {
|
||||||
|
case Val::JSNULL:
|
||||||
|
val(Null());
|
||||||
|
return;
|
||||||
|
case Val::INT:
|
||||||
|
val(v.i);
|
||||||
|
return;
|
||||||
|
case Val::FLOAT:
|
||||||
|
val(v.f);
|
||||||
|
return;
|
||||||
|
case Val::BOOL:
|
||||||
|
val((bool)v.i);
|
||||||
|
return;
|
||||||
|
case Val::STRING:
|
||||||
|
val(v.str);
|
||||||
|
return;
|
||||||
|
case Val::ARRAY:
|
||||||
|
arr();
|
||||||
|
for (const Val& varr : v.arr) val(varr);
|
||||||
|
close();
|
||||||
|
return;
|
||||||
|
case Val::DICT:
|
||||||
|
obj();
|
||||||
|
for (const auto& vdic : v.dict) {
|
||||||
|
keyVal(vdic.first, vdic.second);
|
||||||
|
};
|
||||||
|
close();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// _____________________________________________________________________________
|
||||||
|
void Writer::arr() {
|
||||||
|
if (!_stack.empty() && _stack.top().type == OBJ)
|
||||||
|
throw WriterException("Array not allowed as key");
|
||||||
|
if (!_stack.empty() && _stack.top().type == KEY) _stack.pop();
|
||||||
|
if (!_stack.empty() && _stack.top().type == ARR) valCheck();
|
||||||
|
*_out << "[";
|
||||||
|
_stack.push({ARR, 1});
|
||||||
|
}
|
||||||
|
|
||||||
|
// _____________________________________________________________________________
|
||||||
|
void Writer::prettor() {
|
||||||
|
if (_pretty) {
|
||||||
|
*_out << "\n";
|
||||||
|
for (size_t i = 0; i < _indent * _stack.size(); i++) (*_out) << " ";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// _____________________________________________________________________________
|
||||||
|
void Writer::closeAll() {
|
||||||
|
while (!_stack.empty()) close();
|
||||||
|
}
|
||||||
|
|
||||||
|
// _____________________________________________________________________________
|
||||||
|
void Writer::close() {
|
||||||
|
if (_stack.empty()) return;
|
||||||
|
switch (_stack.top().type) {
|
||||||
|
case OBJ:
|
||||||
|
_stack.pop();
|
||||||
|
prettor();
|
||||||
|
(*_out) << "}";
|
||||||
|
break;
|
||||||
|
case ARR:
|
||||||
|
_stack.pop();
|
||||||
|
(*_out) << "]";
|
||||||
|
break;
|
||||||
|
case KEY:
|
||||||
|
throw WriterException("Missing value.");
|
||||||
|
}
|
||||||
|
}
|
108
src/util/json/Writer.h
Normal file
108
src/util/json/Writer.h
Normal file
|
@ -0,0 +1,108 @@
|
||||||
|
// Copyright 2018, University of Freiburg,
|
||||||
|
// Chair of Algorithms and Data Structures.
|
||||||
|
// Authors: Patrick Brosi <brosi@informatik.uni-freiburg.de>
|
||||||
|
|
||||||
|
#ifndef UTIL_JSON_WRITER_H_
|
||||||
|
#define UTIL_JSON_WRITER_H_
|
||||||
|
|
||||||
|
#include <map>
|
||||||
|
#include <ostream>
|
||||||
|
#include <stack>
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
namespace util {
|
||||||
|
namespace json {
|
||||||
|
|
||||||
|
class WriterException : public std::exception {
|
||||||
|
public:
|
||||||
|
WriterException(std::string msg) : _msg(msg) {}
|
||||||
|
~WriterException() throw() {}
|
||||||
|
|
||||||
|
virtual const char* what() const throw() { return _msg.c_str(); };
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::string _msg;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Null {};
|
||||||
|
|
||||||
|
struct Val {
|
||||||
|
enum VAL_T { INT, FLOAT, STRING, ARRAY, DICT, BOOL, JSNULL };
|
||||||
|
VAL_T type;
|
||||||
|
int i;
|
||||||
|
double f;
|
||||||
|
std::string str;
|
||||||
|
std::vector<Val> arr;
|
||||||
|
std::map<std::string, Val> dict;
|
||||||
|
|
||||||
|
Val() { type = DICT; }
|
||||||
|
Val(Null) { type = JSNULL; }
|
||||||
|
Val(const std::vector<Val>& arrC) { arr = arrC, type = ARRAY; }
|
||||||
|
Val(const std::map<std::string, Val>& dC) { dict = dC, type = DICT; }
|
||||||
|
Val(const std::string& strC) { str = strC, type = STRING; }
|
||||||
|
Val(const char* strC) { str = strC, type = STRING; }
|
||||||
|
Val(double fC) { f = fC, type = FLOAT; }
|
||||||
|
Val(int iC) { i = iC, type = INT; }
|
||||||
|
Val(bool fC) { i = fC, type = BOOL; }
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef int Int;
|
||||||
|
typedef double Float;
|
||||||
|
typedef bool Bool;
|
||||||
|
typedef std::string String;
|
||||||
|
typedef std::vector<Val> Array;
|
||||||
|
typedef std::map<std::string, Val> Dict;
|
||||||
|
|
||||||
|
// simple JSON writer class without much overhead
|
||||||
|
class Writer {
|
||||||
|
public:
|
||||||
|
explicit Writer(std::ostream* out);
|
||||||
|
Writer(std::ostream* out, size_t prec);
|
||||||
|
Writer(std::ostream* out, size_t prec, bool pretty);
|
||||||
|
Writer(std::ostream* out, size_t prec, bool pretty, size_t indent);
|
||||||
|
~Writer(){};
|
||||||
|
|
||||||
|
void obj();
|
||||||
|
void arr();
|
||||||
|
void key(const std::string& k);
|
||||||
|
void val(const std::string& v);
|
||||||
|
void val(const char* v);
|
||||||
|
void val(double v);
|
||||||
|
void val(int v);
|
||||||
|
void val(bool v);
|
||||||
|
void val(Null);
|
||||||
|
void val(const Val& v);
|
||||||
|
template <typename V>
|
||||||
|
void keyVal(const std::string& k, const V& v) {
|
||||||
|
key(k);
|
||||||
|
val(v);
|
||||||
|
}
|
||||||
|
|
||||||
|
void close();
|
||||||
|
void closeAll();
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::ostream* _out;
|
||||||
|
|
||||||
|
enum NODE_T { OBJ, ARR, KEY };
|
||||||
|
|
||||||
|
struct Node {
|
||||||
|
NODE_T type;
|
||||||
|
bool empty;
|
||||||
|
};
|
||||||
|
|
||||||
|
std::stack<Node> _stack;
|
||||||
|
|
||||||
|
bool _pretty;
|
||||||
|
size_t _indent;
|
||||||
|
size_t _floatPrec;
|
||||||
|
|
||||||
|
void valCheck();
|
||||||
|
void prettor();
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace json
|
||||||
|
} // namespace util
|
||||||
|
|
||||||
|
#endif // UTIL_JSON_WRITER_H_
|
Loading…
Reference in a new issue