Click
Loading...
Searching...
No Matches
json.hh
1// -*- c-basic-offset: 4 -*-
2#ifndef CLICK_JSON_HH
3#define CLICK_JSON_HH 1
4#include <click/straccum.hh>
5#include <click/hashtable.hh>
6#include <click/vector.hh>
7#include <click/glue.hh>
8#include <click/pair.hh>
9#if CLICK_USERLEVEL
10# include <iterator>
11#endif
12CLICK_DECLS
13
14template <typename P> class Json_proxy_base;
15template <typename T> class Json_object_proxy;
16template <typename T> class Json_object_str_proxy;
17template <typename T> class Json_array_proxy;
18class Json_get_proxy;
19
20class Json { public:
21
22 enum json_type { // order matters
23 j_null = 0, j_array, j_object, j_int, j_double, j_bool, j_string
24 };
25
26 const char *class_name() const { return "Json"; }
27
28 typedef int size_type;
29
30 typedef Pair<const String, Json> object_value_type;
31 class object_iterator;
32 class const_object_iterator;
33
34 typedef Json array_value_type;
35 class array_iterator;
36 class const_array_iterator;
37
38 class iterator;
39 class const_iterator;
40
41 typedef bool (Json::*unspecified_bool_type)() const;
42 struct unparse_manipulator;
43
44 typedef uninitialized_type uninitialized_t;
45
46 // Constructors
47 inline Json();
48 inline Json(const uninitialized_t &);
49 inline Json(const Json &x);
50#if HAVE_CXX_RVALUE_REFERENCES
51 inline Json(Json &&x);
52#endif
53 inline Json(int x);
54 inline Json(unsigned x);
55 inline Json(long x);
56 inline Json(unsigned long x);
57#if HAVE_LONG_LONG
58 inline Json(long long x);
59 inline Json(unsigned long long x);
60#endif
61#if HAVE_FLOAT_TYPES
62 inline Json(double x);
63#endif
64 inline Json(bool x);
65 inline Json(const String &x);
66 inline Json(const char *x);
67 template <typename T> inline Json(const Vector<T> &x);
68 template <typename T> inline Json(T first, T last);
69 template <typename T> inline Json(const HashTable<String, T> &x);
70 inline ~Json();
71
72 static inline const Json &make_null();
73 static inline Json make_array();
74 static inline Json make_object();
75 static inline Json make_string(const String &x);
76 static inline Json make_string(const char *s, int len);
77
78 static void static_initialize();
79
80 // Type information
81 inline operator unspecified_bool_type() const;
82 inline bool operator!() const;
83
84 inline json_type type() const;
85 inline bool is_null() const;
86 inline bool is_int() const;
87 inline bool is_double() const;
88 inline bool is_number() const;
89 inline bool is_bool() const;
90 inline bool is_string() const;
91 inline bool is_array() const;
92 inline bool is_object() const;
93 inline bool is_primitive() const;
94
95 inline bool empty() const;
96 inline size_type size() const;
97
98 // Primitive extractors
99 inline long to_i() const;
100 inline uint64_t to_u64() const;
101 bool to_i(int &x) const;
102 bool to_i(unsigned &x) const;
103 bool to_i(long &x) const;
104 bool to_i(unsigned long &x) const;
105#if HAVE_LONG_LONG
106 bool to_i(long long &x) const;
107 bool to_i(unsigned long long &x) const;
108#endif
109 inline long as_i() const;
110
111#if HAVE_FLOAT_TYPES
112 double to_d() const;
113 inline bool to_d(double &x) const;
114 inline double as_d() const;
115#endif
116
117 inline bool to_b() const;
118 inline bool to_b(bool &x) const;
119 inline bool as_b() const;
120
121 inline const String &to_s() const;
122 inline bool to_s(String &x) const;
123 inline const String &as_s() const;
124 inline const char *c_str() const;
125
126 // Object methods
127 inline size_type count(const StringRef &key) const;
128 inline const Json &get(const StringRef &key) const;
129 inline Json &get_insert(const String &key);
130 inline Json &get_insert(const StringRef &key);
131 inline Json &get_insert(const char *key);
132
133 inline long get_i(const StringRef &key) const;
134#if HAVE_FLOAT_TYPES
135 inline double get_d(const StringRef &key) const;
136#endif
137 inline bool get_b(const StringRef &key) const;
138 inline const String &get_s(const StringRef &key) const;
139
140 inline const Json_get_proxy get(const StringRef &key, Json &x) const;
141 inline const Json_get_proxy get(const StringRef &key, int &x) const;
142 inline const Json_get_proxy get(const StringRef &key, unsigned &x) const;
143 inline const Json_get_proxy get(const StringRef &key, long &x) const;
144 inline const Json_get_proxy get(const StringRef &key, unsigned long &x) const;
145#if HAVE_LONG_LONG
146 inline const Json_get_proxy get(const StringRef &key, long long &x) const;
147 inline const Json_get_proxy get(const StringRef &key, unsigned long long &x) const;
148#endif
149#if HAVE_FLOAT_TYPES
150 inline const Json_get_proxy get(const StringRef &key, double &x) const;
151#endif
152 inline const Json_get_proxy get(const StringRef &key, bool &x) const;
153 inline const Json_get_proxy get(const StringRef &key, String &x) const;
154
155 const Json &operator[](const StringRef &key) const;
156 inline Json_object_proxy<Json> operator[](const String &key);
157 inline Json_object_str_proxy<Json> operator[](const StringRef &key);
158 inline Json_object_str_proxy<Json> operator[](const char *key);
159
160 inline const Json &at(const StringRef &key) const;
161 inline Json &at_insert(const String &key);
162 inline Json &at_insert(const StringRef &key);
163 inline Json &at_insert(const char *key);
164
165 template <typename T> inline Json &set(const String &key, T value);
166#if HAVE_CXX_RVALUE_REFERENCES
167 inline Json &set(const String &key, Json &&x);
168#endif
169 inline Json &unset(const StringRef &key);
170
171 inline Pair<object_iterator, bool> insert(const object_value_type &x);
172 inline object_iterator insert(object_iterator position,
173 const object_value_type &x);
174 inline size_type erase(const StringRef &key);
175
176 inline Json &merge(const Json &x);
177 template <typename P> inline Json &merge(const Json_proxy_base<P> &x);
178
179 // Array methods
180 inline const Json &get(size_type x) const;
181 inline Json &get_insert(size_type x);
182
183 inline const Json &operator[](size_type x) const;
184 inline Json_array_proxy<Json> operator[](size_type x);
185
186 inline const Json &at(size_type x) const;
187 inline Json &at_insert(size_type x);
188
189 inline const Json &back() const;
190 inline Json &back();
191
192 template <typename T> inline Json &push_back(T x);
193#if HAVE_CXX_RVALUE_REFERENCES
194 inline Json &push_back(Json &&x);
195#endif
196 inline void pop_back();
197
198 // Iteration
199 inline const_object_iterator obegin() const;
200 inline const_object_iterator oend() const;
201 inline object_iterator obegin();
202 inline object_iterator oend();
203 inline const_object_iterator cobegin() const;
204 inline const_object_iterator coend() const;
205
206 inline const_array_iterator abegin() const;
207 inline const_array_iterator aend() const;
208 inline array_iterator abegin();
209 inline array_iterator aend();
210 inline const_array_iterator cabegin() const;
211 inline const_array_iterator caend() const;
212
213 inline const_iterator begin() const;
214 inline const_iterator end() const;
215 inline iterator begin();
216 inline iterator end();
217 inline const_iterator cbegin() const;
218 inline const_iterator cend() const;
219
220 // Unparsing
221 static inline unparse_manipulator indent_depth(int x);
222 static inline unparse_manipulator tab_width(int x);
223
224 inline String unparse() const;
225 inline String unparse(bool add_newline) const;
226 inline String unparse(const unparse_manipulator &m,
227 bool add_newline = false) const;
228 void unparse(StringAccum &sa) const;
229 inline void unparse(StringAccum &sa, const unparse_manipulator &m) const;
230
231 // Parsing
232 inline bool assign_parse(const String &str);
233 inline bool assign_parse(const char *first, const char *last);
234
235 static inline Json parse(const String &str);
236 static inline Json parse(const char *first, const char *last);
237
238 // Assignment
239 inline Json &operator=(const Json &x);
240#if HAVE_CXX_RVALUE_REFERENCES
241 inline Json &operator=(Json &&x);
242#endif
243 template <typename P> inline Json &operator=(const Json_proxy_base<P> &x);
244
245 inline Json &operator++();
246 inline void operator++(int);
247 inline Json &operator--();
248 inline void operator--(int);
249 inline Json &operator+=(int x);
250 inline Json &operator+=(long x);
251#if HAVE_FLOAT_TYPES
252 inline Json &operator+=(double x);
253#endif
254
255 inline void swap(Json &x);
256
257 private:
258
259 enum {
260 st_initial = 0, st_array_initial = 1, st_array_delim = 2,
261 st_array_value = 3, st_object_initial = 4, st_object_delim = 5,
262 st_object_key = 6, st_object_colon = 7, st_object_value = 8,
263 max_depth = 2048
264 };
265
266 typedef Vector<Json> JsonVector;
267
268 struct ComplexJson {
269 int refcount;
270 ComplexJson()
271 : refcount(1) {
272 }
273 void ref() {
274 ++refcount;
275 }
276 inline void deref(json_type j);
277 private:
278 ComplexJson(const ComplexJson &x); // does not exist
279 };
280
281 struct ArrayJson;
282 struct ObjectItem;
283 struct ObjectJson;
284
285 json_type _type;
286 String _str;
287 ComplexJson *_cjson;
288
289 inline ObjectJson *ojson() const;
290 inline ArrayJson *ajson() const;
291
292 long hard_to_i() const;
293 long hard_as_i() const;
294 uint64_t hard_to_u64() const;
295 bool hard_to_b() const;
296 const String &hard_to_s() const;
297 inline void force_number();
298
299 const Json &hard_get(const StringRef &key) const;
300 const Json &hard_get(size_type x) const;
301 Json &hard_get_insert(size_type x);
302
303 void hard_uniqueify(int type);
304 inline void uniqueify_object(bool convert);
305 inline void uniqueify_array(bool convert);
306
307 bool unparse_is_complex() const;
308 static void unparse_indent(StringAccum &sa, const unparse_manipulator &m, int depth);
309 void hard_unparse(StringAccum &sa, const unparse_manipulator &m, int depth) const;
310
311 static inline const char *skip_space(const char *s, const char *end);
312 bool assign_parse(const String &str, const char *begin, const char *end);
313 static const char *parse_string(String &result, const String &str, const char *s, const char *end);
314 const char *parse_primitive(const String &str, const char *s, const char *end);
315
316 friend class object_iterator;
317 friend class const_object_iterator;
318 friend class array_iterator;
319 friend class const_array_iterator;
320 friend bool operator==(const Json &a, const Json &b);
321
322 struct JsonStatics;
323 static char statics[];
324
325};
326
327
328struct Json::ArrayJson : public ComplexJson {
329 JsonVector values;
330 ArrayJson() {
331 }
332 ArrayJson(const ArrayJson &x)
333 : ComplexJson(), values(x.values) {
334 }
335};
336
337struct Json::ObjectItem {
338 Pair<const String, Json> v_;
339 int next_;
340 explicit ObjectItem(const String &key, const Json &value, int next)
341 : v_(key, value), next_(next) {
342 }
343};
344
345struct Json::ObjectJson : public ComplexJson {
346 ObjectItem *os_;
347 int n_;
348 int capacity_;
349 Vector<int> hash_;
350 int nremoved_;
351 ObjectJson()
352 : os_(), n_(0), capacity_(0), nremoved_(0) {
353 }
354 ObjectJson(const ObjectJson &x);
355 ~ObjectJson() CLICK_COLD;
356 void grow(bool copy);
357 int bucket(const char *s, int len) const {
358 return String::hashcode(s, s + len) & (hash_.size() - 1);
359 }
360 ObjectItem &item(int i) const {
361 return os_[i];
362 }
363 int find(const char *s, int len) const {
364 if (hash_.size()) {
365 int i = hash_[bucket(s, len)];
366 while (i >= 0) {
367 ObjectItem &oi = item(i);
368 if (oi.v_.first.equals(s, len))
369 return i;
370 i = oi.next_;
371 }
372 }
373 return -1;
374 }
375 int find_insert(const String &key, const Json &value);
376 inline Json &get_insert(const String &key) {
377 int i = find_insert(key, make_null());
378 return item(i).v_.second;
379 }
380 Json &get_insert(const StringRef &key);
381 size_type erase(const StringRef &key);
382 void rehash();
383};
384
385struct CLICK_MAY_ALIAS Json::JsonStatics {
386 Json null_json;
387 String array_string;
388 String object_string;
389 inline JsonStatics();
390};
391
392inline const Json &Json::make_null() {
393 return reinterpret_cast<JsonStatics *>(statics)->null_json;
394}
395
396inline void Json::ComplexJson::deref(json_type j) {
397 if (--refcount <= 0) {
398 if (j == j_object)
399 delete static_cast<ObjectJson *>(this);
400 else
401 delete static_cast<ArrayJson *>(this);
402 }
403}
404
405inline Json::ArrayJson *Json::ajson() const {
406 assert(_type == j_null || _type == j_array);
407 return static_cast<ArrayJson *>(_cjson);
408}
409
410inline Json::ObjectJson *Json::ojson() const {
411 assert(_type == j_null || _type == j_object);
412 return static_cast<ObjectJson *>(_cjson);
413}
414
415inline void Json::uniqueify_object(bool convert) {
416 if (_type != j_object || !_cjson || _cjson->refcount > 1)
417 hard_uniqueify(convert ? j_object : -j_object);
418 assert(_type == j_object);
419}
420
421inline void Json::uniqueify_array(bool convert) {
422 if (_type != j_array || !_cjson || _cjson->refcount > 1)
423 hard_uniqueify(convert ? j_array : -j_array);
424 assert(_type == j_array);
425}
426
427
428class Json::const_object_iterator { public:
429 typedef Pair<const String, Json> value_type;
430 typedef const value_type *pointer_type;
431 typedef const value_type &reference_type;
432#if CLICK_USERLEVEL
433 typedef std::forward_iterator_tag iterator_category;
434#endif
435
436 const_object_iterator() {
437 }
438 typedef bool (const_object_iterator::*unspecified_bool_type)() const;
439 operator unspecified_bool_type() const {
440 return live() ? &const_object_iterator::live : 0;
441 }
442 bool live() const {
443 return i_ >= 0;
444 }
445 const value_type &operator*() const {
446 return j_->ojson()->item(i_).v_;
447 }
448 const value_type *operator->() const {
449 return &(**this);
450 }
451 const String &key() const {
452 return (**this).first;
453 }
454 const Json &value() const {
455 return (**this).second;
456 }
457 void operator++() {
458 ++i_;
459 fix();
460 }
461 void operator++(int) {
462 ++(*this);
463 }
464 private:
465 const Json *j_;
466 int i_;
467 const_object_iterator(const Json *j, int i)
468 : j_(j), i_(i) {
469 if (i_ >= 0)
470 fix();
471 }
472 void fix() {
473 ObjectJson *oj = j_->ojson();
474 retry:
475 if (!oj || i_ >= oj->n_)
476 i_ = -1;
477 else if (oj->item(i_).next_ == -2) {
478 ++i_;
479 goto retry;
480 }
481 }
482 friend class Json;
483 friend bool operator==(const const_object_iterator &, const const_object_iterator &);
484};
485
486class Json::object_iterator : public const_object_iterator { public:
487 typedef value_type *pointer_type;
488 typedef value_type &reference_type;
489
490 object_iterator() {
491 }
492 value_type &operator*() const {
493 const_cast<Json *>(j_)->uniqueify_object(false);
494 return j_->ojson()->item(i_).v_;
495 }
496 value_type *operator->() const {
497 return &(**this);
498 }
499 Json &value() const {
500 return (**this).second;
501 }
502 private:
503 object_iterator(Json *j, int i)
504 : const_object_iterator(j, i) {
505 }
506 friend class Json;
507};
508
509inline bool operator==(const Json::const_object_iterator &a, const Json::const_object_iterator &b) {
510 return a.j_ == b.j_ && a.i_ == b.i_;
511}
512
513inline bool operator!=(const Json::const_object_iterator &a, const Json::const_object_iterator &b) {
514 return !(a == b);
515}
516
517class Json::const_array_iterator { public:
518 typedef Json::size_type difference_type;
519 typedef Json value_type;
520 typedef const Json *pointer_type;
521 typedef const Json &reference_type;
522#if CLICK_USERLEVEL
523 typedef std::random_access_iterator_tag iterator_category;
524#endif
525
526 const_array_iterator() {
527 }
528 typedef bool (const_array_iterator::*unspecified_bool_type)() const;
529 operator unspecified_bool_type() const {
530 return live() ? &const_array_iterator::live : 0;
531 }
532 bool live() const {
533 return j_->_type == j_array && j_->ajson() && JsonVector::size_type(i_) < j_->ajson()->values.size();
534 }
535 const Json &operator*() const {
536 return j_->ajson()->values[i_];
537 }
538 const Json &operator[](difference_type i) const {
539 return j_->ajson()->values[i_ + i];
540 }
541 const Json *operator->() const {
542 return &(**this);
543 }
544 const Json &value() const {
545 return **this;
546 }
547 void operator++(int) {
548 ++i_;
549 }
550 void operator++() {
551 ++i_;
552 }
553 void operator--(int) {
554 --i_;
555 }
556 void operator--() {
557 --i_;
558 }
559 const_array_iterator &operator+=(difference_type x) {
560 i_ += x;
561 return *this;
562 }
563 const_array_iterator &operator-=(difference_type x) {
564 i_ -= x;
565 return *this;
566 }
567 private:
568 const Json *j_;
569 int i_;
570 const_array_iterator(const Json *j, int i)
571 : j_(j), i_(i) {
572 }
573 friend class Json;
574 friend class Json::array_iterator;
575 friend bool operator==(const const_array_iterator &, const const_array_iterator &);
576 friend bool operator<(const const_array_iterator &, const const_array_iterator &);
577 friend difference_type operator-(const const_array_iterator &, const const_array_iterator &);
578};
579
580class Json::array_iterator : public const_array_iterator { public:
581 typedef const Json *pointer_type;
582 typedef const Json &reference_type;
583
584 array_iterator() {
585 }
586 Json &operator*() const {
587 const_cast<Json *>(j_)->uniqueify_array(false);
588 return j_->ajson()->values[i_];
589 }
590 Json &operator[](difference_type i) const {
591 const_cast<Json *>(j_)->uniqueify_array(false);
592 return j_->ajson()->values[i_ + i];
593 }
594 Json *operator->() const {
595 return &(**this);
596 }
597 Json &value() const {
598 return **this;
599 }
600 private:
601 array_iterator(Json *j, int i)
602 : const_array_iterator(j, i) {
603 }
604 friend class Json;
605};
606
607inline bool operator==(const Json::const_array_iterator &a, const Json::const_array_iterator &b) {
608 return a.j_ == b.j_ && a.i_ == b.i_;
609}
610
611inline bool operator<(const Json::const_array_iterator &a, const Json::const_array_iterator &b) {
612 return a.j_ < b.j_ || (a.j_ == b.j_ && a.i_ < b.i_);
613}
614
615inline bool operator!=(const Json::const_array_iterator &a, const Json::const_array_iterator &b) {
616 return !(a == b);
617}
618
619inline bool operator<=(const Json::const_array_iterator &a, const Json::const_array_iterator &b) {
620 return !(b < a);
621}
622
623inline bool operator>(const Json::const_array_iterator &a, const Json::const_array_iterator &b) {
624 return b < a;
625}
626
627inline bool operator>=(const Json::const_array_iterator &a, const Json::const_array_iterator &b) {
628 return !(a < b);
629}
630
631inline Json::const_array_iterator operator+(Json::const_array_iterator a, Json::const_array_iterator::difference_type i) {
632 return a += i;
633}
634
635inline Json::const_array_iterator operator-(Json::const_array_iterator a, Json::const_array_iterator::difference_type i) {
636 return a -= i;
637}
638
639inline Json::const_array_iterator::difference_type operator-(const Json::const_array_iterator &a, const Json::const_array_iterator &b) {
640 assert(a.j_ == b.j_);
641 return a.i_ - b.i_;
642}
643
644class Json::const_iterator { public:
645 typedef Pair<const String, Json &> value_type;
646 typedef const value_type *pointer_type;
647 typedef const value_type &reference_type;
648#if CLICK_USERLEVEL
649 typedef std::forward_iterator_tag iterator_category;
650#endif
651
652 const_iterator()
653 : value_(String(), Json::uninitialized_t()) {
654 }
655 typedef bool (const_iterator::*unspecified_bool_type)() const;
656 operator unspecified_bool_type() const {
657 return live() ? &const_iterator::live : 0;
658 }
659 bool live() const {
660 return i_ >= 0;
661 }
662 const value_type &operator*() const {
663 return value_;
664 }
665 const value_type *operator->() const {
666 return &(**this);
667 }
668 const String &key() const {
669 return (**this).first;
670 }
671 const Json &value() const {
672 return (**this).second;
673 }
674 void operator++() {
675 ++i_;
676 fix();
677 }
678 void operator++(int) {
679 ++(*this);
680 }
681 private:
682 const Json *j_;
683 int i_;
684 value_type value_;
685 const_iterator(const Json *j, int i)
686 : j_(j), i_(i), value_(String(), Json::uninitialized_t()) {
687 if (i_ >= 0)
688 fix();
689 }
690 void fix() {
691 if (j_->_type == j_object) {
692 ObjectJson *oj = j_->ojson();
693 retry:
694 if (!oj || i_ >= oj->n_)
695 i_ = -1;
696 else if (oj->item(i_).next_ == -2) {
697 ++i_;
698 goto retry;
699 } else {
700 value_.~Pair();
701 new((void *) &value_) value_type(oj->item(i_).v_.first,
702 oj->item(i_).v_.second);
703 }
704 } else {
705 ArrayJson *aj = j_->ajson();
706 if (!aj || i_ >= aj->values.size())
707 i_ = -1;
708 else {
709 value_.~Pair();
710 new((void *) &value_) value_type(String(i_), aj->values[i_]);
711 }
712 }
713 }
714 friend class Json;
715 friend bool operator==(const const_iterator &, const const_iterator &);
716};
717
718class Json::iterator : public const_iterator { public:
719 typedef value_type *pointer_type;
720 typedef value_type &reference_type;
721
722 iterator() {
723 }
724 value_type &operator*() const {
725 if (j_->_cjson->refcount > 1)
726 uniqueify();
727 return const_cast<value_type &>(const_iterator::operator*());
728 }
729 value_type *operator->() const {
730 return &(**this);
731 }
732 Json &value() const {
733 return (**this).second;
734 }
735 private:
736 iterator(Json *j, int i)
737 : const_iterator(j, i) {
738 }
739 void uniqueify() const {
740 if (j_->_type == j_object)
741 const_cast<Json *>(j_)->uniqueify_object(false);
742 else
743 const_cast<Json *>(j_)->uniqueify_array(false);
744 const_cast<iterator *>(this)->fix();
745 }
746 friend class Json;
747};
748
749inline bool operator==(const Json::const_iterator &a, const Json::const_iterator &b) {
750 return a.j_ == b.j_ && a.i_ == b.i_;
751}
752
753inline bool operator!=(const Json::const_iterator &a, const Json::const_iterator &b) {
754 return !(a == b);
755}
756
757
758template <typename P>
759class Json_proxy_base {
760 public:
761 const Json &cvalue() const {
762 return static_cast<const P *>(this)->cvalue();
763 }
764 Json &value() {
765 return static_cast<P *>(this)->value();
766 }
767 operator const Json &() const {
768 return cvalue();
769 }
770 operator Json &() {
771 return value();
772 }
773 operator Json::unspecified_bool_type() const {
774 return cvalue();
775 }
776 bool operator!() const {
777 return !cvalue();
778 }
779 Json::json_type type() const {
780 return cvalue().type();
781 }
782 bool is_null() const {
783 return cvalue().is_null();
784 }
785 bool is_int() const {
786 return cvalue().is_int();
787 }
788 bool is_double() const {
789 return cvalue().is_double();
790 }
791 bool is_number() const {
792 return cvalue().is_number();
793 }
794 bool is_bool() const {
795 return cvalue().is_bool();
796 }
797 bool is_string() const {
798 return cvalue().is_string();
799 }
800 bool is_array() const {
801 return cvalue().is_array();
802 }
803 bool is_object() const {
804 return cvalue().is_object();
805 }
806 bool is_primitive() const {
807 return cvalue().is_primitive();
808 }
809 bool empty() const {
810 return cvalue().empty();
811 }
812 Json::size_type size() const {
813 return cvalue().size();
814 }
815 long to_i() const {
816 return cvalue().to_i();
817 }
818 uint64_t to_u64() const {
819 return cvalue().to_u64();
820 }
821 bool to_i(int &x) const {
822 return cvalue().to_i(x);
823 }
824 bool to_i(unsigned &x) const {
825 return cvalue().to_i(x);
826 }
827 bool to_i(long &x) const {
828 return cvalue().to_i(x);
829 }
830 bool to_i(unsigned long &x) const {
831 return cvalue().to_i(x);
832 }
833#if HAVE_LONG_LONG
834 bool to_i(long long &x) const {
835 return cvalue().to_i(x);
836 }
837 bool to_i(unsigned long long &x) const {
838 return cvalue().to_i(x);
839 }
840#endif
841 long as_i() const {
842 return cvalue().as_i();
843 }
844#if HAVE_FLOAT_TYPES
845 double to_d() const {
846 return cvalue().to_d();
847 }
848 bool to_d(double &x) const {
849 return cvalue().to_d(x);
850 }
851 double as_d() const {
852 return cvalue().as_d();
853 }
854#endif
855 bool to_b() const {
856 return cvalue().to_b();
857 }
858 bool to_b(bool &x) const {
859 return cvalue().to_b(x);
860 }
861 bool as_b() const {
862 return cvalue().as_b();
863 }
864 const String &to_s() const {
865 return cvalue().to_s();
866 }
867 bool to_s(String &x) const {
868 return cvalue().to_s(x);
869 }
870 const String &as_s() const {
871 return cvalue().as_s();
872 }
873 const char *c_str() const {
874 return cvalue().c_str();
875 }
876 Json::size_type count(const StringRef &key) const {
877 return cvalue().count(key);
878 }
879 const Json &get(const StringRef &key) const {
880 return cvalue().get(key);
881 }
882 Json &get_insert(const String &key) {
883 return value().get_insert(key);
884 }
885 Json &get_insert(const StringRef &key) {
886 return value().get_insert(key);
887 }
888 Json &get_insert(const char *key) {
889 return value().get_insert(key);
890 }
891 long get_i(const StringRef &key) const {
892 return cvalue().get_i(key);
893 }
894#if HAVE_FLOAT_TYPES
895 double get_d(const StringRef &key) const {
896 return cvalue().get_d(key);
897 }
898#endif
899 bool get_b(const StringRef &key) const {
900 return cvalue().get_b(key);
901 }
902 const String &get_s(const StringRef &key) const {
903 return cvalue().get_s(key);
904 }
905 inline const Json_get_proxy get(const StringRef &key, Json &x) const;
906 inline const Json_get_proxy get(const StringRef &key, int &x) const;
907 inline const Json_get_proxy get(const StringRef &key, unsigned &x) const;
908 inline const Json_get_proxy get(const StringRef &key, long &x) const;
909 inline const Json_get_proxy get(const StringRef &key, unsigned long &x) const;
910#if HAVE_LONG_LONG
911 inline const Json_get_proxy get(const StringRef &key, long long &x) const;
912 inline const Json_get_proxy get(const StringRef &key, unsigned long long &x) const;
913#endif
914#if HAVE_FLOAT_TYPES
915 inline const Json_get_proxy get(const StringRef &key, double &x) const;
916#endif
917 inline const Json_get_proxy get(const StringRef &key, bool &x) const;
918 inline const Json_get_proxy get(const StringRef &key, String &x) const;
919 const Json &operator[](const StringRef &key) const {
920 return cvalue().get(key);
921 }
922 Json_object_proxy<P> operator[](const String &key) {
923 return Json_object_proxy<P>(*static_cast<P *>(this), key);
924 }
925 Json_object_str_proxy<P> operator[](const StringRef &key) {
926 return Json_object_str_proxy<P>(*static_cast<P *>(this), key);
927 }
928 Json_object_str_proxy<P> operator[](const char *key) {
929 return Json_object_str_proxy<P>(*static_cast<P *>(this), key);
930 }
931 const Json &at(const StringRef &key) const {
932 return cvalue().at(key);
933 }
934 Json &at_insert(const String &key) {
935 return value().at_insert(key);
936 }
937 Json &at_insert(const StringRef &key) {
938 return value().at_insert(key);
939 }
940 Json &at_insert(const char *key) {
941 return value().at_insert(key);
942 }
943 template <typename T> inline Json &set(const String &key, T value) {
944 return this->value().set(key, value);
945 }
946#if HAVE_CXX_RVALUE_REFERENCES
947 inline Json &set(const String &key, Json &&value) {
948 return this->value().set(key, click_move(value));
949 }
950#endif
951 Json &unset(const StringRef &key) {
952 return value().unset(key);
953 }
954 Pair<Json::object_iterator, bool> insert(const Json::object_value_type &x) {
955 return value().insert(x);
956 }
957 Json::object_iterator insert(Json::object_iterator position, const Json::object_value_type &x) {
958 return value().insert(position, x);
959 }
960 Json::size_type erase(const StringRef &key) {
961 return value().erase(key);
962 }
963 Json &merge(const Json &x) {
964 return value().merge(x);
965 }
966 template <typename P2> Json &merge(const Json_proxy_base<P2> &x) {
967 return value().merge(x.cvalue());
968 }
969 const Json &get(Json::size_type x) const {
970 return cvalue().get(x);
971 }
972 Json &get_insert(Json::size_type x) {
973 return value().get_insert(x);
974 }
975 const Json &operator[](int key) const {
976 return cvalue().at(key);
977 }
978 Json_array_proxy<P> operator[](int key) {
979 return Json_array_proxy<P>(*static_cast<P *>(this), key);
980 }
981 const Json &at(Json::size_type x) const {
982 return cvalue().at(x);
983 }
984 Json &at_insert(Json::size_type x) {
985 return value().at_insert(x);
986 }
987 const Json &back() const {
988 return cvalue().back();
989 }
990 Json &back() {
991 return value().back();
992 }
993 template <typename T> Json &push_back(T x) {
994 return value().push_back(x);
995 }
996#if HAVE_CXX_RVALUE_REFERENCES
997 Json &push_back(Json &&x) {
998 return value().push_back(click_move(x));
999 }
1000#endif
1001 void pop_back() {
1002 value().pop_back();
1003 }
1004 void unparse(StringAccum &sa) const {
1005 return cvalue().unparse(sa);
1006 }
1007 void unparse(StringAccum &sa, const Json::unparse_manipulator &m) const {
1008 return cvalue().unparse(sa, m);
1009 }
1010 String unparse() const {
1011 return cvalue().unparse(false);
1012 }
1013 String unparse(bool add_newline) const {
1014 return cvalue().unparse(add_newline);
1015 }
1016 String unparse(const Json::unparse_manipulator &m, bool add_newline = false) const {
1017 return cvalue().unparse(m, add_newline);
1018 }
1019 bool assign_parse(const String &str) {
1020 return value().assign_parse(str);
1021 }
1022 bool assign_parse(const char *first, const char *last) {
1023 return value().assign_parse(first, last);
1024 }
1025 Json &operator++() {
1026 return ++value();
1027 }
1028 void operator++(int) {
1029 value()++;
1030 }
1031 Json &operator--() {
1032 return --value();
1033 }
1034 void operator--(int) {
1035 value()--;
1036 }
1037 Json &operator+=(int x) {
1038 return value() += x;
1039 }
1040 Json &operator+=(long x) {
1041 return value() += x;
1042 }
1043#if HAVE_FLOAT_TYPES
1044 Json &operator+=(double x) {
1045 return value() += x;
1046 }
1047#endif
1048 Json::const_object_iterator obegin() const {
1049 return cvalue().obegin();
1050 }
1051 Json::const_object_iterator oend() const {
1052 return cvalue().oend();
1053 }
1054 Json::object_iterator obegin() {
1055 return value().obegin();
1056 }
1057 Json::object_iterator oend() {
1058 return value().oend();
1059 }
1060 Json::const_object_iterator cobegin() const {
1061 return cvalue().cobegin();
1062 }
1063 Json::const_object_iterator coend() const {
1064 return cvalue().coend();
1065 }
1066 Json::const_array_iterator abegin() const {
1067 return cvalue().abegin();
1068 }
1069 Json::const_array_iterator aend() const {
1070 return cvalue().aend();
1071 }
1072 Json::array_iterator abegin() {
1073 return value().abegin();
1074 }
1075 Json::array_iterator aend() {
1076 return value().aend();
1077 }
1078 Json::const_array_iterator cabegin() const {
1079 return cvalue().cabegin();
1080 }
1081 Json::const_array_iterator caend() const {
1082 return cvalue().caend();
1083 }
1084 Json::const_iterator begin() const {
1085 return cvalue().begin();
1086 }
1087 Json::const_iterator end() const {
1088 return cvalue().end();
1089 }
1090 Json::iterator begin() {
1091 return value().begin();
1092 }
1093 Json::iterator end() {
1094 return value().end();
1095 }
1096 Json::const_iterator cbegin() const {
1097 return cvalue().cbegin();
1098 }
1099 Json::const_iterator cend() const {
1100 return cvalue().cend();
1101 }
1102};
1103
1104template <typename T>
1105class Json_object_proxy : public Json_proxy_base<Json_object_proxy<T> > {
1106 public:
1107 const Json &cvalue() const {
1108 return base_.get(key_);
1109 }
1110 Json &value() {
1111 return base_.get_insert(key_);
1112 }
1113 Json &operator=(const Json &x) {
1114 return value() = x;
1115 }
1116#if HAVE_CXX_RVALUE_REFERENCES
1117 Json &operator=(Json &&x) {
1118 return value() = click_move(x);
1119 }
1120#endif
1121 Json &operator=(const Json_object_proxy<T> &x) {
1122 return value() = x.cvalue();
1123 }
1124 template <typename P> Json &operator=(const Json_proxy_base<P> &x) {
1125 return value() = x.cvalue();
1126 }
1127 Json_object_proxy(T &ref, const String &key)
1128 : base_(ref), key_(key) {
1129 }
1130 T &base_;
1131 String key_;
1132};
1133
1134template <typename T>
1135class Json_object_str_proxy : public Json_proxy_base<Json_object_str_proxy<T> > {
1136 public:
1137 const Json &cvalue() const {
1138 return base_.get(key_);
1139 }
1140 Json &value() {
1141 return base_.get_insert(key_);
1142 }
1143 Json &operator=(const Json &x) {
1144 return value() = x;
1145 }
1146#if HAVE_CXX_RVALUE_REFERENCES
1147 Json &operator=(Json &&x) {
1148 return value() = click_move(x);
1149 }
1150#endif
1151 Json &operator=(const Json_object_str_proxy<T> &x) {
1152 return value() = x.cvalue();
1153 }
1154 template <typename P> Json &operator=(const Json_proxy_base<P> &x) {
1155 return value() = x.cvalue();
1156 }
1157 Json_object_str_proxy(T &ref, const StringRef &key)
1158 : base_(ref), key_(key) {
1159 }
1160 T &base_;
1161 StringRef key_;
1162};
1163
1164template <typename T>
1165class Json_array_proxy : public Json_proxy_base<Json_array_proxy<T> > {
1166 public:
1167 const Json &cvalue() const {
1168 return base_.get(key_);
1169 }
1170 Json &value() {
1171 return base_.get_insert(key_);
1172 }
1173 Json &operator=(const Json &x) {
1174 return value() = x;
1175 }
1176#if HAVE_CXX_RVALUE_REFERENCES
1177 Json &operator=(Json &&x) {
1178 return value() = click_move(x);
1179 }
1180#endif
1181 Json &operator=(const Json_array_proxy<T> &x) {
1182 return value() = x.cvalue();
1183 }
1184 template <typename P> Json &operator=(const Json_proxy_base<P> &x) {
1185 return value() = x.cvalue();
1186 }
1187 Json_array_proxy(T &ref, int key)
1188 : base_(ref), key_(key) {
1189 }
1190 T &base_;
1191 int key_;
1192};
1193
1194class Json_get_proxy : public Json_proxy_base<Json_get_proxy> {
1195 public:
1196 const Json &cvalue() const {
1197 return base_;
1198 }
1199 operator Json::unspecified_bool_type() const {
1200 return status_ ? &Json::is_null : 0;
1201 }
1202 bool operator!() const {
1203 return !status_;
1204 }
1205 bool status() const {
1206 return status_;
1207 }
1208 const Json_get_proxy &status(bool &x) const {
1209 x = status_;
1210 return *this;
1211 }
1212 Json_get_proxy(const Json &ref, bool status)
1213 : base_(ref), status_(status) {
1214 }
1215 const Json &base_;
1216 bool status_;
1217 private:
1218 Json_get_proxy &operator=(const Json_get_proxy &x);
1219};
1220
1221template <typename T>
1222inline const Json_get_proxy Json_proxy_base<T>::get(const StringRef &key, Json &x) const {
1223 return cvalue().get(key, x);
1224}
1225template <typename T>
1226inline const Json_get_proxy Json_proxy_base<T>::get(const StringRef &key, int &x) const {
1227 return cvalue().get(key, x);
1228}
1229template <typename T>
1230inline const Json_get_proxy Json_proxy_base<T>::get(const StringRef &key, unsigned &x) const {
1231 return cvalue().get(key, x);
1232}
1233template <typename T>
1234inline const Json_get_proxy Json_proxy_base<T>::get(const StringRef &key, long &x) const {
1235 return cvalue().get(key, x);
1236}
1237template <typename T>
1238inline const Json_get_proxy Json_proxy_base<T>::get(const StringRef &key, unsigned long &x) const {
1239 return cvalue().get(key, x);
1240}
1241#if HAVE_LONG_LONG
1242template <typename T>
1243inline const Json_get_proxy Json_proxy_base<T>::get(const StringRef &key, long long &x) const {
1244 return cvalue().get(key, x);
1245}
1246template <typename T>
1247inline const Json_get_proxy Json_proxy_base<T>::get(const StringRef &key, unsigned long long &x) const {
1248 return cvalue().get(key, x);
1249}
1250#endif
1251#if HAVE_FLOAT_TYPES
1252template <typename T>
1253inline const Json_get_proxy Json_proxy_base<T>::get(const StringRef &key, double &x) const {
1254 return cvalue().get(key, x);
1255}
1256#endif
1257template <typename T>
1258inline const Json_get_proxy Json_proxy_base<T>::get(const StringRef &key, bool &x) const {
1259 return cvalue().get(key, x);
1260}
1261template <typename T>
1262inline const Json_get_proxy Json_proxy_base<T>::get(const StringRef &key, String &x) const {
1263 return cvalue().get(key, x);
1264}
1265
1266
1269 : _type(j_null), _cjson() {
1270}
1272inline Json::Json(const uninitialized_t &unused) : _type(j_null), _cjson() {
1273 (void) unused;
1274}
1276inline Json::Json(const Json &x)
1277 : _type(x._type), _str(x._str), _cjson(x._cjson) {
1278 if (_cjson)
1279 _cjson->ref();
1280}
1281#if HAVE_CXX_RVALUE_REFERENCES
1283inline Json::Json(Json &&x)
1284 : _type(x._type), _str(click_move(x._str)), _cjson(x._cjson) {
1285 x._cjson = 0;
1286}
1287#endif
1289inline Json::Json(int x)
1290 : _type(j_int), _str(x), _cjson() {
1291}
1292inline Json::Json(unsigned x)
1293 : _type(j_int), _str(x), _cjson() {
1294}
1295inline Json::Json(long x)
1296 : _type(j_int), _str(x), _cjson() {
1297}
1298inline Json::Json(unsigned long x)
1299 : _type(j_int), _str(x), _cjson() {
1300}
1301#if HAVE_LONG_LONG
1302inline Json::Json(long long x)
1303 : _type(j_int), _str(x), _cjson() {
1304}
1305inline Json::Json(unsigned long long x)
1306 : _type(j_int), _str(x), _cjson() {
1307}
1308#endif
1309#if HAVE_FLOAT_TYPES
1310inline Json::Json(double x)
1311 : _type(j_double), _str(x), _cjson() {
1312}
1313#endif
1314inline Json::Json(bool x)
1315 : _type(j_bool), _str(x), _cjson() {
1316}
1317inline Json::Json(const String &x)
1318 : _type(j_string), _str(x), _cjson() {
1319}
1320inline Json::Json(const char *x)
1321 : _type(j_string), _str(x), _cjson() {
1322}
1324template <typename T>
1325inline Json::Json(const Vector<T> &x)
1326 : _type(j_array), _cjson(new ArrayJson) {
1327 for (const T *it = x.begin(); it != x.end(); ++it)
1328 ajson()->values.push_back(Json(*it));
1329}
1332template <typename T>
1333inline Json::Json(T first, T last)
1334 : _type(j_array), _cjson(new ArrayJson) {
1335 while (first != last) {
1336 ajson()->values.push_back(Json(*first));
1337 ++first;
1338 }
1339}
1341template <typename T>
1343 : _type(j_object), _cjson(new ObjectJson) {
1344 for (typename HashTable<String, T>::const_iterator it = x.begin();
1345 it != x.end(); ++it) {
1346 Json &x = ojson()->get_insert(it.key());
1347 x = Json(it.value());
1348 }
1349}
1350inline Json::~Json() {
1351 if (_cjson)
1352 _cjson->deref(_type);
1353}
1354
1357 Json j;
1358 j._type = j_array;
1359 return j;
1360}
1363 Json j;
1364 j._type = j_object;
1365 return j;
1366}
1369 return Json(x);
1370}
1372inline Json Json::make_string(const char *s, int len) {
1373 return Json(String(s, len));
1374}
1375
1378inline Json::operator unspecified_bool_type() const {
1379 return _type == j_null ? 0 : &Json::is_null;
1380}
1382inline bool Json::operator!() const {
1383 return _type == j_null;
1384}
1385
1387inline Json::json_type Json::type() const {
1388 return _type;
1389}
1391inline bool Json::is_null() const {
1392 return _type == j_null;
1393}
1394inline bool Json::is_int() const {
1395 return _type == j_int;
1396}
1397inline bool Json::is_double() const {
1398 return _type == j_double;
1399}
1400inline bool Json::is_number() const {
1401 return is_int() || is_double();
1402}
1403inline bool Json::is_bool() const {
1404 return _type == j_bool;
1405}
1406inline bool Json::is_string() const {
1407 return _type == j_string;
1408}
1409inline bool Json::is_array() const {
1410 return _type == j_array;
1411}
1412inline bool Json::is_object() const {
1413 return _type == j_object;
1414}
1416inline bool Json::is_primitive() const {
1417 return _type >= j_int && _type <= j_string;
1418}
1419
1422inline bool Json::empty() const {
1423 return (_type <= j_object && size() == 0);
1424}
1427inline Json::size_type Json::size() const {
1428 assert(_type == j_null || _type == j_array || _type == j_object);
1429 if (!_cjson)
1430 return 0;
1431 else if (_type == j_object) {
1432 ObjectJson *oj = ojson();
1433 return oj->n_ - oj->nremoved_;
1434 } else
1435 return ajson()->values.size();
1436}
1437
1438
1439// Primitive methods
1440
1448inline long Json::to_i() const {
1449 if (_type == j_int && _str.length() == 1)
1450 return _str[0] - '0';
1451 else
1452 return hard_to_i();
1453}
1454
1458inline uint64_t Json::to_u64() const {
1459 if (_type == j_int && _str.length() == 1)
1460 return _str[0] - '0';
1461 else
1462 return hard_to_u64();
1463}
1464
1468inline long Json::as_i() const {
1469 assert(_type == j_int || _type == j_double);
1470 if (_str.length() == 1)
1471 return _str[0] - '0';
1472 else
1473 return hard_as_i();
1474}
1475
1476#if HAVE_FLOAT_TYPES
1482inline bool Json::to_d(double &x) const {
1483 if (_type == j_double || _type == j_int) {
1484 x = to_d();
1485 return true;
1486 } else
1487 return false;
1488}
1489
1493inline double Json::as_d() const {
1494 assert(_type == j_double || _type == j_int);
1495 return to_d();
1496}
1497#endif
1498
1506inline bool Json::to_b() const {
1507 if (_type == j_bool)
1508 return _str[0] == 't';
1509 else
1510 return hard_to_b();
1511}
1512
1518inline bool Json::to_b(bool &x) const {
1519 if (_type == j_bool) {
1520 x = _str[0] == 't';
1521 return true;
1522 } else
1523 return false;
1524}
1525
1529inline bool Json::as_b() const {
1530 assert(_type == j_bool);
1531 return _str[0] == 't';
1532}
1533
1541inline const String &Json::to_s() const {
1542 if (_type == j_string)
1543 return _str;
1544 else
1545 return hard_to_s();
1546}
1547
1553inline bool Json::to_s(String &x) const {
1554 if (_type == j_string) {
1555 x = _str;
1556 return true;
1557 } else
1558 return false;
1559}
1560
1564inline const String &Json::as_s() const {
1565 assert(_type == j_string);
1566 return _str;
1567}
1568
1570inline const char *Json::c_str() const {
1571 return to_s().c_str();
1572}
1573
1574inline void Json::force_number() {
1575 assert(_type == j_null || _type == j_int || _type == j_double);
1576 if (_type == j_null) {
1577 _type = j_int;
1578 _str = String(0);
1579 }
1580}
1581
1582
1583// Object methods
1584
1588inline Json::size_type Json::count(const StringRef &key) const {
1589 assert(_type == j_null || _type == j_object);
1590 return _cjson ? ojson()->find(key.data(), key.length()) >= 0 : 0;
1591}
1592
1598inline const Json &Json::get(const StringRef &key) const {
1599 int i;
1600 ObjectJson *oj;
1601 if (_type == j_object && (oj = ojson())
1602 && (i = oj->find(key.data(), key.length())) >= 0)
1603 return oj->item(i).v_.second;
1604 else
1605 return hard_get(key);
1606}
1607
1613inline Json &Json::get_insert(const String &key) {
1614 uniqueify_object(true);
1615 return ojson()->get_insert(key);
1616}
1617
1619inline Json &Json::get_insert(const StringRef &key) {
1620 uniqueify_object(true);
1621 return ojson()->get_insert(key);
1622}
1623
1625inline Json &Json::get_insert(const char *key) {
1626 uniqueify_object(true);
1627 return ojson()->get_insert(StringRef(key));
1628}
1629
1631inline long Json::get_i(const StringRef &key) const {
1632 return get(key).to_i();
1633}
1634
1635#if HAVE_FLOAT_TYPES
1637inline double Json::get_d(const StringRef &key) const {
1638 return get(key).to_d();
1639}
1640#endif
1641
1643inline bool Json::get_b(const StringRef &key) const {
1644 return get(key).to_b();
1645}
1646
1648inline const String &Json::get_s(const StringRef &key) const {
1649 return get(key).to_s();
1650}
1651
1694inline const Json_get_proxy Json::get(const StringRef &key, Json &x) const {
1695 int i;
1696 ObjectJson *oj;
1697 if (_type == j_object && (oj = ojson())
1698 && (i = oj->find(key.data(), key.length())) >= 0) {
1699 x = oj->item(i).v_.second;
1700 return Json_get_proxy(*this, true);
1701 } else
1702 return Json_get_proxy(*this, false);
1703}
1704
1706inline const Json_get_proxy Json::get(const StringRef &key, int &x) const {
1707 return Json_get_proxy(*this, get(key).to_i(x));
1708}
1709
1711inline const Json_get_proxy Json::get(const StringRef &key, unsigned &x) const {
1712 return Json_get_proxy(*this, get(key).to_i(x));
1713}
1714
1716inline const Json_get_proxy Json::get(const StringRef &key, long &x) const {
1717 return Json_get_proxy(*this, get(key).to_i(x));
1718}
1719
1721inline const Json_get_proxy Json::get(const StringRef &key, unsigned long &x) const {
1722 return Json_get_proxy(*this, get(key).to_i(x));
1723}
1724
1725#if HAVE_LONG_LONG
1727inline const Json_get_proxy Json::get(const StringRef &key, long long &x) const {
1728 return Json_get_proxy(*this, get(key).to_i(x));
1729}
1730
1732inline const Json_get_proxy Json::get(const StringRef &key, unsigned long long &x) const {
1733 return Json_get_proxy(*this, get(key).to_i(x));
1734}
1735#endif
1736
1737#if HAVE_FLOAT_TYPES
1739inline const Json_get_proxy Json::get(const StringRef &key, double &x) const {
1740 return Json_get_proxy(*this, get(key).to_d(x));
1741}
1742#endif
1743
1745inline const Json_get_proxy Json::get(const StringRef &key, bool &x) const {
1746 return Json_get_proxy(*this, get(key).to_b(x));
1747}
1748
1750inline const Json_get_proxy Json::get(const StringRef &key, String &x) const {
1751 return Json_get_proxy(*this, get(key).to_s(x));
1752}
1753
1754
1757inline const Json &Json::operator[](const StringRef &key) const {
1758 return get(key);
1759}
1760
1767inline Json_object_proxy<Json> Json::operator[](const String &key) {
1768 return Json_object_proxy<Json>(*this, key);
1769}
1770
1772inline Json_object_str_proxy<Json> Json::operator[](const StringRef &key) {
1773 return Json_object_str_proxy<Json>(*this, key);
1774}
1775
1777inline Json_object_str_proxy<Json> Json::operator[](const char *key) {
1778 return Json_object_str_proxy<Json>(*this, key);
1779}
1780
1783inline const Json &Json::at(const StringRef &key) const {
1784 assert(_type == j_object && _cjson);
1785 ObjectJson *oj = ojson();
1786 int i = oj->find(key.data(), key.length());
1787 assert(i >= 0);
1788 return oj->item(i).v_.second;
1789}
1790
1795inline Json &Json::at_insert(const String &key) {
1796 assert(_type == j_object);
1797 return get_insert(key);
1798}
1799
1801inline Json &Json::at_insert(const StringRef &key) {
1802 assert(_type == j_object);
1803 return get_insert(key);
1804}
1805
1807inline Json &Json::at_insert(const char *key) {
1808 assert(_type == j_object);
1809 return get_insert(StringRef(key));
1810}
1811
1817template <typename T> inline Json &Json::set(const String &key, T value) {
1818 uniqueify_object(true);
1819 ojson()->get_insert(key) = Json(value);
1820 return *this;
1821}
1822
1823#if HAVE_CXX_RVALUE_REFERENCES
1825inline Json &Json::set(const String &key, Json &&value) {
1826 uniqueify_object(true);
1827 ojson()->get_insert(key) = click_move(value);
1828 return *this;
1829}
1830#endif
1831
1835inline Json &Json::unset(const StringRef &key) {
1836 if (_type == j_object) {
1837 uniqueify_object(true);
1838 ojson()->erase(key);
1839 }
1840 return *this;
1841}
1842
1850inline Pair<Json::object_iterator, bool> Json::insert(const object_value_type &x) {
1851 assert(_type == j_object);
1852 uniqueify_object(false);
1853 ObjectJson *oj = ojson();
1854 int n = oj->n_, i = oj->find_insert(x.first, x.second);
1855 return make_pair(object_iterator(this, i), i == n);
1856}
1857
1866inline Json::object_iterator Json::insert(object_iterator position, const object_value_type &x) {
1867 (void) position;
1868 return insert(x).first;
1869}
1870
1874inline Json::size_type Json::erase(const StringRef &key) {
1875 assert(_type == j_object);
1876 uniqueify_object(false);
1877 return ojson()->erase(key);
1878}
1879
1887inline Json &Json::merge(const Json &x) {
1888 assert(_type == j_object || _type == j_null);
1889 assert(x._type == j_object || x._type == j_null);
1890 if (x._cjson) {
1891 uniqueify_object(false);
1892 ObjectJson *oj = ojson(), *xoj = x.ojson();
1893 const ObjectItem *xb = xoj->os_, *xe = xb + xoj->n_;
1894 for (; xb != xe; ++xb)
1895 if (xb->next_ > -2)
1896 oj->get_insert(xb->v_.first) = xb->v_.second;
1897 }
1898 return *this;
1899}
1900
1902template <typename U>
1903inline Json &Json::merge(const Json_proxy_base<U> &x) {
1904 return merge(x.cvalue());
1905}
1909// ARRAY METHODS
1910
1916inline const Json &Json::get(size_type x) const {
1917 ArrayJson *aj;
1918 if (_type == j_array && (aj = ajson())
1919 && JsonVector::size_type(x) < aj->values.size())
1920 return aj->values[x];
1921 else
1922 return hard_get(x);
1923}
1924
1930inline Json &Json::get_insert(size_type x) {
1931 ArrayJson *aj;
1932 if (_type == j_array && (aj = ajson()) && aj->refcount == 1
1933 && JsonVector::size_type(x) < aj->values.size())
1934 return aj->values[x];
1935 else
1936 return hard_get_insert(x);
1937}
1938
1943inline const Json &Json::at(size_type x) const {
1944 assert(_type == j_array);
1945 return get(x);
1946}
1947
1952inline Json &Json::at_insert(size_type x) {
1953 assert(_type == j_array);
1954 return get_insert(x);
1955}
1956
1962inline const Json &Json::operator[](size_type x) const {
1963 return get(x);
1964}
1965
1973inline Json_array_proxy<Json> Json::operator[](size_type x) {
1974 return Json_array_proxy<Json>(*this, x);
1975}
1976
1979inline const Json &Json::back() const {
1980 assert(_type == j_array && _cjson && ajson()->values.size() > 0);
1981 return ajson()->values.back();
1982}
1983
1986inline Json &Json::back() {
1987 assert(_type == j_array && _cjson && ajson()->values.size() > 0);
1988 uniqueify_array(false);
1989 return ajson()->values.back();
1990}
1991
1997template <typename T> inline Json &Json::push_back(T x) {
1998 uniqueify_array(false);
1999 ajson()->values.push_back(Json(x));
2000 return *this;
2001}
2002
2003#if HAVE_CXX_RVALUE_REFERENCES
2005inline Json &Json::push_back(Json &&x) {
2006 uniqueify_array(false);
2007 ajson()->values.push_back(click_move(x));
2008 return *this;
2009}
2010#endif
2011
2015 assert(_type == j_array && _cjson && ajson()->values.size() > 0);
2016 uniqueify_array(false);
2017 ajson()->values.pop_back();
2018}
2019
2020
2021inline Json::const_object_iterator Json::cobegin() const {
2022 assert(_type == j_null || _type == j_object);
2023 return const_object_iterator(this, 0);
2024}
2025
2026inline Json::const_object_iterator Json::coend() const {
2027 assert(_type == j_null || _type == j_object);
2028 return const_object_iterator(this, -1);
2029}
2030
2031inline Json::const_object_iterator Json::obegin() const {
2032 return cobegin();
2033}
2034
2035inline Json::const_object_iterator Json::oend() const {
2036 return coend();
2037}
2038
2039inline Json::object_iterator Json::obegin() {
2040 assert(_type == j_null || _type == j_object);
2041 return object_iterator(this, 0);
2042}
2043
2044inline Json::object_iterator Json::oend() {
2045 assert(_type == j_null || _type == j_object);
2046 return object_iterator(this, -1);
2047}
2048
2049inline Json::const_array_iterator Json::cabegin() const {
2050 assert(_type == j_null || _type == j_array);
2051 return const_array_iterator(this, 0);
2052}
2053
2054inline Json::const_array_iterator Json::caend() const {
2055 assert(_type == j_null || _type == j_array);
2056 ArrayJson *aj = ajson();
2057 return const_array_iterator(this, aj ? aj->values.size() : 0);
2058}
2059
2060inline Json::const_array_iterator Json::abegin() const {
2061 return cabegin();
2062}
2063
2064inline Json::const_array_iterator Json::aend() const {
2065 return caend();
2066}
2067
2068inline Json::array_iterator Json::abegin() {
2069 assert(_type == j_null || _type == j_array);
2070 return array_iterator(this, 0);
2071}
2072
2073inline Json::array_iterator Json::aend() {
2074 assert(_type == j_null || _type == j_array);
2075 ArrayJson *aj = ajson();
2076 return array_iterator(this, aj ? aj->values.size() : 0);
2077}
2078
2079inline Json::const_iterator Json::cbegin() const {
2080 return const_iterator(this, 0);
2081}
2082
2083inline Json::const_iterator Json::cend() const {
2084 return const_iterator(this, -1);
2085}
2086
2087inline Json::iterator Json::begin() {
2088 return iterator(this, 0);
2089}
2090
2091inline Json::iterator Json::end() {
2092 return iterator(this, -1);
2093}
2094
2095inline Json::const_iterator Json::begin() const {
2096 return cbegin();
2097}
2098
2099inline Json::const_iterator Json::end() const {
2100 return cend();
2101}
2102
2103
2104// Unparsing
2105struct Json::unparse_manipulator {
2106 unparse_manipulator()
2107 : _indent_depth(0), _tab_width(8) {
2108 }
2109 int indent_depth() const {
2110 return _indent_depth;
2111 }
2112 unparse_manipulator indent_depth(int x) const {
2113 unparse_manipulator m(*this);
2114 m._indent_depth = x;
2115 return m;
2116 }
2117 int tab_width() const {
2118 return _tab_width;
2119 }
2120 unparse_manipulator tab_width(int x) const {
2121 unparse_manipulator m(*this);
2122 m._tab_width = x;
2123 return m;
2124 }
2125 private:
2126 int _indent_depth;
2127 int _tab_width;
2128};
2129
2130inline Json::unparse_manipulator Json::indent_depth(int x) {
2131 return unparse_manipulator().indent_depth(x);
2132}
2133inline Json::unparse_manipulator Json::tab_width(int x) {
2134 return unparse_manipulator().tab_width(x);
2135}
2136
2138inline String Json::unparse() const {
2139 return unparse(false);
2140}
2141
2144inline String Json::unparse(bool add_newline) const {
2145 StringAccum sa;
2146 unparse(sa);
2147 if (add_newline)
2148 sa << '\n';
2149 return sa.take_string();
2150}
2151
2153inline void Json::unparse(StringAccum &sa, const unparse_manipulator &m) const {
2154 hard_unparse(sa, m, 0);
2155}
2156
2159inline String Json::unparse(const unparse_manipulator &m,
2160 bool add_newline) const {
2161 StringAccum sa;
2162 hard_unparse(sa, m, 0);
2163 if (add_newline)
2164 sa << '\n';
2165 return sa.take_string();
2166}
2167
2168
2169// Parsing
2170
2175inline bool Json::assign_parse(const String &str) {
2176 return assign_parse(str, str.begin(), str.end());
2177}
2178
2183inline bool Json::assign_parse(const char *first, const char *last) {
2184 return assign_parse(String(), first, last);
2185}
2186
2190inline Json Json::parse(const String &str) {
2191 Json j;
2192 (void) j.assign_parse(str);
2193 return j;
2194}
2195
2199inline Json Json::parse(const char *first, const char *last) {
2200 Json j;
2201 (void) j.assign_parse(first, last);
2202 return j;
2203}
2204
2205
2206// Assignment
2207
2208inline Json &Json::operator=(const Json &x) {
2209 _str = x._str;
2210 if (_cjson != x._cjson) {
2211 if (_cjson)
2212 _cjson->deref(_type);
2213 _cjson = x._cjson;
2214 if (_cjson)
2215 _cjson->ref();
2216 }
2217 _type = x._type;
2218 return *this;
2219}
2220
2221#if HAVE_CXX_RVALUE_REFERENCES
2222inline Json &Json::operator=(Json &&x) {
2223 _type = x._type;
2224 _str = click_move(x._str);
2225 _cjson = x._cjson;
2226 x._cjson = 0;
2227 return *this;
2228}
2229#endif
2230
2232template <typename U>
2233inline Json &Json::operator=(const Json_proxy_base<U> &x) {
2234 return *this = x.cvalue();
2235}
2239 return *this += 1;
2240}
2241inline void Json::operator++(int) {
2242 ++(*this);
2243}
2244inline Json &Json::operator--() {
2245 return *this += -1;
2246}
2247inline void Json::operator--(int) {
2248 --(*this);
2249}
2250inline Json &Json::operator+=(int x) {
2251 force_number();
2252#if HAVE_FLOAT_TYPES
2253 if (_type == j_int)
2254 _str = String(as_i() + x);
2255 else
2256 _str = String(as_d() + x);
2257#else
2258 _str = String(as_i() + x);
2259#endif
2260 return *this;
2261}
2262inline Json &Json::operator+=(long x) {
2263 force_number();
2264#if HAVE_FLOAT_TYPES
2265 if (_type == j_int)
2266 _str = String(as_i() + x);
2267 else
2268 _str = String(as_d() + x);
2269#else
2270 _str = String(as_i() + x);
2271#endif
2272 return *this;
2273}
2274#if HAVE_FLOAT_TYPES
2275inline Json &Json::operator+=(double x) {
2276 force_number();
2277 _str = String(as_d() + x);
2278 return *this;
2279}
2280#endif
2281
2283inline void Json::swap(Json &x) {
2284 click_swap(_type, x._type);
2285 _str.swap(x._str);
2286 click_swap(_cjson, x._cjson);
2287}
2288
2289
2290inline StringAccum &operator<<(StringAccum &sa, const Json &json) {
2291 json.unparse(sa);
2292 return sa;
2293}
2294
2295inline bool operator==(const Json &a, const Json &b) {
2296 return a.type() == b.type()
2297 && (a.is_primitive() ? a._str == b._str : a._cjson == b._cjson);
2298}
2299
2300template <typename T>
2301inline bool operator==(const Json_proxy_base<T> &a, const Json &b) {
2302 return a.cvalue() == b;
2303}
2304
2305template <typename T>
2306inline bool operator==(const Json &a, const Json_proxy_base<T> &b) {
2307 return a == b.cvalue();
2308}
2309
2310template <typename T, typename U>
2311inline bool operator==(const Json_proxy_base<T> &a,
2312 const Json_proxy_base<U> &b) {
2313 return a.cvalue() == b.cvalue();
2314}
2315
2316inline bool operator!=(const Json &a, const Json &b) {
2317 return !(a == b);
2318}
2319
2320template <typename T>
2321inline bool operator!=(const Json_proxy_base<T> &a, const Json &b) {
2322 return !(a == b);
2323}
2324
2325template <typename T>
2326inline bool operator!=(const Json &a, const Json_proxy_base<T> &b) {
2327 return !(a == b);
2328}
2329
2330template <typename T, typename U>
2331inline bool operator!=(const Json_proxy_base<T> &a,
2332 const Json_proxy_base<U> &b) {
2333 return !(a == b);
2334}
2335
2336CLICK_ENDDECLS
2337#endif
Hash table template.
Definition hashtable.hh:570
iterator begin()
Return an iterator for the first element in the table.
Definition hashtable.hh:666
iterator end()
Return an iterator for the end of the table.
Definition hashtable.hh:676
Json data.
Definition json.hh:20
Pair< object_iterator, bool > insert(const object_value_type &x)
Insert element x in this object Json.
Definition json.hh:1850
Json & unset(const StringRef &key)
Remove the value of key from an object Json.
Definition json.hh:1835
uint64_t to_u64() const
Return this Json converted to a 64-bit unsigned integer.
Definition json.hh:1458
bool is_primitive() const
Test if this Json is a primitive value, not including null.
Definition json.hh:1416
Json & set(const String &key, T value)
Set the value of key to value in this object Json.
Definition json.hh:1817
void swap(Json &x)
Swap this Json with x.
Definition json.hh:2283
long to_i() const
Return this Json converted to an integer.
Definition json.hh:1448
bool operator!() const
Return true if this Json is null.
Definition json.hh:1382
String unparse() const
Return the string representation of this Json.
Definition json.hh:2138
static Json make_string(const String &x)
Return a string-valued Json.
Definition json.hh:1368
Json & at_insert(const String &key)
Return a reference to the value at key in an object Json.
Definition json.hh:1795
size_type erase(const StringRef &key)
Remove the value of key from an object Json.
Definition json.hh:1874
long as_i() const
Return the integer value of this numeric Json.
Definition json.hh:1468
bool is_null() const
Test this Json's type.
Definition json.hh:1391
json_type type() const
Return this Json's type.
Definition json.hh:1387
long get_i(const StringRef &key) const
Return get(key).to_i().
Definition json.hh:1631
static Json make_array()
Return an empty array-valued Json.
Definition json.hh:1356
double to_d() const
Return this Json converted to a double.
Definition json.cc:380
double get_d(const StringRef &key) const
Return get(key).to_d().
Definition json.hh:1637
const char * c_str() const
Return to_s().c_str().
Definition json.hh:1570
Json & get_insert(const String &key)
Return a reference to the value of key in an object Json.
Definition json.hh:1613
size_type count(const StringRef &key) const
Return 1 if this object Json contains key, 0 otherwise.
Definition json.hh:1588
Json & operator++()
Definition json.hh:2238
bool empty() const
Return true if this Json is null, an empty array, or an empty object.
Definition json.hh:1422
size_type size() const
Return the number of elements in this complex Json.
Definition json.hh:1427
static Json make_object()
Return an empty object-valued Json.
Definition json.hh:1362
Json()
Construct a null Json.
Definition json.hh:1268
void pop_back()
Remove the last element from an array.
Definition json.hh:2014
static Json parse(const String &str)
Return str parsed as UTF-8 JSON.
Definition json.hh:2190
bool get_b(const StringRef &key) const
Return get(key).to_b().
Definition json.hh:1643
bool to_b() const
Return this Json converted to a boolean.
Definition json.hh:1506
Json & merge(const Json &x)
Merge the values of object Json x into this object Json.
Definition json.hh:1887
const Json & operator[](const StringRef &key) const
Return the value at key in an object or array Json.
Definition json.hh:1757
const String & get_s(const StringRef &key) const
Return get(key).to_s().
Definition json.hh:1648
const Json & at(const StringRef &key) const
Return the value at key in an object Json.
Definition json.hh:1783
bool assign_parse(const String &str)
Parse str as UTF-8 JSON into this Json object.
Definition json.hh:2175
const Json & get(const StringRef &key) const
Return the value at key in an object or array Json.
Definition json.hh:1598
Json & push_back(T x)
Push an element onto the back of the array.
Definition json.hh:1997
const String & to_s() const
Return this Json converted to a string.
Definition json.hh:1541
bool as_b() const
Return the value of this boolean Json.
Definition json.hh:1529
double as_d() const
Return the double value of this numeric Json.
Definition json.hh:1493
const String & as_s() const
Return the value of this string Json.
Definition json.hh:1564
const Json & back() const
Return the last array element.
Definition json.hh:1979
Efficiently build up Strings from pieces.
Definition straccum.hh:28
String take_string()
Return a String object with this StringAccum's contents.
Definition straccum.cc:211
A string of characters.
Definition string.hh:22
int length() const
Return the string's length.
Definition string.hh:509
const char * c_str() const
Null-terminate the string.
Definition string.hh:519
const_iterator end() const
Return an iterator for the end of the string.
Definition string.hh:584
uint32_t hashcode() const
Returns a 32-bit hash function of this string's characters.
Definition string.hh:646
void swap(String &x)
Swap the values of this string and x.
Definition string.hh:730
const_iterator begin() const
Return an iterator for the first character in the string.
Definition string.hh:576
Vector template.
Definition vector.hh:111
int size_type
Type of sizes (size()).
Definition vector.hh:128
iterator end()
Return an iterator for the end of the vector.
Definition vector.hh:266
iterator begin()
Return an iterator for the first element in the vector.
Definition vector.hh:253
size_type size() const
Return the number of elements.
Definition vector.hh:231
Click's hash table container template.
Click's StringAccum class, used to construct Strings efficiently from pieces.
Timestamp operator*(const Timestamp &a, double b)
Scale a by a factor of b and return the result.
Definition timestamp.hh:1447
Click's vector container template.