nodebuilder.cpp 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. #include <assert.h>
  2. #include <cassert>
  3. #include "nodebuilder.h"
  4. #include "yaml-cpp/node/detail/node.h"
  5. #include "yaml-cpp/node/impl.h"
  6. #include "yaml-cpp/node/node.h"
  7. #include "yaml-cpp/node/type.h"
  8. namespace YAML {
  9. struct Mark;
  10. NodeBuilder::NodeBuilder()
  11. : m_pMemory(new detail::memory_holder), m_pRoot(0), m_mapDepth(0) {
  12. m_anchors.push_back(0); // since the anchors start at 1
  13. }
  14. NodeBuilder::~NodeBuilder() {}
  15. Node NodeBuilder::Root() {
  16. if (!m_pRoot)
  17. return Node();
  18. return Node(*m_pRoot, m_pMemory);
  19. }
  20. void NodeBuilder::OnDocumentStart(const Mark&) {}
  21. void NodeBuilder::OnDocumentEnd() {}
  22. void NodeBuilder::OnNull(const Mark& mark, anchor_t anchor) {
  23. detail::node& node = Push(mark, anchor);
  24. node.set_null();
  25. Pop();
  26. }
  27. void NodeBuilder::OnAlias(const Mark& /* mark */, anchor_t anchor) {
  28. detail::node& node = *m_anchors[anchor];
  29. Push(node);
  30. Pop();
  31. }
  32. void NodeBuilder::OnScalar(const Mark& mark, const std::string& tag,
  33. anchor_t anchor, const std::string& value) {
  34. detail::node& node = Push(mark, anchor);
  35. node.set_scalar(value);
  36. node.set_tag(tag);
  37. Pop();
  38. }
  39. void NodeBuilder::OnSequenceStart(const Mark& mark, const std::string& tag,
  40. anchor_t anchor, EmitterStyle::value style) {
  41. detail::node& node = Push(mark, anchor);
  42. node.set_tag(tag);
  43. node.set_type(NodeType::Sequence);
  44. node.set_style(style);
  45. }
  46. void NodeBuilder::OnSequenceEnd() { Pop(); }
  47. void NodeBuilder::OnMapStart(const Mark& mark, const std::string& tag,
  48. anchor_t anchor, EmitterStyle::value style) {
  49. detail::node& node = Push(mark, anchor);
  50. node.set_type(NodeType::Map);
  51. node.set_tag(tag);
  52. node.set_style(style);
  53. m_mapDepth++;
  54. }
  55. void NodeBuilder::OnMapEnd() {
  56. assert(m_mapDepth > 0);
  57. m_mapDepth--;
  58. Pop();
  59. }
  60. detail::node& NodeBuilder::Push(const Mark& mark, anchor_t anchor) {
  61. detail::node& node = m_pMemory->create_node();
  62. node.set_mark(mark);
  63. RegisterAnchor(anchor, node);
  64. Push(node);
  65. return node;
  66. }
  67. void NodeBuilder::Push(detail::node& node) {
  68. const bool needsKey =
  69. (!m_stack.empty() && m_stack.back()->type() == NodeType::Map &&
  70. m_keys.size() < m_mapDepth);
  71. m_stack.push_back(&node);
  72. if (needsKey)
  73. m_keys.push_back(PushedKey(&node, false));
  74. }
  75. void NodeBuilder::Pop() {
  76. assert(!m_stack.empty());
  77. if (m_stack.size() == 1) {
  78. m_pRoot = m_stack[0];
  79. m_stack.pop_back();
  80. return;
  81. }
  82. detail::node& node = *m_stack.back();
  83. m_stack.pop_back();
  84. detail::node& collection = *m_stack.back();
  85. if (collection.type() == NodeType::Sequence) {
  86. collection.push_back(node, m_pMemory);
  87. } else if (collection.type() == NodeType::Map) {
  88. assert(!m_keys.empty());
  89. PushedKey& key = m_keys.back();
  90. if (key.second) {
  91. collection.insert(*key.first, node, m_pMemory);
  92. m_keys.pop_back();
  93. } else {
  94. key.second = true;
  95. }
  96. } else {
  97. assert(false);
  98. m_stack.clear();
  99. }
  100. }
  101. void NodeBuilder::RegisterAnchor(anchor_t anchor, detail::node& node) {
  102. if (anchor) {
  103. assert(anchor == m_anchors.size());
  104. m_anchors.push_back(&node);
  105. }
  106. }
  107. }