CSCI3081W Drone Delivery System
json.h
1 #ifndef UTIL_JSON_H_
2 #define UTIL_JSON_H_
3 
4 #include <functional>
5 #include <initializer_list>
6 #include <iostream>
7 #include <string>
8 #include <utility>
9 
10 #include "picojson.h"
11 
12 class JsonObject;
13 class JsonArray;
14 
20 class JsonValue {
21  public:
25  JsonValue() : v() {}
26 
31  JsonValue(picojson::value val) : v(std::move(val)) {}
32 
37  JsonValue(double d) : v(d) {}
38 
43  JsonValue(int i) : v(static_cast<double>(i)) {}
44 
49  JsonValue(const std::string& s) : v(s) {}
50 
55  JsonValue(const char* s) : v(s) {}
56 
61  JsonValue(bool b) : v(b) {}
62 
67  JsonValue(const JsonObject& o);
68 
73  JsonValue(const JsonArray& a);
74 
79 
84  JsonValue(const JsonValue& other);
85 
91  JsonValue& operator=(const JsonValue& other);
92 
97  JsonValue(JsonValue&& other);
98 
104  JsonValue& operator=(JsonValue&& other) noexcept;
105 
113  static JsonValue fromReference(picojson::value& v);
114 
118  picojson::value& getValue() { return isRef ? ref.get() : v; }
119 
123  const picojson::value& getValue() const { return isRef ? ref.get() : v; }
124 
125  // DOUBLE
126 
130  operator double() const { return get<double>(); }
131 
136  JsonValue& operator=(double d) {
137  set(d);
138  return *this;
139  }
140 
141  // FLOAT
142 
146  operator float() const { return static_cast<float>(get<double>()); }
147 
152  JsonValue& operator=(float f) {
153  set(static_cast<double>(f));
154  return *this;
155  }
156 
157  // INT
158 
162  operator int() const { return static_cast<int>(get<double>()); }
163 
169  set(static_cast<double>(i));
170  return *this;
171  }
172 
173  // STRING
174 
178  operator std::string() const { return get<std::string>(); }
179 
184  JsonValue& operator=(const std::string& s) {
185  set(s);
186  return *this;
187  }
188 
193  JsonValue& operator=(const char* s) {
194  set(s);
195  return *this;
196  }
197 
198  // BOOL
199 
203  operator bool() const { return get<bool>(); }
204 
209  JsonValue& operator=(bool b) {
210  set(b);
211  return *this;
212  }
213 
214  // JSON OBJECT
215 
219  operator JsonObject() const;
220 
226 
227  // JSON ARRAY
228 
232  operator JsonArray() const;
233 
238  JsonValue& operator=(const JsonArray& a);
239 
244  std::string toString() const { return getValue().serialize(); }
245 
246  protected:
250  template <class T>
251  T get() const {
252  return getValue().get<T>();
253  }
254 
259  template <class T>
260  void set(const T& t) {
261  getValue() = picojson::value(t);
262  }
263 
264  union {
265  picojson::value v;
266  std::reference_wrapper<picojson::value> ref;
267  };
268 
269  bool isRef = false;
270 };
271 
277 class JsonObject {
278  public:
282  JsonObject() = default;
283 
288  JsonObject(picojson::object obj) : obj(std::move(obj)) {}
289 
303  JsonValue operator[](const std::string& key) {
304  return JsonValue::fromReference(obj[key]);
305  }
306 
319  JsonValue operator[](const std::string& key) const { return obj.at(key); }
320 
324  picojson::object& getObject() { return obj; }
325 
329  const picojson::object& getObject() const { return obj; }
330 
335  std::string toString() const { return picojson::value(obj).serialize(); }
336 
342  bool contains(const std::string& key) const {
343  return obj.find(key) != obj.end();
344  }
345 
349  std::vector<std::string> getKeys() const;
350 
351  protected:
352  picojson::object obj;
353 };
354 
360 class JsonArray {
361  public:
365  JsonArray() = default;
366 
371  JsonArray(picojson::array arr) : arr(std::move(arr)) {}
372 
381  JsonArray(const std::initializer_list<JsonValue> ls) {
382  for (const auto& val : ls) push(val);
383  }
384 
389  explicit JsonArray(int size) : arr(size) {}
390 
394  picojson::array& getArray() { return arr; }
395 
399  const picojson::array& getArray() const { return arr; }
400 
405  std::string toString() const { return picojson::value(arr).serialize(); }
406 
420  JsonValue operator[](int idx) { return JsonValue::fromReference(arr[idx]); }
421 
437  JsonValue operator[](int idx) const { return arr.at(idx); }
438 
446  JsonValue at(int idx) const { return arr.at(idx); }
447 
457  void push(const JsonValue& val) { arr.push_back(val.getValue()); }
458 
462  int size() const { return arr.size(); }
463 
468  void resize(int size) { arr.resize(size); }
469 
470  protected:
471  picojson::array arr;
472 };
473 
474 inline JsonValue::~JsonValue() {
475  if (!isRef) {
476  v.~value();
477  }
478 }
479 
480 inline JsonValue::JsonValue(const JsonValue& other) {
481  isRef = other.isRef;
482  if (isRef) {
483  ref = other.ref;
484  } else {
485  v = other.v;
486  }
487 }
488 
489 inline JsonValue& JsonValue::operator=(const JsonValue& other) {
490  if (this != &other) {
491  isRef = other.isRef;
492  if (isRef) {
493  ref = other.ref;
494  } else {
495  v = other.v;
496  }
497  }
498  return *this;
499 }
500 
501 inline JsonValue::JsonValue(JsonValue&& other) {
502  isRef = other.isRef;
503  if (isRef) {
504  ref = other.ref;
505  } else {
506  v = std::move(other.v);
507  }
508 }
509 
510 inline JsonValue& JsonValue::operator=(JsonValue&& other) noexcept {
511  isRef = other.isRef;
512  if (isRef) {
513  ref = other.ref;
514  } else {
515  v = std::move(other.v);
516  }
517  return *this;
518 }
519 
520 inline JsonValue JsonValue::fromReference(picojson::value& v) {
521  JsonValue val;
522  val.ref = v;
523  val.isRef = true;
524  return val;
525 }
526 
527 inline JsonValue& JsonValue::operator=(const JsonObject& o) {
528  set(o.getObject());
529  return *this;
530 }
531 
532 inline JsonValue::operator JsonObject() const {
533  return {get<picojson::object>()};
534 }
535 
536 inline JsonValue& JsonValue::operator=(const JsonArray& a) {
537  set(a.getArray());
538  return *this;
539 }
540 
541 inline JsonValue::operator JsonArray() const {
542  return {get<picojson::array>()};
543 }
544 
545 inline JsonValue::JsonValue(const JsonObject& o) : v(o.getObject()) {}
546 
547 inline JsonValue::JsonValue(const JsonArray& a) : v(a.getArray()) {}
548 
549 inline std::vector<std::string> JsonObject::getKeys() const {
550  std::vector<std::string> keys;
551  for (const auto& kv : obj) {
552  keys.push_back(kv.first);
553  }
554  return keys;
555 }
556 
560 inline std::ostream& operator<<(std::ostream& os, const JsonValue& val) {
561  os << val.toString();
562  return os;
563 }
564 
568 inline std::ostream& operator<<(std::ostream& os, const JsonObject& obj) {
569  os << obj.toString();
570  return os;
571 }
572 
576 inline std::ostream& operator<<(std::ostream& os, const JsonArray& array) {
577  os << array.toString();
578  return os;
579 }
580 
581 #endif // UTIL_JSON_H_
Manages a picojson::object, works with JsonValue to provide implicit casting.
Manages a picojson::value, provides implicit casting for valid JSON types.
Definition: json.h:20
JsonValue(const JsonArray &a)
Create a JsonValue from a JsonArray.
JsonValue(double d)
Create a JsonValue from a double.
Definition: json.h:37
JsonValue(picojson::value val)
Create a JsonValue from an existing picojson::value (creates a copy)
Definition: json.h:31
picojson::value & getValue()
Definition: json.h:118
JsonValue(bool b)
Create a JsonValue from a bool.
Definition: json.h:61
static JsonValue fromReference(picojson::value &v)
Create a a JsonValue using a reference to an existing picojson::value. Instead of creating a copy of ...
JsonValue(const char *s)
Create a JsonValue from a string literal.
Definition: json.h:55
JsonValue(int i)
Create a JsonValue from an int.
Definition: json.h:43
JsonValue(JsonValue &&other)
Move constructor.
JsonValue & operator=(float f)
set this value to a float
Definition: json.h:152
JsonValue & operator=(const JsonValue &other)
Copy operator.
void set(const T &t)
Sets the value from the specific template.
Definition: json.h:260
const picojson::value & getValue() const
Definition: json.h:123
JsonValue & operator=(bool b)
set this value to a bool
Definition: json.h:209
~JsonValue()
Destructor.
JsonValue(const JsonObject &o)
Create a JsonValue from a JsonObject.
JsonValue & operator=(const JsonObject &o)
set this value to a JsonObject
JsonValue & operator=(JsonValue &&other) noexcept
Move operator.
JsonValue(const std::string &s)
Create a JsonValue from a string.
Definition: json.h:49
JsonValue & operator=(const std::string &s)
set this value to a string
Definition: json.h:184
T get() const
Gets the value from the specific template.
Definition: json.h:251
std::string toString() const
Serialize this to valid JSON text.
Definition: json.h:244
JsonValue()
Default constructor.
Definition: json.h:25
JsonValue & operator=(const char *s)
set this value to a string
Definition: json.h:193
JsonValue & operator=(int i)
set this value to an int
Definition: json.h:168
JsonValue(const JsonValue &other)
Copy constructor.
JsonValue & operator=(double d)
set this value to a double
Definition: json.h:136
JsonValue & operator=(const JsonArray &a)
set this value to a JsonArray