Веб-сайт самохостера Lotigara

summaryrefslogtreecommitdiff
path: root/source/core/StarJsonBuilder.hpp
blob: 46f192c0988a97573a2b71801c649a93052edb04 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
#pragma once

#include "StarJsonParser.hpp"
#include "StarJson.hpp"

namespace Star {

class JsonBuilderStream : public JsonStream {
public:
  virtual void beginObject();
  virtual void objectKey(char32_t const* s, size_t len);
  virtual void endObject();

  virtual void beginArray();
  virtual void endArray();

  virtual void putString(char32_t const* s, size_t len);
  virtual void putDouble(char32_t const* s, size_t len);
  virtual void putInteger(char32_t const* s, size_t len);
  virtual void putBoolean(bool b);
  virtual void putNull();

  virtual void putWhitespace(char32_t const* s, size_t len);
  virtual void putColon();
  virtual void putComma();

  size_t stackSize();
  Json takeTop();

private:
  void push(Json v);
  Json pop();
  void set(Json v);
  void pushSentry();
  bool isSentry();

  List<Maybe<Json>> m_stack;
};

template <typename Jsonlike>
class JsonStreamer {
public:
  static void toJsonStream(Jsonlike const& val, JsonStream& stream, bool sort);
};

template <>
class JsonStreamer<Json> {
public:
  static void toJsonStream(Json const& val, JsonStream& stream, bool sort);
};

template <typename InputIterator>
Json inputUtf8Json(InputIterator begin, InputIterator end, JsonParseType parseType) {
  typedef U8ToU32Iterator<InputIterator> Utf32Input;
  typedef JsonParser<Utf32Input> Parser;

  JsonBuilderStream stream;
  Parser parser(stream);
  Utf32Input wbegin(begin);
  Utf32Input wend(end);
  Utf32Input pend = parser.parse(wbegin, wend, parseType);

  if (parser.error())
    throw JsonParsingException(strf("Error parsing json: {} at {}:{}", parser.error(), parser.line(), parser.column()));
  else if (pend != wend)
    throw JsonParsingException(strf("Error extra data at end of input at {}:{}", parser.line(), parser.column()));

  return stream.takeTop();
}

template <typename OutputIterator>
void outputUtf8Json(Json const& val, OutputIterator out, int pretty, bool sort) {
  typedef Utf8OutputIterator<OutputIterator> Utf8Output;
  typedef JsonWriter<Utf8Output> Writer;
  Writer writer(Utf8Output(out), pretty);
  JsonStreamer<Json>::toJsonStream(val, writer, sort);
}

template <typename InputIterator, typename Stream = JsonBuilderStream, typename Jsonlike = Json>
Jsonlike inputUtf32Json(InputIterator begin, InputIterator end, JsonParseType parseType) {
  Stream stream;
  JsonParser<InputIterator> parser(stream);

  InputIterator pend = parser.parse(begin, end, parseType);

  if (parser.error()) {
    throw JsonParsingException(strf("Error parsing json: {} at {}:{}", parser.error(), parser.line(), parser.column()));
  } else if (pend != end) {
    throw JsonParsingException(strf("Error extra data at end of input at {}:{}", parser.line(), parser.column()));
  }

  return stream.takeTop();
}

template <typename OutputIterator, typename Jsonlike = Json>
void outputUtf32Json(Jsonlike const& val, OutputIterator out, int pretty, bool sort) {
  JsonWriter<OutputIterator> writer(out, pretty);
  JsonStreamer<Jsonlike>::toJsonStream(val, writer, sort);
}

}