7#include <click/glue.hh>
8#include <click/pair.hh>
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;
23 j_null = 0, j_array, j_object, j_int, j_double, j_bool, j_string
26 const char *class_name()
const {
return "Json"; }
28 typedef int size_type;
30 typedef Pair<const String, Json> object_value_type;
31 class object_iterator;
32 class const_object_iterator;
36 class const_array_iterator;
41 typedef bool (
Json::*unspecified_bool_type)()
const;
42 struct unparse_manipulator;
44 typedef uninitialized_type uninitialized_t;
48 inline Json(
const uninitialized_t &);
50#if HAVE_CXX_RVALUE_REFERENCES
54 inline Json(
unsigned x);
56 inline Json(
unsigned long x);
58 inline Json(
long long x);
59 inline Json(
unsigned long long x);
62 inline Json(
double x);
66 inline Json(
const char *x);
68 template <
typename T>
inline Json(T first, T last);
72 static inline const Json &make_null();
78 static void static_initialize();
81 inline operator unspecified_bool_type()
const;
84 inline json_type
type()
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;
95 inline bool empty()
const;
96 inline size_type
size()
const;
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;
106 bool to_i(
long long &x)
const;
107 bool to_i(
unsigned long long &x)
const;
109 inline long as_i()
const;
113 inline bool to_d(
double &x)
const;
114 inline double as_d()
const;
117 inline bool to_b()
const;
118 inline bool to_b(
bool &x)
const;
119 inline bool as_b()
const;
124 inline const char *
c_str()
const;
127 inline size_type
count(
const StringRef &key)
const;
128 inline const Json &
get(
const StringRef &key)
const;
133 inline long get_i(
const StringRef &key)
const;
135 inline double get_d(
const StringRef &key)
const;
137 inline bool get_b(
const StringRef &key)
const;
138 inline const String &
get_s(
const StringRef &key)
const;
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;
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;
150 inline const Json_get_proxy
get(
const StringRef &key,
double &x)
const;
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;
157 inline Json_object_str_proxy<Json>
operator[](
const StringRef &key);
158 inline Json_object_str_proxy<Json>
operator[](
const char *key);
160 inline const Json &
at(
const StringRef &key)
const;
165 template <
typename T>
inline Json &
set(
const String &key, T value);
166#if HAVE_CXX_RVALUE_REFERENCES
169 inline Json &
unset(
const StringRef &key);
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);
177 template <
typename P>
inline Json &
merge(
const Json_proxy_base<P> &x);
180 inline const Json &
get(size_type x)
const;
184 inline Json_array_proxy<Json>
operator[](size_type x);
186 inline const Json &
at(size_type x)
const;
193#if HAVE_CXX_RVALUE_REFERENCES
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;
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;
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;
221 static inline unparse_manipulator indent_depth(
int x);
222 static inline unparse_manipulator tab_width(
int x);
227 bool add_newline =
false)
const;
233 inline bool assign_parse(
const char *first,
const char *last);
236 static inline Json parse(
const char *first,
const char *last);
239 inline Json &operator=(
const Json &x);
240#if HAVE_CXX_RVALUE_REFERENCES
243 template <
typename P>
inline Json &operator=(
const Json_proxy_base<P> &x);
247 inline Json &operator--();
248 inline void operator--(
int);
249 inline Json &operator+=(
int x);
250 inline Json &operator+=(
long x);
252 inline Json &operator+=(
double x);
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,
276 inline void deref(json_type j);
278 ComplexJson(
const ComplexJson &x);
289 inline ObjectJson *ojson()
const;
290 inline ArrayJson *ajson()
const;
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();
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);
303 void hard_uniqueify(
int type);
304 inline void uniqueify_object(
bool convert);
305 inline void uniqueify_array(
bool convert);
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;
311 static inline const char *skip_space(
const char *s,
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);
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);
323 static char statics[];
328struct Json::ArrayJson :
public ComplexJson {
332 ArrayJson(
const ArrayJson &x)
333 : ComplexJson(), values(x.values) {
337struct Json::ObjectItem {
338 Pair<const String, Json> v_;
340 explicit ObjectItem(
const String &key,
const Json &value,
int next)
341 : v_(key, value), next_(next) {
345struct Json::ObjectJson :
public ComplexJson {
352 : os_(), n_(0), capacity_(0), nremoved_(0) {
354 ObjectJson(
const ObjectJson &x);
355 ~ObjectJson() CLICK_COLD;
356 void grow(
bool copy);
357 int bucket(const
char *s,
int len)
const {
360 ObjectItem &item(
int i)
const {
363 int find(
const char *s,
int len)
const {
365 int i = hash_[bucket(s, len)];
367 ObjectItem &oi = item(i);
368 if (oi.v_.first.equals(s, len))
375 int find_insert(
const String &key,
const Json &value);
377 int i = find_insert(key, make_null());
378 return item(i).v_.second;
380 Json &get_insert(
const StringRef &key);
381 size_type erase(
const StringRef &key);
385struct CLICK_MAY_ALIAS
Json::JsonStatics {
389 inline JsonStatics();
392inline const Json &Json::make_null() {
393 return reinterpret_cast<JsonStatics *
>(statics)->null_json;
396inline void Json::ComplexJson::deref(json_type j) {
397 if (--refcount <= 0) {
399 delete static_cast<ObjectJson *
>(
this);
401 delete static_cast<ArrayJson *
>(
this);
405inline Json::ArrayJson *Json::ajson()
const {
406 assert(_type == j_null || _type == j_array);
407 return static_cast<ArrayJson *
>(_cjson);
410inline Json::ObjectJson *Json::ojson()
const {
411 assert(_type == j_null || _type == j_object);
412 return static_cast<ObjectJson *
>(_cjson);
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);
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);
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;
433 typedef std::forward_iterator_tag iterator_category;
436 const_object_iterator() {
438 typedef bool (const_object_iterator::*unspecified_bool_type)() const;
439 operator unspecified_bool_type()
const {
440 return live() ? &const_object_iterator::live : 0;
446 return j_->ojson()->item(i_).v_;
448 const value_type *operator->()
const {
451 const String &key()
const {
452 return (**this).first;
454 const Json &value()
const {
455 return (**this).second;
461 void operator++(
int) {
467 const_object_iterator(
const Json *j,
int i)
473 ObjectJson *oj = j_->ojson();
475 if (!oj || i_ >= oj->n_)
477 else if (oj->item(i_).next_ == -2) {
483 friend bool operator==(
const const_object_iterator &,
const const_object_iterator &);
486class Json::object_iterator :
public const_object_iterator {
public:
487 typedef value_type *pointer_type;
488 typedef value_type &reference_type;
493 const_cast<Json *
>(j_)->uniqueify_object(
false);
494 return j_->ojson()->item(i_).v_;
496 value_type *operator->()
const {
499 Json &value()
const {
500 return (**this).second;
503 object_iterator(
Json *j,
int i)
504 : const_object_iterator(j, i) {
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_;
513inline bool operator!=(
const Json::const_object_iterator &a,
const Json::const_object_iterator &b) {
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;
523 typedef std::random_access_iterator_tag iterator_category;
526 const_array_iterator() {
528 typedef bool (const_array_iterator::*unspecified_bool_type)() const;
529 operator unspecified_bool_type()
const {
530 return live() ? &const_array_iterator::live : 0;
533 return j_->_type == j_array && j_->ajson() &&
JsonVector::size_type(i_) < j_->ajson()->values.size();
536 return j_->ajson()->values[i_];
538 const Json &operator[](difference_type i)
const {
539 return j_->ajson()->values[i_ + i];
541 const Json *operator->()
const {
544 const Json &value()
const {
547 void operator++(
int) {
553 void operator--(
int) {
559 const_array_iterator &operator+=(difference_type x) {
563 const_array_iterator &operator-=(difference_type x) {
570 const_array_iterator(
const Json *j,
int i)
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 &);
580class Json::array_iterator :
public const_array_iterator {
public:
581 typedef const Json *pointer_type;
582 typedef const Json &reference_type;
587 const_cast<Json *
>(j_)->uniqueify_array(
false);
588 return j_->ajson()->values[i_];
590 Json &operator[](difference_type i)
const {
591 const_cast<Json *
>(j_)->uniqueify_array(
false);
592 return j_->ajson()->values[i_ + i];
594 Json *operator->()
const {
597 Json &value()
const {
601 array_iterator(
Json *j,
int i)
602 : const_array_iterator(j, i) {
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_;
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_);
615inline bool operator!=(
const Json::const_array_iterator &a,
const Json::const_array_iterator &b) {
619inline bool operator<=(
const Json::const_array_iterator &a,
const Json::const_array_iterator &b) {
623inline bool operator>(
const Json::const_array_iterator &a,
const Json::const_array_iterator &b) {
627inline bool operator>=(
const Json::const_array_iterator &a,
const Json::const_array_iterator &b) {
631inline Json::const_array_iterator operator+(Json::const_array_iterator a, Json::const_array_iterator::difference_type i) {
635inline Json::const_array_iterator operator-(Json::const_array_iterator a, Json::const_array_iterator::difference_type i) {
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_);
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;
649 typedef std::forward_iterator_tag iterator_category;
655 typedef bool (const_iterator::*unspecified_bool_type)() const;
656 operator unspecified_bool_type()
const {
657 return live() ? &const_iterator::live : 0;
665 const value_type *operator->()
const {
668 const String &key()
const {
669 return (**this).first;
671 const Json &value()
const {
672 return (**this).second;
678 void operator++(
int) {
685 const_iterator(
const Json *j,
int i)
686 : j_(j), i_(i), value_(
String(),
Json::uninitialized_t()) {
691 if (j_->_type == j_object) {
692 ObjectJson *oj = j_->ojson();
694 if (!oj || i_ >= oj->n_)
696 else if (oj->item(i_).next_ == -2) {
701 new((
void *) &value_) value_type(oj->item(i_).v_.first,
702 oj->item(i_).v_.second);
705 ArrayJson *aj = j_->ajson();
706 if (!aj || i_ >= aj->values.size())
710 new((
void *) &value_) value_type(
String(i_), aj->values[i_]);
715 friend bool operator==(
const const_iterator &,
const const_iterator &);
718class Json::iterator :
public const_iterator {
public:
719 typedef value_type *pointer_type;
720 typedef value_type &reference_type;
725 if (j_->_cjson->refcount > 1)
727 return const_cast<value_type &
>(const_iterator::operator*());
729 value_type *operator->()
const {
732 Json &value()
const {
733 return (**this).second;
736 iterator(
Json *j,
int i)
737 : const_iterator(j, i) {
739 void uniqueify()
const {
740 if (j_->_type == j_object)
741 const_cast<Json *
>(j_)->uniqueify_object(
false);
743 const_cast<Json *
>(j_)->uniqueify_array(
false);
744 const_cast<iterator *
>(
this)->fix();
749inline bool operator==(
const Json::const_iterator &a,
const Json::const_iterator &b) {
750 return a.j_ == b.j_ && a.i_ == b.i_;
753inline bool operator!=(
const Json::const_iterator &a,
const Json::const_iterator &b) {
759class Json_proxy_base {
761 const Json &cvalue()
const {
762 return static_cast<const P *
>(
this)->cvalue();
765 return static_cast<P *
>(
this)->value();
767 operator const Json &()
const {
773 operator Json::unspecified_bool_type()
const {
776 bool operator!()
const {
779 Json::json_type type()
const {
780 return cvalue().type();
782 bool is_null()
const {
783 return cvalue().is_null();
785 bool is_int()
const {
786 return cvalue().is_int();
788 bool is_double()
const {
789 return cvalue().is_double();
791 bool is_number()
const {
792 return cvalue().is_number();
794 bool is_bool()
const {
795 return cvalue().is_bool();
797 bool is_string()
const {
798 return cvalue().is_string();
800 bool is_array()
const {
801 return cvalue().is_array();
803 bool is_object()
const {
804 return cvalue().is_object();
806 bool is_primitive()
const {
807 return cvalue().is_primitive();
810 return cvalue().empty();
812 Json::size_type size()
const {
813 return cvalue().size();
816 return cvalue().to_i();
818 uint64_t to_u64()
const {
819 return cvalue().to_u64();
821 bool to_i(
int &x)
const {
822 return cvalue().to_i(x);
824 bool to_i(
unsigned &x)
const {
825 return cvalue().to_i(x);
827 bool to_i(
long &x)
const {
828 return cvalue().to_i(x);
830 bool to_i(
unsigned long &x)
const {
831 return cvalue().to_i(x);
834 bool to_i(
long long &x)
const {
835 return cvalue().to_i(x);
837 bool to_i(
unsigned long long &x)
const {
838 return cvalue().to_i(x);
842 return cvalue().as_i();
845 double to_d()
const {
846 return cvalue().to_d();
848 bool to_d(
double &x)
const {
849 return cvalue().to_d(x);
851 double as_d()
const {
852 return cvalue().as_d();
856 return cvalue().to_b();
858 bool to_b(
bool &x)
const {
859 return cvalue().to_b(x);
862 return cvalue().as_b();
864 const String &to_s()
const {
865 return cvalue().to_s();
867 bool to_s(
String &x)
const {
868 return cvalue().to_s(x);
870 const String &as_s()
const {
871 return cvalue().as_s();
873 const char *c_str()
const {
874 return cvalue().
c_str();
876 Json::size_type count(
const StringRef &key)
const {
877 return cvalue().count(key);
879 const Json &get(
const StringRef &key)
const {
880 return cvalue().
get(key);
885 Json &get_insert(
const StringRef &key) {
888 Json &get_insert(
const char *key) {
891 long get_i(
const StringRef &key)
const {
892 return cvalue().
get_i(key);
895 double get_d(
const StringRef &key)
const {
896 return cvalue().get_d(key);
899 bool get_b(
const StringRef &key)
const {
900 return cvalue().get_b(key);
902 const String &get_s(
const StringRef &key)
const {
903 return cvalue().get_s(key);
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;
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;
915 inline const Json_get_proxy get(
const StringRef &key,
double &x)
const;
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);
922 Json_object_proxy<P> operator[](
const String &key) {
923 return Json_object_proxy<P>(*
static_cast<P *
>(
this), key);
925 Json_object_str_proxy<P> operator[](
const StringRef &key) {
926 return Json_object_str_proxy<P>(*
static_cast<P *
>(
this), key);
928 Json_object_str_proxy<P> operator[](
const char *key) {
929 return Json_object_str_proxy<P>(*
static_cast<P *
>(
this), key);
931 const Json &at(
const StringRef &key)
const {
932 return cvalue().
at(key);
937 Json &at_insert(
const StringRef &key) {
940 Json &at_insert(
const char *key) {
943 template <
typename T>
inline Json &set(
const String &key, T value) {
944 return this->value().
set(key, value);
946#if HAVE_CXX_RVALUE_REFERENCES
948 return this->value().
set(key, click_move(value));
951 Json &unset(
const StringRef &key) {
952 return value().
unset(key);
954 Pair<Json::object_iterator, bool> insert(
const Json::object_value_type &x) {
957 Json::object_iterator insert(Json::object_iterator position,
const Json::object_value_type &x) {
958 return value().insert(position, x);
960 Json::size_type erase(
const StringRef &key) {
961 return value().erase(key);
964 return value().
merge(x);
966 template <
typename P2>
Json &merge(
const Json_proxy_base<P2> &x) {
967 return value().
merge(x.cvalue());
969 const Json &get(Json::size_type x)
const {
970 return cvalue().
get(x);
972 Json &get_insert(Json::size_type x) {
975 const Json &operator[](
int key)
const {
976 return cvalue().
at(key);
978 Json_array_proxy<P> operator[](
int key) {
979 return Json_array_proxy<P>(*
static_cast<P *
>(
this), key);
981 const Json &at(Json::size_type x)
const {
982 return cvalue().
at(x);
984 Json &at_insert(Json::size_type x) {
987 const Json &back()
const {
988 return cvalue().
back();
991 return value().
back();
993 template <
typename T>
Json &push_back(T x) {
996#if HAVE_CXX_RVALUE_REFERENCES
1005 return cvalue().unparse(sa);
1007 void unparse(
StringAccum &sa,
const Json::unparse_manipulator &m)
const {
1008 return cvalue().unparse(sa, m);
1011 return cvalue().unparse(
false);
1013 String unparse(
bool add_newline)
const {
1014 return cvalue().unparse(add_newline);
1016 String unparse(
const Json::unparse_manipulator &m,
bool add_newline =
false)
const {
1017 return cvalue().unparse(m, add_newline);
1019 bool assign_parse(
const String &str) {
1020 return value().assign_parse(str);
1022 bool assign_parse(
const char *first,
const char *last) {
1023 return value().assign_parse(first, last);
1025 Json &operator++() {
1028 void operator++(
int) {
1031 Json &operator--() {
1034 void operator--(
int) {
1037 Json &operator+=(
int x) {
1038 return value() += x;
1040 Json &operator+=(
long x) {
1041 return value() += x;
1044 Json &operator+=(
double x) {
1045 return value() += x;
1048 Json::const_object_iterator obegin()
const {
1049 return cvalue().obegin();
1051 Json::const_object_iterator oend()
const {
1052 return cvalue().oend();
1054 Json::object_iterator obegin() {
1055 return value().obegin();
1057 Json::object_iterator oend() {
1058 return value().oend();
1060 Json::const_object_iterator cobegin()
const {
1061 return cvalue().cobegin();
1063 Json::const_object_iterator coend()
const {
1064 return cvalue().coend();
1066 Json::const_array_iterator abegin()
const {
1067 return cvalue().abegin();
1069 Json::const_array_iterator aend()
const {
1070 return cvalue().aend();
1072 Json::array_iterator abegin() {
1073 return value().abegin();
1075 Json::array_iterator aend() {
1076 return value().aend();
1078 Json::const_array_iterator cabegin()
const {
1079 return cvalue().cabegin();
1081 Json::const_array_iterator caend()
const {
1082 return cvalue().caend();
1084 Json::const_iterator begin()
const {
1085 return cvalue().begin();
1087 Json::const_iterator end()
const {
1088 return cvalue().end();
1090 Json::iterator begin() {
1091 return value().begin();
1093 Json::iterator end() {
1094 return value().end();
1096 Json::const_iterator cbegin()
const {
1097 return cvalue().cbegin();
1099 Json::const_iterator cend()
const {
1100 return cvalue().cend();
1104template <
typename T>
1105class Json_object_proxy :
public Json_proxy_base<Json_object_proxy<T> > {
1107 const Json &cvalue()
const {
1108 return base_.
get(key_);
1116#if HAVE_CXX_RVALUE_REFERENCES
1118 return value() = click_move(x);
1121 Json &operator=(
const Json_object_proxy<T> &x) {
1122 return value() = x.cvalue();
1124 template <
typename P>
Json &operator=(
const Json_proxy_base<P> &x) {
1125 return value() = x.cvalue();
1127 Json_object_proxy(T &ref,
const String &key)
1128 : base_(ref), key_(key) {
1134template <
typename T>
1135class Json_object_str_proxy :
public Json_proxy_base<Json_object_str_proxy<T> > {
1137 const Json &cvalue()
const {
1138 return base_.
get(key_);
1146#if HAVE_CXX_RVALUE_REFERENCES
1148 return value() = click_move(x);
1151 Json &operator=(
const Json_object_str_proxy<T> &x) {
1152 return value() = x.cvalue();
1154 template <
typename P>
Json &operator=(
const Json_proxy_base<P> &x) {
1155 return value() = x.cvalue();
1157 Json_object_str_proxy(T &ref,
const StringRef &key)
1158 : base_(ref), key_(key) {
1164template <
typename T>
1165class Json_array_proxy :
public Json_proxy_base<Json_array_proxy<T> > {
1167 const Json &cvalue()
const {
1168 return base_.
get(key_);
1176#if HAVE_CXX_RVALUE_REFERENCES
1178 return value() = click_move(x);
1181 Json &operator=(
const Json_array_proxy<T> &x) {
1182 return value() = x.cvalue();
1184 template <
typename P>
Json &operator=(
const Json_proxy_base<P> &x) {
1185 return value() = x.cvalue();
1187 Json_array_proxy(T &ref,
int key)
1188 : base_(ref), key_(key) {
1194class Json_get_proxy :
public Json_proxy_base<Json_get_proxy> {
1196 const Json &cvalue()
const {
1199 operator Json::unspecified_bool_type()
const {
1202 bool operator!()
const {
1205 bool status()
const {
1208 const Json_get_proxy &status(
bool &x)
const {
1212 Json_get_proxy(
const Json &ref,
bool status)
1213 : base_(ref), status_(status) {
1218 Json_get_proxy &operator=(
const Json_get_proxy &x);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
1269 : _type(j_null), _cjson() {
1272inline Json::Json(
const uninitialized_t &unused) : _type(j_null), _cjson() {
1277 : _type(x._type), _str(x._str), _cjson(x._cjson) {
1281#if HAVE_CXX_RVALUE_REFERENCES
1284 : _type(x._type), _str(click_move(x._str)), _cjson(x._cjson) {
1290 : _type(j_int), _str(x), _cjson() {
1293 : _type(j_int), _str(x), _cjson() {
1296 : _type(j_int), _str(x), _cjson() {
1299 : _type(j_int), _str(x), _cjson() {
1303 : _type(j_int), _str(x), _cjson() {
1306 : _type(j_int), _str(x), _cjson() {
1311 : _type(j_double), _str(x), _cjson() {
1315 : _type(j_bool), _str(x), _cjson() {
1318 : _type(j_string), _str(x), _cjson() {
1321 : _type(j_string), _str(x), _cjson() {
1324template <
typename T>
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));
1332template <
typename T>
1334 : _type(j_array), _cjson(new ArrayJson) {
1335 while (first != last) {
1336 ajson()->values.push_back(
Json(*first));
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());
1350inline Json::~Json() {
1352 _cjson->deref(_type);
1378inline Json::operator unspecified_bool_type()
const {
1383 return _type == j_null;
1392 return _type == j_null;
1394inline bool Json::is_int()
const {
1395 return _type == j_int;
1397inline bool Json::is_double()
const {
1398 return _type == j_double;
1400inline bool Json::is_number()
const {
1401 return is_int() || is_double();
1403inline bool Json::is_bool()
const {
1404 return _type == j_bool;
1406inline bool Json::is_string()
const {
1407 return _type == j_string;
1409inline bool Json::is_array()
const {
1410 return _type == j_array;
1412inline bool Json::is_object()
const {
1413 return _type == j_object;
1417 return _type >= j_int && _type <= j_string;
1423 return (_type <= j_object &&
size() == 0);
1428 assert(_type == j_null || _type == j_array || _type == j_object);
1431 else if (_type == j_object) {
1432 ObjectJson *oj = ojson();
1433 return oj->n_ - oj->nremoved_;
1435 return ajson()->values.size();
1449 if (_type == j_int && _str.
length() == 1)
1450 return _str[0] -
'0';
1459 if (_type == j_int && _str.
length() == 1)
1460 return _str[0] -
'0';
1462 return hard_to_u64();
1469 assert(_type == j_int || _type == j_double);
1471 return _str[0] -
'0';
1483 if (_type == j_double || _type == j_int) {
1494 assert(_type == j_double || _type == j_int);
1507 if (_type == j_bool)
1508 return _str[0] ==
't';
1519 if (_type == j_bool) {
1530 assert(_type == j_bool);
1531 return _str[0] ==
't';
1542 if (_type == j_string)
1554 if (_type == j_string) {
1565 assert(_type == j_string);
1574inline void Json::force_number() {
1575 assert(_type == j_null || _type == j_int || _type == j_double);
1576 if (_type == j_null) {
1589 assert(_type == j_null || _type == j_object);
1590 return _cjson ? ojson()->find(key.data(), key.length()) >= 0 : 0;
1601 if (_type == j_object && (oj = ojson())
1602 && (i = oj->find(key.data(), key.length())) >= 0)
1603 return oj->item(i).v_.second;
1605 return hard_get(key);
1614 uniqueify_object(
true);
1615 return ojson()->get_insert(key);
1620 uniqueify_object(
true);
1621 return ojson()->get_insert(key);
1626 uniqueify_object(
true);
1627 return ojson()->get_insert(StringRef(key));
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);
1702 return Json_get_proxy(*
this,
false);
1706inline const Json_get_proxy
Json::get(
const StringRef &key,
int &x)
const {
1707 return Json_get_proxy(*
this,
get(key).
to_i(x));
1711inline const Json_get_proxy
Json::get(
const StringRef &key,
unsigned &x)
const {
1712 return Json_get_proxy(*
this,
get(key).
to_i(x));
1716inline const Json_get_proxy
Json::get(
const StringRef &key,
long &x)
const {
1717 return Json_get_proxy(*
this,
get(key).
to_i(x));
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));
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));
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));
1739inline const Json_get_proxy
Json::get(
const StringRef &key,
double &x)
const {
1740 return Json_get_proxy(*
this,
get(key).
to_d(x));
1745inline const Json_get_proxy
Json::get(
const StringRef &key,
bool &x)
const {
1746 return Json_get_proxy(*
this,
get(key).
to_b(x));
1751 return Json_get_proxy(*
this,
get(key).
to_s(x));
1768 return Json_object_proxy<Json>(*
this, key);
1773 return Json_object_str_proxy<Json>(*
this, key);
1778 return Json_object_str_proxy<Json>(*
this, key);
1784 assert(_type == j_object && _cjson);
1785 ObjectJson *oj = ojson();
1786 int i = oj->find(key.data(), key.length());
1788 return oj->item(i).v_.second;
1796 assert(_type == j_object);
1802 assert(_type == j_object);
1808 assert(_type == j_object);
1818 uniqueify_object(
true);
1819 ojson()->get_insert(key) =
Json(value);
1823#if HAVE_CXX_RVALUE_REFERENCES
1826 uniqueify_object(
true);
1827 ojson()->get_insert(key) = click_move(value);
1836 if (_type == j_object) {
1837 uniqueify_object(
true);
1838 ojson()->erase(key);
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);
1866inline Json::object_iterator
Json::insert(object_iterator position,
const object_value_type &x) {
1875 assert(_type == j_object);
1876 uniqueify_object(
false);
1877 return ojson()->erase(key);
1888 assert(_type == j_object || _type == j_null);
1889 assert(x._type == j_object || x._type == j_null);
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)
1896 oj->get_insert(xb->v_.first) = xb->v_.second;
1902template <
typename U>
1904 return merge(x.cvalue());
1918 if (_type == j_array && (aj = ajson())
1920 return aj->values[x];
1932 if (_type == j_array && (aj = ajson()) && aj->refcount == 1
1934 return aj->values[x];
1936 return hard_get_insert(x);
1944 assert(_type == j_array);
1953 assert(_type == j_array);
1974 return Json_array_proxy<Json>(*
this, x);
1980 assert(_type == j_array && _cjson && ajson()->values.size() > 0);
1981 return ajson()->values.back();
1987 assert(_type == j_array && _cjson && ajson()->values.size() > 0);
1988 uniqueify_array(
false);
1989 return ajson()->values.back();
1998 uniqueify_array(
false);
1999 ajson()->values.push_back(
Json(x));
2003#if HAVE_CXX_RVALUE_REFERENCES
2006 uniqueify_array(
false);
2007 ajson()->values.push_back(click_move(x));
2015 assert(_type == j_array && _cjson && ajson()->values.size() > 0);
2016 uniqueify_array(
false);
2017 ajson()->values.pop_back();
2021inline Json::const_object_iterator Json::cobegin()
const {
2022 assert(_type == j_null || _type == j_object);
2023 return const_object_iterator(
this, 0);
2026inline Json::const_object_iterator Json::coend()
const {
2027 assert(_type == j_null || _type == j_object);
2028 return const_object_iterator(
this, -1);
2031inline Json::const_object_iterator Json::obegin()
const {
2035inline Json::const_object_iterator Json::oend()
const {
2039inline Json::object_iterator Json::obegin() {
2040 assert(_type == j_null || _type == j_object);
2041 return object_iterator(
this, 0);
2044inline Json::object_iterator Json::oend() {
2045 assert(_type == j_null || _type == j_object);
2046 return object_iterator(
this, -1);
2049inline Json::const_array_iterator Json::cabegin()
const {
2050 assert(_type == j_null || _type == j_array);
2051 return const_array_iterator(
this, 0);
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);
2060inline Json::const_array_iterator Json::abegin()
const {
2064inline Json::const_array_iterator Json::aend()
const {
2068inline Json::array_iterator Json::abegin() {
2069 assert(_type == j_null || _type == j_array);
2070 return array_iterator(
this, 0);
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);
2079inline Json::const_iterator Json::cbegin()
const {
2080 return const_iterator(
this, 0);
2083inline Json::const_iterator Json::cend()
const {
2084 return const_iterator(
this, -1);
2087inline Json::iterator Json::begin() {
2088 return iterator(
this, 0);
2091inline Json::iterator Json::end() {
2092 return iterator(
this, -1);
2095inline Json::const_iterator Json::begin()
const {
2099inline Json::const_iterator Json::end()
const {
2105struct Json::unparse_manipulator {
2106 unparse_manipulator()
2107 : _indent_depth(0), _tab_width(8) {
2109 int indent_depth()
const {
2110 return _indent_depth;
2112 unparse_manipulator indent_depth(
int x)
const {
2113 unparse_manipulator m(*
this);
2114 m._indent_depth = x;
2117 int tab_width()
const {
2120 unparse_manipulator tab_width(
int x)
const {
2121 unparse_manipulator m(*
this);
2130inline Json::unparse_manipulator Json::indent_depth(
int x) {
2131 return unparse_manipulator().indent_depth(x);
2133inline Json::unparse_manipulator Json::tab_width(
int x) {
2134 return unparse_manipulator().tab_width(x);
2154 hard_unparse(sa, m, 0);
2160 bool add_newline)
const {
2162 hard_unparse(sa, m, 0);
2208inline Json &Json::operator=(
const Json &x) {
2210 if (_cjson != x._cjson) {
2212 _cjson->deref(_type);
2221#if HAVE_CXX_RVALUE_REFERENCES
2222inline Json &Json::operator=(
Json &&x) {
2224 _str = click_move(x._str);
2232template <
typename U>
2233inline Json &Json::operator=(
const Json_proxy_base<U> &x) {
2234 return *
this = x.cvalue();
2244inline Json &Json::operator--() {
2247inline void Json::operator--(
int) {
2250inline Json &Json::operator+=(
int x) {
2262inline Json &Json::operator+=(
long x) {
2275inline Json &Json::operator+=(
double x) {
2284 click_swap(_type, x._type);
2286 click_swap(_cjson, x._cjson);
2295inline bool operator==(
const Json &a,
const Json &b) {
2297 && (a.
is_primitive() ? a._str == b._str : a._cjson == b._cjson);
2300template <
typename T>
2301inline bool operator==(
const Json_proxy_base<T> &a,
const Json &b) {
2302 return a.cvalue() == b;
2305template <
typename T>
2306inline bool operator==(
const Json &a,
const Json_proxy_base<T> &b) {
2307 return a == b.cvalue();
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();
2316inline bool operator!=(
const Json &a,
const Json &b) {
2320template <
typename T>
2321inline bool operator!=(
const Json_proxy_base<T> &a,
const Json &b) {
2325template <
typename T>
2326inline bool operator!=(
const Json &a,
const Json_proxy_base<T> &b) {
2330template <
typename T,
typename U>
2331inline bool operator!=(
const Json_proxy_base<T> &a,
2332 const Json_proxy_base<U> &b) {
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.