Writer.cpp 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174
  1. // Copyright 2018, University of Freiburg,
  2. // Chair of Algorithms and Data Structures.
  3. // Authors: Patrick Brosi <brosi@informatik.uni-freiburg.de>
  4. #include <iomanip>
  5. #include "Writer.h"
  6. #include "util/String.h"
  7. using namespace util;
  8. using namespace json;
  9. using std::ostream;
  10. using std::string;
  11. using std::map;
  12. // _____________________________________________________________________________
  13. Writer::Writer(std::ostream* out)
  14. : _out(out), _pretty(false), _indent(2), _floatPrec(10) {}
  15. // _____________________________________________________________________________
  16. Writer::Writer(std::ostream* out, size_t prec)
  17. : _out(out), _pretty(false), _indent(2), _floatPrec(prec) {}
  18. // _____________________________________________________________________________
  19. Writer::Writer(std::ostream* out, size_t prec, bool pret)
  20. : _out(out), _pretty(pret), _indent(2), _floatPrec(prec) {}
  21. // _____________________________________________________________________________
  22. Writer::Writer(std::ostream* out, size_t prec, bool pret, size_t indent)
  23. : _out(out), _pretty(pret), _indent(indent), _floatPrec(prec) {}
  24. // _____________________________________________________________________________
  25. void Writer::obj() {
  26. if (!_stack.empty() && _stack.top().type == OBJ)
  27. throw WriterException("Object not allowed as key");
  28. if (!_stack.empty() && _stack.top().type == KEY) _stack.pop();
  29. if (!_stack.empty() && _stack.top().type == ARR) valCheck();
  30. if (_stack.size() && _stack.top().type == ARR) prettor();
  31. *_out << "{";
  32. _stack.push({OBJ, 1});
  33. }
  34. // _____________________________________________________________________________
  35. void Writer::key(const std::string& k) {
  36. if (_stack.empty() || _stack.top().type != OBJ)
  37. throw WriterException("Keys only allowed in objects.");
  38. if (!_stack.top().empty) (*_out) << "," << (_pretty ? " " : "");
  39. _stack.top().empty = 0;
  40. prettor();
  41. *_out << "\"" << k << "\""
  42. << ":" << (_pretty ? " " : "");
  43. _stack.push({KEY, 1});
  44. }
  45. // _____________________________________________________________________________
  46. void Writer::valCheck() {
  47. if (_stack.empty() || (_stack.top().type != KEY && _stack.top().type != ARR))
  48. throw WriterException("Value not allowed here.");
  49. if (!_stack.empty() && _stack.top().type == KEY) _stack.pop();
  50. if (!_stack.empty() && _stack.top().type == ARR) {
  51. if (!_stack.top().empty) (*_out) << "," << (_pretty ? " " : "");
  52. _stack.top().empty = 0;
  53. }
  54. }
  55. // _____________________________________________________________________________
  56. void Writer::val(const std::string& v) {
  57. valCheck();
  58. *_out << "\"" << util::jsonStringEscape(v) << "\"";
  59. }
  60. // _____________________________________________________________________________
  61. void Writer::val(const char* v) {
  62. valCheck();
  63. *_out << "\"" << util::jsonStringEscape(v) << "\"";
  64. }
  65. // _____________________________________________________________________________
  66. void Writer::val(bool v) {
  67. valCheck();
  68. *_out << (v ? "true" : "false");
  69. }
  70. // _____________________________________________________________________________
  71. void Writer::val(int v) {
  72. valCheck();
  73. *_out << v;
  74. }
  75. // _____________________________________________________________________________
  76. void Writer::val(double v) {
  77. valCheck();
  78. *_out << std::fixed << std::setprecision(_floatPrec) << v;
  79. }
  80. // _____________________________________________________________________________
  81. void Writer::val(Null) {
  82. valCheck();
  83. *_out << "null";
  84. }
  85. // _____________________________________________________________________________
  86. void Writer::val(const Val& v) {
  87. switch (v.type) {
  88. case Val::JSNULL:
  89. val(Null());
  90. return;
  91. case Val::INT:
  92. val(v.i);
  93. return;
  94. case Val::FLOAT:
  95. val(v.f);
  96. return;
  97. case Val::BOOL:
  98. val((bool)v.i);
  99. return;
  100. case Val::STRING:
  101. val(v.str);
  102. return;
  103. case Val::ARRAY:
  104. arr();
  105. for (const Val& varr : v.arr) val(varr);
  106. close();
  107. return;
  108. case Val::DICT:
  109. obj();
  110. for (const auto& vdic : v.dict) {
  111. keyVal(vdic.first, vdic.second);
  112. };
  113. close();
  114. return;
  115. }
  116. }
  117. // _____________________________________________________________________________
  118. void Writer::arr() {
  119. if (!_stack.empty() && _stack.top().type == OBJ)
  120. throw WriterException("Array not allowed as key");
  121. if (!_stack.empty() && _stack.top().type == KEY) _stack.pop();
  122. if (!_stack.empty() && _stack.top().type == ARR) valCheck();
  123. *_out << "[";
  124. _stack.push({ARR, 1});
  125. }
  126. // _____________________________________________________________________________
  127. void Writer::prettor() {
  128. if (_pretty) {
  129. *_out << "\n";
  130. for (size_t i = 0; i < _indent * _stack.size(); i++) (*_out) << " ";
  131. }
  132. }
  133. // _____________________________________________________________________________
  134. void Writer::closeAll() {
  135. while (!_stack.empty()) close();
  136. }
  137. // _____________________________________________________________________________
  138. void Writer::close() {
  139. if (_stack.empty()) return;
  140. switch (_stack.top().type) {
  141. case OBJ:
  142. _stack.pop();
  143. prettor();
  144. (*_out) << "}";
  145. break;
  146. case ARR:
  147. _stack.pop();
  148. (*_out) << "]";
  149. break;
  150. case KEY:
  151. throw WriterException("Missing value.");
  152. }
  153. }