Back to home page

EIC code displayed by LXR

 
 

    


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); // must start with string, i.e. call new_value
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