cesium-native  0.41.0
ArrayJsonHandler.h
1 #pragma once
2 
3 #include "CesiumUtility/Assert.h"
4 #include "DoubleJsonHandler.h"
5 #include "IntegerJsonHandler.h"
6 #include "JsonHandler.h"
7 #include "Library.h"
8 #include "StringJsonHandler.h"
9 
10 #include <functional>
11 #include <memory>
12 #include <vector>
13 
14 namespace CesiumJsonReader {
15 template <typename T, typename THandler>
16 class CESIUMJSONREADER_API ArrayJsonHandler : public JsonHandler {
17 public:
18  using ValueType = std::vector<T>;
19 
20  template <typename... Ts>
21  ArrayJsonHandler(Ts&&... args) noexcept
22  : JsonHandler(),
23  _handlerFactory(
24  std::bind(handlerFactory<Ts...>, std::forward<Ts>(args)...)),
25  _objectHandler() {}
26 
27  void reset(IJsonHandler* pParent, std::vector<T>* pArray) {
28  JsonHandler::reset(pParent);
29  this->_pArray = pArray;
30  this->_arrayIsOpen = false;
31  this->_objectHandler.reset(this->_handlerFactory());
32  }
33 
34  virtual IJsonHandler* readNull() override {
35  return this->invalid("A null")->readNull();
36  }
37 
38  virtual IJsonHandler* readBool(bool b) override {
39  return this->invalid("A boolean")->readBool(b);
40  }
41 
42  virtual IJsonHandler* readInt32(int32_t i) override {
43  return this->invalid("An integer")->readInt32(i);
44  }
45 
46  virtual IJsonHandler* readUint32(uint32_t i) override {
47  return this->invalid("An integer")->readUint32(i);
48  }
49 
50  virtual IJsonHandler* readInt64(int64_t i) override {
51  return this->invalid("An integer")->readInt64(i);
52  }
53 
54  virtual IJsonHandler* readUint64(uint64_t i) override {
55  return this->invalid("An integer")->readUint64(i);
56  }
57 
58  virtual IJsonHandler* readDouble(double d) override {
59  return this->invalid("A double (floating-point)")->readDouble(d);
60  }
61 
62  virtual IJsonHandler* readString(const std::string_view& str) override {
63  return this->invalid("A string")->readString(str);
64  }
65 
66  virtual IJsonHandler* readObjectStart() override {
67  if (!this->_arrayIsOpen) {
68  return this->invalid("An object")->readObjectStart();
69  }
70 
71  CESIUM_ASSERT(this->_pArray);
72  T& o = this->_pArray->emplace_back();
73  this->_objectHandler->reset(this, &o);
74  return this->_objectHandler->readObjectStart();
75  }
76 
77  virtual IJsonHandler*
78  readObjectKey(const std::string_view& /*str*/) noexcept override {
79  return nullptr;
80  }
81 
82  virtual IJsonHandler* readObjectEnd() noexcept override { return nullptr; }
83 
84  virtual IJsonHandler* readArrayStart() override {
85  if (this->_arrayIsOpen) {
86  return this->invalid("An array")->readArrayStart();
87  }
88 
89  this->_arrayIsOpen = true;
90  this->_pArray->clear();
91  return this;
92  }
93 
94  virtual IJsonHandler* readArrayEnd() override { return this->parent(); }
95 
96  virtual void reportWarning(
97  const std::string& warning,
98  std::vector<std::string>&& context =
99  std::vector<std::string>()) override {
100  context.push_back(
101  std::string("[") + std::to_string(this->_pArray->size()) + "]");
102  this->parent()->reportWarning(warning, std::move(context));
103  }
104 
105 private:
106  IJsonHandler* invalid(const std::string& type) {
107  if (this->_arrayIsOpen) {
108  this->reportWarning(
109  type + " value is not allowed in the object array and has been "
110  "replaced with a default value.");
111  this->_pArray->emplace_back();
112  return this->ignoreAndContinue();
113  } else {
114  this->reportWarning(type + " is not allowed and has been ignored.");
115  return this->ignoreAndReturnToParent();
116  }
117  }
118 
119  template <typename... Ts> static THandler* handlerFactory(Ts&&... args) {
120  return new THandler(std::forward<Ts>(args)...);
121  }
122 
123  std::vector<T>* _pArray = nullptr;
124  bool _arrayIsOpen = false;
125 
126  std::function<THandler*()> _handlerFactory;
127  std::unique_ptr<THandler> _objectHandler;
128 };
129 
130 template <>
131 class CESIUMJSONREADER_API ArrayJsonHandler<double, DoubleJsonHandler>
132  : public JsonHandler {
133 public:
134  using ValueType = std::vector<double>;
135 
136  ArrayJsonHandler() noexcept : JsonHandler() {}
137 
138  void reset(IJsonHandler* pParent, std::vector<double>* pArray) {
139  JsonHandler::reset(pParent);
140  this->_pArray = pArray;
141  this->_arrayIsOpen = false;
142  }
143 
144  virtual IJsonHandler* readNull() override {
145  return this->invalid("A null")->readNull();
146  }
147 
148  virtual IJsonHandler* readBool(bool b) override {
149  return this->invalid("A bool")->readBool(b);
150  }
151 
152  virtual IJsonHandler* readInt32(int32_t i) override {
153  if (!this->_arrayIsOpen) {
154  return this->invalid("An integer")->readInt32(i);
155  }
156 
157  CESIUM_ASSERT(this->_pArray);
158  this->_pArray->emplace_back(static_cast<double>(i));
159  return this;
160  }
161 
162  virtual IJsonHandler* readUint32(uint32_t i) override {
163  if (!this->_arrayIsOpen) {
164  return this->invalid("An integer")->readUint32(i);
165  }
166 
167  CESIUM_ASSERT(this->_pArray);
168  this->_pArray->emplace_back(static_cast<double>(i));
169  return this;
170  }
171 
172  virtual IJsonHandler* readInt64(int64_t i) override {
173  if (!this->_arrayIsOpen) {
174  return this->invalid("An integer")->readInt64(i);
175  }
176 
177  CESIUM_ASSERT(this->_pArray);
178  this->_pArray->emplace_back(static_cast<double>(i));
179  return this;
180  }
181 
182  virtual IJsonHandler* readUint64(uint64_t i) override {
183  if (!this->_arrayIsOpen) {
184  return this->invalid("An integer")->readUint64(i);
185  }
186 
187  CESIUM_ASSERT(this->_pArray);
188  this->_pArray->emplace_back(static_cast<double>(i));
189  return this;
190  }
191 
192  virtual IJsonHandler* readDouble(double d) override {
193  if (!this->_arrayIsOpen) {
194  return this->invalid("An integer")->readDouble(d);
195  }
196 
197  CESIUM_ASSERT(this->_pArray);
198  this->_pArray->emplace_back(d);
199  return this;
200  }
201 
202  virtual IJsonHandler* readString(const std::string_view& str) override {
203  return this->invalid("A string")->readString(str);
204  }
205 
206  virtual IJsonHandler* readObjectStart() override {
207  return this->invalid("An object")->readObjectStart();
208  }
209 
210  virtual IJsonHandler* readArrayStart() override {
211  if (this->_arrayIsOpen) {
212  return this->invalid("An array")->readArrayStart();
213  }
214 
215  this->_arrayIsOpen = true;
216  this->_pArray->clear();
217  return this;
218  }
219 
220  virtual IJsonHandler* readArrayEnd() override { return this->parent(); }
221 
222  virtual void reportWarning(
223  const std::string& warning,
224  std::vector<std::string>&& context =
225  std::vector<std::string>()) override {
226  context.push_back(
227  std::string("[") + std::to_string(this->_pArray->size()) + "]");
228  this->parent()->reportWarning(warning, std::move(context));
229  }
230 
231 private:
232  IJsonHandler* invalid(const std::string& type) {
233  if (this->_arrayIsOpen) {
234  this->reportWarning(
235  type + " value is not allowed in the double array and has been "
236  "replaced with a default value.");
237  this->_pArray->emplace_back();
238  return this->ignoreAndContinue();
239  } else {
240  this->reportWarning(type + " is not allowed and has been ignored.");
241  return this->ignoreAndReturnToParent();
242  }
243  }
244 
245  std::vector<double>* _pArray = nullptr;
246  bool _arrayIsOpen = false;
247 };
248 
249 template <typename T>
250 class CESIUMJSONREADER_API ArrayJsonHandler<T, IntegerJsonHandler<T>>
251  : public JsonHandler {
252 public:
253  using ValueType = std::vector<T>;
254 
255  ArrayJsonHandler() noexcept : JsonHandler() {}
256 
257  void reset(IJsonHandler* pParent, std::vector<T>* pArray) {
258  JsonHandler::reset(pParent);
259  this->_pArray = pArray;
260  this->_arrayIsOpen = false;
261  }
262 
263  virtual IJsonHandler* readNull() override {
264  return this->invalid("A null")->readNull();
265  }
266 
267  virtual IJsonHandler* readBool(bool b) override {
268  return this->invalid("A bool")->readBool(b);
269  }
270 
271  virtual IJsonHandler* readInt32(int32_t i) override {
272  if (!this->_arrayIsOpen) {
273  return this->invalid("An integer")->readInt32(i);
274  }
275 
276  CESIUM_ASSERT(this->_pArray);
277  this->_pArray->emplace_back(static_cast<T>(i));
278  return this;
279  }
280 
281  virtual IJsonHandler* readUint32(uint32_t i) override {
282  if (!this->_arrayIsOpen) {
283  return this->invalid("An integer")->readUint32(i);
284  }
285 
286  CESIUM_ASSERT(this->_pArray);
287  this->_pArray->emplace_back(static_cast<T>(i));
288  return this;
289  }
290 
291  virtual IJsonHandler* readInt64(int64_t i) override {
292  if (!this->_arrayIsOpen) {
293  return this->invalid("An integer")->readInt64(i);
294  }
295 
296  CESIUM_ASSERT(this->_pArray);
297  this->_pArray->emplace_back(static_cast<T>(i));
298  return this;
299  }
300 
301  virtual IJsonHandler* readUint64(uint64_t i) override {
302  if (!this->_arrayIsOpen) {
303  return this->invalid("An integer")->readUint64(i);
304  }
305 
306  CESIUM_ASSERT(this->_pArray);
307  this->_pArray->emplace_back(static_cast<T>(i));
308  return this;
309  }
310 
311  virtual IJsonHandler* readDouble(double d) override {
312  return this->invalid("A double (floating-point)")->readDouble(d);
313  }
314 
315  virtual IJsonHandler* readString(const std::string_view& str) override {
316  return this->invalid("A string")->readString(str);
317  }
318 
319  virtual IJsonHandler* readObjectStart() override {
320  return this->invalid("An object")->readObjectStart();
321  }
322 
323  virtual IJsonHandler* readArrayStart() override {
324  if (this->_arrayIsOpen) {
325  return this->invalid("An array")->readArrayStart();
326  }
327 
328  this->_arrayIsOpen = true;
329  this->_pArray->clear();
330  return this;
331  }
332 
333  virtual IJsonHandler* readArrayEnd() override { return this->parent(); }
334 
335  virtual void reportWarning(
336  const std::string& warning,
337  std::vector<std::string>&& context =
338  std::vector<std::string>()) override {
339  context.push_back(
340  std::string("[") + std::to_string(this->_pArray->size()) + "]");
341  this->parent()->reportWarning(warning, std::move(context));
342  }
343 
344 private:
345  IJsonHandler* invalid(const std::string& type) {
346  if (this->_arrayIsOpen) {
347  this->reportWarning(
348  type + " value is not allowed in the integer array and has been "
349  "replaced with a default value.");
350  this->_pArray->emplace_back();
351  return this->ignoreAndContinue();
352  } else {
353  this->reportWarning(type + " is not allowed and has been ignored.");
354  return this->ignoreAndReturnToParent();
355  }
356  }
357 
358  std::vector<T>* _pArray = nullptr;
359  bool _arrayIsOpen = false;
360 };
361 
362 template <>
363 class CESIUMJSONREADER_API ArrayJsonHandler<std::string, StringJsonHandler>
364  : public JsonHandler {
365 public:
366  using ValueType = std::vector<std::string>;
367 
368  ArrayJsonHandler() noexcept : JsonHandler() {}
369 
370  void reset(IJsonHandler* pParent, std::vector<std::string>* pArray) {
371  JsonHandler::reset(pParent);
372  this->_pArray = pArray;
373  this->_arrayIsOpen = false;
374  }
375 
376  virtual IJsonHandler* readNull() override {
377  return this->invalid("A null")->readNull();
378  }
379 
380  virtual IJsonHandler* readBool(bool b) override {
381  return this->invalid("A bool")->readBool(b);
382  }
383 
384  virtual IJsonHandler* readInt32(int32_t i) override {
385  return this->invalid("An integer")->readInt32(i);
386  }
387 
388  virtual IJsonHandler* readUint32(uint32_t i) override {
389  return this->invalid("An integer")->readUint32(i);
390  }
391 
392  virtual IJsonHandler* readInt64(int64_t i) override {
393  return this->invalid("An integer")->readInt64(i);
394  }
395 
396  virtual IJsonHandler* readUint64(uint64_t i) override {
397  return this->invalid("An integer")->readUint64(i);
398  }
399 
400  virtual IJsonHandler* readDouble(double d) override {
401  return this->invalid("A double (floating-point)")->readDouble(d);
402  }
403 
404  virtual IJsonHandler* readObjectStart() override {
405  return this->invalid("An object")->readObjectStart();
406  }
407 
408  virtual IJsonHandler* readArrayStart() override {
409  if (this->_arrayIsOpen) {
410  return this->invalid("An array")->readArrayStart();
411  }
412 
413  this->_arrayIsOpen = true;
414  this->_pArray->clear();
415  return this;
416  }
417 
418  virtual IJsonHandler* readArrayEnd() override { return this->parent(); }
419 
420  virtual IJsonHandler* readString(const std::string_view& str) override {
421  if (!this->_arrayIsOpen) {
422  return this->invalid("A string")->readString(str);
423  }
424 
425  CESIUM_ASSERT(this->_pArray);
426  this->_pArray->emplace_back(str);
427  return this;
428  }
429 
430  virtual void reportWarning(
431  const std::string& warning,
432  std::vector<std::string>&& context =
433  std::vector<std::string>()) override {
434  context.push_back(
435  std::string("[") + std::to_string(this->_pArray->size()) + "]");
436  this->parent()->reportWarning(warning, std::move(context));
437  }
438 
439 private:
440  IJsonHandler* invalid(const std::string& type) {
441  if (this->_arrayIsOpen) {
442  this->reportWarning(
443  type + " value is not allowed in the string array and has been "
444  "replaced with a default value.");
445  this->_pArray->emplace_back();
446  return this->ignoreAndContinue();
447  } else {
448  this->reportWarning(type + " is not allowed and has been ignored.");
449  return this->ignoreAndReturnToParent();
450  }
451  }
452 
453  std::vector<std::string>* _pArray = nullptr;
454  bool _arrayIsOpen = false;
455 };
456 
457 template <typename T, typename THandler>
458 class CESIUMJSONREADER_API
459  ArrayJsonHandler<std::vector<T>, ArrayJsonHandler<T, THandler>>
460  : public JsonHandler {
461 public:
462  using ValueType = std::vector<T>;
463 
464  template <typename... Ts>
465  ArrayJsonHandler(Ts&&... args) noexcept
466  : JsonHandler(),
467  _handlerFactory(
468  std::bind(handlerFactory<Ts...>, std::forward<Ts>(args)...)),
469  _elementHandler() {}
470 
471  void reset(IJsonHandler* pParent, std::vector<std::vector<T>>* pArray) {
472  JsonHandler::reset(pParent);
473  this->_pArray = pArray;
474  this->_arrayIsOpen = false;
475  this->_elementHandler.reset(this->_handlerFactory());
476  }
477 
478  virtual IJsonHandler* readNull() override {
479  return this->invalid("A null")->readNull();
480  }
481 
482  virtual IJsonHandler* readBool(bool b) override {
483  return this->invalid("A bool")->readBool(b);
484  }
485 
486  virtual IJsonHandler* readInt32(int32_t i) override {
487  return this->invalid("An integer")->readInt32(i);
488  }
489 
490  virtual IJsonHandler* readUint32(uint32_t i) override {
491  return this->invalid("An integer")->readUint32(i);
492  }
493 
494  virtual IJsonHandler* readInt64(int64_t i) override {
495  return this->invalid("An integer")->readInt64(i);
496  }
497 
498  virtual IJsonHandler* readUint64(uint64_t i) override {
499  return this->invalid("An integer")->readUint64(i);
500  }
501 
502  virtual IJsonHandler* readDouble(double d) override {
503  return this->invalid("A double (floating-point)")->readDouble(d);
504  }
505 
506  virtual IJsonHandler* readString(const std::string_view& str) override {
507  return this->invalid("A string")->readString(str);
508  }
509 
510  virtual IJsonHandler* readObjectStart() override {
511  return this->invalid("An object")->readObjectStart();
512  }
513 
514  virtual IJsonHandler* readArrayStart() override {
515  if (this->_arrayIsOpen) {
516  CESIUM_ASSERT(this->_pArray);
517  std::vector<T>& o = this->_pArray->emplace_back();
518  this->_elementHandler->reset(this, &o);
519  return this->_elementHandler->readArrayStart();
520  } else {
521  this->_arrayIsOpen = true;
522  this->_pArray->clear();
523  return this;
524  }
525  }
526 
527  virtual IJsonHandler* readArrayEnd() override { return this->parent(); }
528 
529  virtual void reportWarning(
530  const std::string& warning,
531  std::vector<std::string>&& context =
532  std::vector<std::string>()) override {
533  context.push_back(
534  std::string("[") + std::to_string(this->_pArray->size()) + "]");
535  this->parent()->reportWarning(warning, std::move(context));
536  }
537 
538 private:
539  IJsonHandler* invalid(const std::string& type) {
540  if (this->_arrayIsOpen) {
541  this->reportWarning(
542  type + " value is not allowed in the array of arrays and has been "
543  "replaced with a default value.");
544  this->_pArray->emplace_back();
545  return this->ignoreAndContinue();
546  } else {
547  this->reportWarning(type + " is not allowed and has been ignored.");
548  return this->ignoreAndReturnToParent();
549  }
550  }
551 
552  template <typename... Ts>
553  static ArrayJsonHandler<T, THandler>* handlerFactory(Ts&&... args) {
554  return new ArrayJsonHandler<T, THandler>(std::forward<Ts>(args)...);
555  }
556 
557  std::vector<std::vector<T>>* _pArray = nullptr;
558  bool _arrayIsOpen = false;
559 
560  std::function<ArrayJsonHandler<T, THandler>*()> _handlerFactory;
561  std::unique_ptr<ArrayJsonHandler<T, THandler>> _elementHandler;
562 };
563 
564 } // namespace CesiumJsonReader
Classes for reading JSON.