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