diff options
author | Devtools Arcadia <arcadia-devtools@yandex-team.ru> | 2022-02-07 18:08:42 +0300 |
---|---|---|
committer | Devtools Arcadia <arcadia-devtools@mous.vla.yp-c.yandex.net> | 2022-02-07 18:08:42 +0300 |
commit | 1110808a9d39d4b808aef724c861a2e1a38d2a69 (patch) | |
tree | e26c9fed0de5d9873cce7e00bc214573dc2195b7 /contrib/libs/yaml-cpp/src/nodebuilder.cpp | |
download | ydb-1110808a9d39d4b808aef724c861a2e1a38d2a69.tar.gz |
intermediate changes
ref:cde9a383711a11544ce7e107a78147fb96cc4029
Diffstat (limited to 'contrib/libs/yaml-cpp/src/nodebuilder.cpp')
-rw-r--r-- | contrib/libs/yaml-cpp/src/nodebuilder.cpp | 130 |
1 files changed, 130 insertions, 0 deletions
diff --git a/contrib/libs/yaml-cpp/src/nodebuilder.cpp b/contrib/libs/yaml-cpp/src/nodebuilder.cpp new file mode 100644 index 0000000000..093d2efeb7 --- /dev/null +++ b/contrib/libs/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); + } +} +} |