#ifndef BOOST_PROPERTY_TREE_DETAIL_JSON_PARSER_STANDARD_CALLBACKS_HPP #define BOOST_PROPERTY_TREE_DETAIL_JSON_PARSER_STANDARD_CALLBACKS_HPP #include #include #include namespace boost { namespace property_tree { namespace json_parser { namespace detail { namespace constants { template const Ch* null_value(); template <> inline const char* null_value() { return "null"; } template <> inline const wchar_t* null_value() { return L"null"; } template const Ch* true_value(); template <> inline const char* true_value() { return "true"; } template <> inline const wchar_t* true_value() { return L"true"; } template const Ch* false_value(); template <> inline const char* false_value() { return "false"; } template <> inline const wchar_t* false_value() { return L"false"; } } template class standard_callbacks { public: typedef typename Ptree::data_type string; typedef typename string::value_type char_type; void on_null() { new_value() = constants::null_value(); } void on_boolean(bool b) { new_value() = b ? constants::true_value() : constants::false_value(); } template void on_number(Range code_units) { new_value().assign(code_units.begin(), code_units.end()); } void on_begin_number() { new_value(); } void on_digit(char_type d) { current_value() += d; } void on_end_number() {} void on_begin_string() { new_value(); } template void on_code_units(Range code_units) { current_value().append(code_units.begin(), code_units.end()); } void on_code_unit(char_type c) { current_value() += c; } void on_end_string() {} void on_begin_array() { new_tree(); stack.back().k = array; } void on_end_array() { if (stack.back().k == leaf) stack.pop_back(); stack.pop_back(); } void on_begin_object() { new_tree(); stack.back().k = object; } void on_end_object() { if (stack.back().k == leaf) stack.pop_back(); stack.pop_back(); } Ptree& output() { return root; } protected: bool is_key() const { return stack.back().k == key; } string& current_value() { layer& l = stack.back(); switch (l.k) { case key: return key_buffer; default: return l.t->data(); } } private: Ptree root; string key_buffer; enum kind { array, object, key, leaf }; struct layer { kind k; Ptree* t; }; std::vector stack; Ptree& new_tree() { if (stack.empty()) { layer l = {leaf, &root}; stack.push_back(l); return root; } layer& l = stack.back(); switch (l.k) { case array: { l.t->push_back(std::make_pair(string(), Ptree())); layer nl = {leaf, &l.t->back().second}; stack.push_back(nl); return *stack.back().t; } case object: default: BOOST_ASSERT(false); // must start with string, i.e. call new_value case key: { l.t->push_back(std::make_pair(key_buffer, Ptree())); l.k = object; layer nl = {leaf, &l.t->back().second}; stack.push_back(nl); return *stack.back().t; } case leaf: stack.pop_back(); return new_tree(); } } string& new_value() { if (stack.empty()) return new_tree().data(); layer& l = stack.back(); switch (l.k) { case leaf: stack.pop_back(); return new_value(); case object: l.k = key; key_buffer.clear(); return key_buffer; default: return new_tree().data(); } } }; }}}} #endif