libdballe  8.6
json.h
1 #ifndef DBALLE_CORE_JSON_H
2 #define DBALLE_CORE_JSON_H
3 
4 #include <wreport/varinfo.h>
5 #include <wreport/var.h>
6 #include <dballe/types.h>
7 #include <dballe/core/fwd.h>
8 #include <vector>
9 #include <ostream>
10 #include <istream>
11 
12 namespace dballe {
13 namespace core {
14 
15 struct JSONParseException : public std::runtime_error {
16  using std::runtime_error::runtime_error;
17 };
18 
19 
30 {
31 protected:
32  enum State {
33  LIST_FIRST,
34  LIST,
35  MAPPING_KEY_FIRST,
36  MAPPING_KEY,
37  MAPPING_VAL,
38  };
39  std::ostream& out;
40  std::vector<State> stack;
41 
43  void val_head();
44 
45  void jputc(char c);
46  void jputs(const char* s);
47 
48 public:
49  JSONWriter(std::ostream& out);
50  ~JSONWriter();
51 
56  void reset();
57 
58  void start_list();
59  void end_list();
60 
61  void start_mapping();
62  void end_mapping();
63 
64  void add_null();
65  void add_bool(bool val);
66  void add_int(int val);
67  void add_double(double val);
68  void add_cstring(const char* val);
69  void add_string(const std::string& val);
70  template<typename T>
71  void add_ostream(const T& val)
72  {
73  val_head();
74  out << val;
75  }
76 
77  void add_number(const std::string& val);
78  void add_level(const Level& val);
79  void add_trange(const Trange& val);
80  void add_datetime(const Datetime& val);
81  void add_datetimerange(const DatetimeRange& val);
82  void add_coords(const Coords& val);
83  void add_ident(const Ident& val);
84  void add_var(const wreport::Var& val);
85  void add_station(const Station& s);
86  void add_dbstation(const DBStation& s);
87  void add_values(const Values& values);
88  void add_dbvalues(const DBValues& values);
89  void add_break();
90 
91  void add(const std::string& val) { add_string(val); }
92  void add(const char* val) { add_cstring(val); }
93  void add(double val) { add_double(val); }
94  void add(int val) { add_int(val); }
95  void add(bool val) { add_bool(val); }
96  void add(size_t val) { add_ostream(val); }
97  void add(wreport::Varcode val) { add_int(val); }
98  void add(const Level& val) { add_level(val); }
99  void add(const Trange& val) { add_trange(val); }
100  void add(const Datetime& val) { add_datetime(val); }
101  void add(const DatetimeRange& val) { add_datetimerange(val); }
102  void add(const Coords& val) { add_coords(val); }
103  void add(const Ident& val) { add_ident(val); }
104  void add(const wreport::Var& val) { add_var(val); }
105  void add(const Station& s) { add_station(s); }
106  void add(const DBStation& s) { add_dbstation(s); }
107  void add(const Values& v) { add_values(v); }
108  void add(const DBValues& v) { add_dbvalues(v); }
109 
110  template<typename T>
111  void add(const char* a, T b)
112  {
113  add_cstring(a);
114  add(b);
115  }
116 
117  template<typename T>
118  void add_list(const T& val)
119  {
120  start_list();
121  for (const auto& i : val)
122  add(i);
123  end_list();
124  }
125 };
126 
131 {
132 public:
133  virtual ~JSONReader() {}
134 
135  virtual void on_start_list() = 0;
136  virtual void on_end_list() = 0;
137 
138  virtual void on_start_mapping() = 0;
139  virtual void on_end_mapping() = 0;
140 
141  virtual void on_add_null() = 0;
142  virtual void on_add_bool(bool val) = 0;
143  virtual void on_add_int(int val) = 0;
144  virtual void on_add_double(double val) = 0;
145  virtual void on_add_string(const std::string& val) = 0;
146 
147  // Parse a stream
148  void parse(std::istream& in);
149 };
150 
151 
152 namespace json {
153 
154 enum Element
155 {
156  JSON_OBJECT,
157  JSON_ARRAY,
158  JSON_STRING,
159  JSON_NUMBER,
160  JSON_TRUE,
161  JSON_FALSE,
162  JSON_NULL,
163 };
164 
165 struct Stream
166 {
167  std::istream& in;
168 
169  Stream(std::istream& in) : in(in) {}
170 
172  void expect_token(const char* token);
173 
175  void skip_spaces();
176 
178  template<typename T>
180  {
181  T res = 0;
182  while (true)
183  {
184  int c = in.peek();
185  if (c >= '0' and c <= '9')
186  res = res * 10 + in.get() - '0';
187  else
188  break;
189  }
190  skip_spaces();
191  return res;
192  }
193 
195  template<typename T>
197  {
198  if (in.peek() == '-')
199  {
200  in.get();
201  return -parse_unsigned<T>();
202  } else
203  return parse_unsigned<T>();
204  }
205 
207  double parse_double();
208 
215  std::tuple<std::string, bool> parse_number();
216 
218  std::string parse_string();
219 
221  Coords parse_coords();
222 
224  Station parse_station();
225 
227  DBStation parse_dbstation();
228 
230  Ident parse_ident();
231 
233  Level parse_level();
234 
236  Trange parse_trange();
237 
239  Datetime parse_datetime();
240 
242  DatetimeRange parse_datetimerange();
243 
244  template<typename T>
245  inline T parse() { throw wreport::error_unimplemented(); }
246 
248  void parse_array(std::function<void()> on_element);
249 
251  void parse_object(std::function<void(const std::string& key)> on_value);
252 
255  Element identify_next();
256 };
257 
258 template<> inline std::string Stream::parse() { return parse_string(); }
259 template<> inline Coords Stream::parse() { return parse_coords(); }
260 template<> inline Station Stream::parse() { return parse_station(); }
261 template<> inline DBStation Stream::parse() { return parse_dbstation(); }
262 template<> inline Ident Stream::parse() { return parse_ident(); }
263 template<> inline Level Stream::parse() { return parse_level(); }
264 template<> inline Trange Stream::parse() { return parse_trange(); }
265 template<> inline Datetime Stream::parse() { return parse_datetime(); }
266 template<> inline DatetimeRange Stream::parse() { return parse_datetimerange(); }
267 
268 }
269 
270 }
271 }
272 #endif
Common base types used by most of DB-All.e code.
Definition: json.h:165
Station information.
Definition: types.h:793
T parse_unsigned()
Parse an unsigned integer.
Definition: json.h:179
Coordinates.
Definition: types.h:368
Information on how a value has been sampled or computed with regards to time.
Definition: types.h:686
Definition: cmdline.h:18
Collection of DBValue objects, indexed by wreport::Varcode.
Definition: values.h:191
Vertical level or layer.
Definition: types.h:624
A station identifier, that can be any string (including the empty string) or a missing value...
Definition: types.h:747
uint16_t Varcode
Range of datetimes.
Definition: types.h:294
JSON sax-like parser.
Definition: json.h:130
T parse_signed()
Parse a signed integer.
Definition: json.h:196
Date and time.
Definition: types.h:164
JSON serializer.
Definition: json.h:29
Definition: types.h:850
Collection of Value objects, indexed by wreport::Varcode.
Definition: values.h:176