standard_callbacks.hpp 4.5 KB

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