diff options
Diffstat (limited to 'src/libs/3rdparty/yaml-cpp/src/nodebuilder.cpp')
-rw-r--r-- | src/libs/3rdparty/yaml-cpp/src/nodebuilder.cpp | 130 |
1 files changed, 130 insertions, 0 deletions
diff --git a/src/libs/3rdparty/yaml-cpp/src/nodebuilder.cpp b/src/libs/3rdparty/yaml-cpp/src/nodebuilder.cpp new file mode 100644 index 00000000000..093d2efeb77 --- /dev/null +++ b/src/libs/3rdparty/yaml-cpp/src/nodebuilder.cpp @@ -0,0 +1,130 @@ +#include <assert.h> +#include <cassert> + +#include "nodebuilder.h" +#include "yaml-cpp/node/detail/node.h" +#include "yaml-cpp/node/impl.h" +#include "yaml-cpp/node/node.h" +#include "yaml-cpp/node/type.h" + +namespace YAML { +struct Mark; + +NodeBuilder::NodeBuilder() + : m_pMemory(new detail::memory_holder), m_pRoot(0), m_mapDepth(0) { + m_anchors.push_back(0); // since the anchors start at 1 +} + +NodeBuilder::~NodeBuilder() {} + +Node NodeBuilder::Root() { + if (!m_pRoot) + return Node(); + + return Node(*m_pRoot, m_pMemory); +} + +void NodeBuilder::OnDocumentStart(const Mark&) {} + +void NodeBuilder::OnDocumentEnd() {} + +void NodeBuilder::OnNull(const Mark& mark, anchor_t anchor) { + detail::node& node = Push(mark, anchor); + node.set_null(); + Pop(); +} + +void NodeBuilder::OnAlias(const Mark& /* mark */, anchor_t anchor) { + detail::node& node = *m_anchors[anchor]; + Push(node); + Pop(); +} + +void NodeBuilder::OnScalar(const Mark& mark, const std::string& tag, + anchor_t anchor, const std::string& value) { + detail::node& node = Push(mark, anchor); + node.set_scalar(value); + node.set_tag(tag); + Pop(); +} + +void NodeBuilder::OnSequenceStart(const Mark& mark, const std::string& tag, + anchor_t anchor, EmitterStyle::value style) { + detail::node& node = Push(mark, anchor); + node.set_tag(tag); + node.set_type(NodeType::Sequence); + node.set_style(style); +} + +void NodeBuilder::OnSequenceEnd() { Pop(); } + +void NodeBuilder::OnMapStart(const Mark& mark, const std::string& tag, + anchor_t anchor, EmitterStyle::value style) { + detail::node& node = Push(mark, anchor); + node.set_type(NodeType::Map); + node.set_tag(tag); + node.set_style(style); + m_mapDepth++; +} + +void NodeBuilder::OnMapEnd() { + assert(m_mapDepth > 0); + m_mapDepth--; + Pop(); +} + +detail::node& NodeBuilder::Push(const Mark& mark, anchor_t anchor) { + detail::node& node = m_pMemory->create_node(); + node.set_mark(mark); + RegisterAnchor(anchor, node); + Push(node); + return node; +} + +void NodeBuilder::Push(detail::node& node) { + const bool needsKey = + (!m_stack.empty() && m_stack.back()->type() == NodeType::Map && + m_keys.size() < m_mapDepth); + + m_stack.push_back(&node); + if (needsKey) + m_keys.push_back(PushedKey(&node, false)); +} + +void NodeBuilder::Pop() { + assert(!m_stack.empty()); + if (m_stack.size() == 1) { + m_pRoot = m_stack[0]; + m_stack.pop_back(); + return; + } + + detail::node& node = *m_stack.back(); + m_stack.pop_back(); + + detail::node& collection = *m_stack.back(); + + if (collection.type() == NodeType::Sequence) { + collection.push_back(node, m_pMemory); + } else if (collection.type() == NodeType::Map) { + assert(!m_keys.empty()); + PushedKey& key = m_keys.back(); + if (key.second) { + collection.insert(*key.first, node, m_pMemory); + m_keys.pop_back(); + } else { + key.second = true; + } + } else { + assert(false); + m_stack.clear(); + } +} + +void NodeBuilder::RegisterAnchor(anchor_t anchor, detail::node& node) { + if (anchor) { + assert(anchor == m_anchors.size()); + m_anchors.push_back(&node); + } +} +} |