File indexing completed on 2025-01-18 09:50:18
0001 #ifndef BOOST_PROPERTY_TREE_DETAIL_JSON_PARSER_STANDARD_CALLBACKS_HPP
0002 #define BOOST_PROPERTY_TREE_DETAIL_JSON_PARSER_STANDARD_CALLBACKS_HPP
0003
0004 #include <boost/assert.hpp>
0005 #include <boost/property_tree/ptree.hpp>
0006 #include <vector>
0007
0008 namespace boost { namespace property_tree {
0009 namespace json_parser { namespace detail
0010 {
0011
0012 namespace constants
0013 {
0014 template <typename Ch> const Ch* null_value();
0015 template <> inline const char* null_value() { return "null"; }
0016 template <> inline const wchar_t* null_value() { return L"null"; }
0017
0018 template <typename Ch> const Ch* true_value();
0019 template <> inline const char* true_value() { return "true"; }
0020 template <> inline const wchar_t* true_value() { return L"true"; }
0021
0022 template <typename Ch> const Ch* false_value();
0023 template <> inline const char* false_value() { return "false"; }
0024 template <> inline const wchar_t* false_value() { return L"false"; }
0025 }
0026
0027 template <typename Ptree>
0028 class standard_callbacks {
0029 public:
0030 typedef typename Ptree::data_type string;
0031 typedef typename string::value_type char_type;
0032
0033 void on_null() {
0034 new_value() = constants::null_value<char_type>();
0035 }
0036
0037 void on_boolean(bool b) {
0038 new_value() = b ? constants::true_value<char_type>()
0039 : constants::false_value<char_type>();
0040 }
0041
0042 template <typename Range>
0043 void on_number(Range code_units) {
0044 new_value().assign(code_units.begin(), code_units.end());
0045 }
0046 void on_begin_number() {
0047 new_value();
0048 }
0049 void on_digit(char_type d) {
0050 current_value() += d;
0051 }
0052 void on_end_number() {}
0053
0054 void on_begin_string() {
0055 new_value();
0056 }
0057 template <typename Range>
0058 void on_code_units(Range code_units) {
0059 current_value().append(code_units.begin(), code_units.end());
0060 }
0061 void on_code_unit(char_type c) {
0062 current_value() += c;
0063 }
0064 void on_end_string() {}
0065
0066 void on_begin_array() {
0067 new_tree();
0068 stack.back().k = array;
0069 }
0070 void on_end_array() {
0071 if (stack.back().k == leaf) stack.pop_back();
0072 stack.pop_back();
0073 }
0074
0075 void on_begin_object() {
0076 new_tree();
0077 stack.back().k = object;
0078 }
0079 void on_end_object() {
0080 if (stack.back().k == leaf) stack.pop_back();
0081 stack.pop_back();
0082 }
0083
0084 Ptree& output() { return root; }
0085
0086 protected:
0087 bool is_key() const {
0088 return stack.back().k == key;
0089 }
0090 string& current_value() {
0091 layer& l = stack.back();
0092 switch (l.k) {
0093 case key: return key_buffer;
0094 default: return l.t->data();
0095 }
0096 }
0097
0098 private:
0099 Ptree root;
0100 string key_buffer;
0101 enum kind { array, object, key, leaf };
0102 struct layer { kind k; Ptree* t; };
0103 std::vector<layer> stack;
0104
0105 Ptree& new_tree() {
0106 if (stack.empty()) {
0107 layer l = {leaf, &root};
0108 stack.push_back(l);
0109 return root;
0110 }
0111 layer& l = stack.back();
0112 switch (l.k) {
0113 case array: {
0114 l.t->push_back(std::make_pair(string(), Ptree()));
0115 layer nl = {leaf, &l.t->back().second};
0116 stack.push_back(nl);
0117 return *stack.back().t;
0118 }
0119 case object:
0120 default:
0121 BOOST_ASSERT(false);
0122 case key: {
0123 l.t->push_back(std::make_pair(key_buffer, Ptree()));
0124 l.k = object;
0125 layer nl = {leaf, &l.t->back().second};
0126 stack.push_back(nl);
0127 return *stack.back().t;
0128 }
0129 case leaf:
0130 stack.pop_back();
0131 return new_tree();
0132 }
0133 }
0134 string& new_value() {
0135 if (stack.empty()) return new_tree().data();
0136 layer& l = stack.back();
0137 switch (l.k) {
0138 case leaf:
0139 stack.pop_back();
0140 return new_value();
0141 case object:
0142 l.k = key;
0143 key_buffer.clear();
0144 return key_buffer;
0145 default:
0146 return new_tree().data();
0147 }
0148 }
0149 };
0150
0151 }}}}
0152
0153 #endif