1 #ifndef BOOST_PROPERTY_TREE_DETAIL_JSON_PARSER_STANDARD_CALLBACKS_HPP 2 #define BOOST_PROPERTY_TREE_DETAIL_JSON_PARSER_STANDARD_CALLBACKS_HPP 3 4 #include <boost/property_tree/ptree.hpp> 5 #include <vector> 6 7 namespace boost { namespace property_tree { 8 namespace json_parser { namespace detail 9 { 10 11 namespace constants 12 { 13 template <typename Ch> const Ch* null_value(); null_value()14 template <> inline const char* null_value() { return "null"; } null_value()15 template <> inline const wchar_t* null_value() { return L"null"; } 16 17 template <typename Ch> const Ch* true_value(); true_value()18 template <> inline const char* true_value() { return "true"; } true_value()19 template <> inline const wchar_t* true_value() { return L"true"; } 20 21 template <typename Ch> const Ch* false_value(); false_value()22 template <> inline const char* false_value() { return "false"; } false_value()23 template <> inline const wchar_t* false_value() { return L"false"; } 24 } 25 26 template <typename Ptree> 27 class standard_callbacks { 28 public: 29 typedef typename Ptree::data_type string; 30 typedef typename string::value_type char_type; 31 on_null()32 void on_null() { 33 new_value() = constants::null_value<char_type>(); 34 } 35 on_boolean(bool b)36 void on_boolean(bool b) { 37 new_value() = b ? constants::true_value<char_type>() 38 : constants::false_value<char_type>(); 39 } 40 41 template <typename Range> on_number(Range code_units)42 void on_number(Range code_units) { 43 new_value().assign(code_units.begin(), code_units.end()); 44 } on_begin_number()45 void on_begin_number() { 46 new_value(); 47 } on_digit(char_type d)48 void on_digit(char_type d) { 49 current_value() += d; 50 } on_end_number()51 void on_end_number() {} 52 on_begin_string()53 void on_begin_string() { 54 new_value(); 55 } 56 template <typename Range> on_code_units(Range code_units)57 void on_code_units(Range code_units) { 58 current_value().append(code_units.begin(), code_units.end()); 59 } on_code_unit(char_type c)60 void on_code_unit(char_type c) { 61 current_value() += c; 62 } on_end_string()63 void on_end_string() {} 64 on_begin_array()65 void on_begin_array() { 66 new_tree(); 67 stack.back().k = array; 68 } on_end_array()69 void on_end_array() { 70 if (stack.back().k == leaf) stack.pop_back(); 71 stack.pop_back(); 72 } 73 on_begin_object()74 void on_begin_object() { 75 new_tree(); 76 stack.back().k = object; 77 } on_end_object()78 void on_end_object() { 79 if (stack.back().k == leaf) stack.pop_back(); 80 stack.pop_back(); 81 } 82 output()83 Ptree& output() { return root; } 84 85 protected: is_key() const86 bool is_key() const { 87 return stack.back().k == key; 88 } current_value()89 string& current_value() { 90 layer& l = stack.back(); 91 switch (l.k) { 92 case key: return key_buffer; 93 default: return l.t->data(); 94 } 95 } 96 97 private: 98 Ptree root; 99 string key_buffer; 100 enum kind { array, object, key, leaf }; 101 struct layer { kind k; Ptree* t; }; 102 std::vector<layer> stack; 103 new_tree()104 Ptree& new_tree() { 105 if (stack.empty()) { 106 layer l = {leaf, &root}; 107 stack.push_back(l); 108 return root; 109 } 110 layer& l = stack.back(); 111 switch (l.k) { 112 case array: { 113 l.t->push_back(std::make_pair(string(), Ptree())); 114 layer nl = {leaf, &l.t->back().second}; 115 stack.push_back(nl); 116 return *stack.back().t; 117 } 118 case object: 119 assert(false); // must start with string, i.e. call new_value 120 case key: { 121 l.t->push_back(std::make_pair(key_buffer, Ptree())); 122 l.k = object; 123 layer nl = {leaf, &l.t->back().second}; 124 stack.push_back(nl); 125 return *stack.back().t; 126 } 127 case leaf: 128 stack.pop_back(); 129 return new_tree(); 130 } 131 assert(false); 132 } new_value()133 string& new_value() { 134 if (stack.empty()) return new_tree().data(); 135 layer& l = stack.back(); 136 switch (l.k) { 137 case leaf: 138 stack.pop_back(); 139 return new_value(); 140 case object: 141 l.k = key; 142 key_buffer.clear(); 143 return key_buffer; 144 default: 145 return new_tree().data(); 146 } 147 } 148 }; 149 150 }}}} 151 152 #endif 153