aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/libs/yaml-cpp/src/nodeevents.cpp
diff options
context:
space:
mode:
authorDevtools Arcadia <arcadia-devtools@yandex-team.ru>2022-02-07 18:08:42 +0300
committerDevtools Arcadia <arcadia-devtools@mous.vla.yp-c.yandex.net>2022-02-07 18:08:42 +0300
commit1110808a9d39d4b808aef724c861a2e1a38d2a69 (patch)
treee26c9fed0de5d9873cce7e00bc214573dc2195b7 /contrib/libs/yaml-cpp/src/nodeevents.cpp
downloadydb-1110808a9d39d4b808aef724c861a2e1a38d2a69.tar.gz
intermediate changes
ref:cde9a383711a11544ce7e107a78147fb96cc4029
Diffstat (limited to 'contrib/libs/yaml-cpp/src/nodeevents.cpp')
-rw-r--r--contrib/libs/yaml-cpp/src/nodeevents.cpp101
1 files changed, 101 insertions, 0 deletions
diff --git a/contrib/libs/yaml-cpp/src/nodeevents.cpp b/contrib/libs/yaml-cpp/src/nodeevents.cpp
new file mode 100644
index 0000000000..82261feb05
--- /dev/null
+++ b/contrib/libs/yaml-cpp/src/nodeevents.cpp
@@ -0,0 +1,101 @@
+#include "nodeevents.h"
+#include "yaml-cpp/eventhandler.h"
+#include "yaml-cpp/mark.h"
+#include "yaml-cpp/node/detail/node.h"
+#include "yaml-cpp/node/detail/node_iterator.h"
+#include "yaml-cpp/node/node.h"
+#include "yaml-cpp/node/type.h"
+
+namespace YAML {
+void NodeEvents::AliasManager::RegisterReference(const detail::node& node) {
+ m_anchorByIdentity.insert(std::make_pair(node.ref(), _CreateNewAnchor()));
+}
+
+anchor_t NodeEvents::AliasManager::LookupAnchor(
+ const detail::node& node) const {
+ AnchorByIdentity::const_iterator it = m_anchorByIdentity.find(node.ref());
+ if (it == m_anchorByIdentity.end())
+ return 0;
+ return it->second;
+}
+
+NodeEvents::NodeEvents(const Node& node)
+ : m_pMemory(node.m_pMemory), m_root(node.m_pNode) {
+ if (m_root)
+ Setup(*m_root);
+}
+
+void NodeEvents::Setup(const detail::node& node) {
+ int& refCount = m_refCount[node.ref()];
+ refCount++;
+ if (refCount > 1)
+ return;
+
+ if (node.type() == NodeType::Sequence) {
+ for (detail::const_node_iterator it = node.begin(); it != node.end(); ++it)
+ Setup(**it);
+ } else if (node.type() == NodeType::Map) {
+ for (detail::const_node_iterator it = node.begin(); it != node.end();
+ ++it) {
+ Setup(*it->first);
+ Setup(*it->second);
+ }
+ }
+}
+
+void NodeEvents::Emit(EventHandler& handler) {
+ AliasManager am;
+
+ handler.OnDocumentStart(Mark());
+ if (m_root)
+ Emit(*m_root, handler, am);
+ handler.OnDocumentEnd();
+}
+
+void NodeEvents::Emit(const detail::node& node, EventHandler& handler,
+ AliasManager& am) const {
+ anchor_t anchor = NullAnchor;
+ if (IsAliased(node)) {
+ anchor = am.LookupAnchor(node);
+ if (anchor) {
+ handler.OnAlias(Mark(), anchor);
+ return;
+ }
+
+ am.RegisterReference(node);
+ anchor = am.LookupAnchor(node);
+ }
+
+ switch (node.type()) {
+ case NodeType::Undefined:
+ break;
+ case NodeType::Null:
+ handler.OnNull(Mark(), anchor);
+ break;
+ case NodeType::Scalar:
+ handler.OnScalar(Mark(), node.tag(), anchor, node.scalar());
+ break;
+ case NodeType::Sequence:
+ handler.OnSequenceStart(Mark(), node.tag(), anchor, node.style());
+ for (detail::const_node_iterator it = node.begin(); it != node.end();
+ ++it)
+ Emit(**it, handler, am);
+ handler.OnSequenceEnd();
+ break;
+ case NodeType::Map:
+ handler.OnMapStart(Mark(), node.tag(), anchor, node.style());
+ for (detail::const_node_iterator it = node.begin(); it != node.end();
+ ++it) {
+ Emit(*it->first, handler, am);
+ Emit(*it->second, handler, am);
+ }
+ handler.OnMapEnd();
+ break;
+ }
+}
+
+bool NodeEvents::IsAliased(const detail::node& node) const {
+ RefCount::const_iterator it = m_refCount.find(node.ref());
+ return it != m_refCount.end() && it->second > 1;
+}
+}