diff options
Diffstat (limited to 'yaml-cpp/src/nodebuilder.cpp')
-rwxr-xr-x | yaml-cpp/src/nodebuilder.cpp | 145 |
1 files changed, 145 insertions, 0 deletions
diff --git a/yaml-cpp/src/nodebuilder.cpp b/yaml-cpp/src/nodebuilder.cpp new file mode 100755 index 00000000..13a70326 --- /dev/null +++ b/yaml-cpp/src/nodebuilder.cpp @@ -0,0 +1,145 @@ +#include "nodebuilder.h" +#include "yaml-cpp/mark.h" +#include "yaml-cpp/node.h" +#include <cassert> + +namespace YAML +{ + NodeBuilder::NodeBuilder(Node& root): m_root(root), m_initializedRoot(false), m_finished(false) + { + m_root.Clear(); + m_anchors.push_back(0); // since the anchors start at 1 + } + + NodeBuilder::~NodeBuilder() + { + } + + void NodeBuilder::OnDocumentStart(const Mark&) + { + } + + void NodeBuilder::OnDocumentEnd() + { + assert(m_finished); + } + + void NodeBuilder::OnNull(const Mark& mark, anchor_t anchor) + { + Node& node = Push(anchor); + node.Init(NodeType::Null, mark, ""); + Pop(); + } + + void NodeBuilder::OnAlias(const Mark& /*mark*/, anchor_t anchor) + { + Node& node = *m_anchors[anchor]; + Insert(node); + node.MarkAsAliased(); + } + + void NodeBuilder::OnScalar(const Mark& mark, const std::string& tag, anchor_t anchor, const std::string& value) + { + Node& node = Push(anchor); + node.Init(NodeType::Scalar, mark, tag); + node.SetScalarData(value); + Pop(); + } + + void NodeBuilder::OnSequenceStart(const Mark& mark, const std::string& tag, anchor_t anchor) + { + Node& node = Push(anchor); + node.Init(NodeType::Sequence, mark, tag); + } + + void NodeBuilder::OnSequenceEnd() + { + Pop(); + } + + void NodeBuilder::OnMapStart(const Mark& mark, const std::string& tag, anchor_t anchor) + { + Node& node = Push(anchor); + node.Init(NodeType::Map, mark, tag); + m_didPushKey.push(false); + } + + void NodeBuilder::OnMapEnd() + { + m_didPushKey.pop(); + Pop(); + } + + Node& NodeBuilder::Push(anchor_t anchor) + { + Node& node = Push(); + RegisterAnchor(anchor, node); + return node; + } + + Node& NodeBuilder::Push() + { + if(!m_initializedRoot) { + m_initializedRoot = true; + return m_root; + } + + Node& node = m_root.CreateNode(); + m_stack.push(&node); + return node; + } + + Node& NodeBuilder::Top() + { + return m_stack.empty() ? m_root : *m_stack.top(); + } + + void NodeBuilder::Pop() + { + assert(!m_finished); + if(m_stack.empty()) { + m_finished = true; + return; + } + + Node& node = *m_stack.top(); + m_stack.pop(); + Insert(node); + } + + void NodeBuilder::Insert(Node& node) + { + Node& curTop = Top(); + switch(curTop.Type()) { + case NodeType::Null: + case NodeType::Scalar: + assert(false); + break; + case NodeType::Sequence: + curTop.Append(node); + break; + case NodeType::Map: + assert(!m_didPushKey.empty()); + if(m_didPushKey.top()) { + assert(!m_pendingKeys.empty()); + + Node& key = *m_pendingKeys.top(); + m_pendingKeys.pop(); + curTop.Insert(key, node); + m_didPushKey.top() = false; + } else { + m_pendingKeys.push(&node); + m_didPushKey.top() = true; + } + break; + } + } + + void NodeBuilder::RegisterAnchor(anchor_t anchor, Node& node) + { + if(anchor) { + assert(anchor == m_anchors.size()); + m_anchors.push_back(&node); + } + } +} |