yaml-cpp

FORK: A YAML parser and emitter in C++
git clone https://git.neptards.moe/neptards/yaml-cpp.git
Log | Files | Refs | README | LICENSE

nodeevents.cpp (2607B)


      1 #include "nodeevents.h"
      2 #include "yaml-cpp/eventhandler.h"
      3 #include "yaml-cpp/mark.h"
      4 #include "yaml-cpp/node/detail/node.h"
      5 #include "yaml-cpp/node/detail/node_iterator.h"
      6 #include "yaml-cpp/node/node.h"
      7 #include "yaml-cpp/node/type.h"
      8 
      9 namespace YAML {
     10 void NodeEvents::AliasManager::RegisterReference(const detail::node& node) {
     11   m_anchorByIdentity.insert(std::make_pair(node.ref(), _CreateNewAnchor()));
     12 }
     13 
     14 anchor_t NodeEvents::AliasManager::LookupAnchor(
     15     const detail::node& node) const {
     16   auto it = m_anchorByIdentity.find(node.ref());
     17   if (it == m_anchorByIdentity.end())
     18     return 0;
     19   return it->second;
     20 }
     21 
     22 NodeEvents::NodeEvents(const Node& node)
     23     : m_pMemory(node.m_pMemory), m_root(node.m_pNode), m_refCount{} {
     24   if (m_root)
     25     Setup(*m_root);
     26 }
     27 
     28 void NodeEvents::Setup(const detail::node& node) {
     29   int& refCount = m_refCount[node.ref()];
     30   refCount++;
     31   if (refCount > 1)
     32     return;
     33 
     34   if (node.type() == NodeType::Sequence) {
     35     for (auto element : node)
     36       Setup(*element);
     37   } else if (node.type() == NodeType::Map) {
     38     for (auto element : node) {
     39       Setup(*element.first);
     40       Setup(*element.second);
     41     }
     42   }
     43 }
     44 
     45 void NodeEvents::Emit(EventHandler& handler) {
     46   AliasManager am;
     47 
     48   handler.OnDocumentStart(Mark());
     49   if (m_root)
     50     Emit(*m_root, handler, am);
     51   handler.OnDocumentEnd();
     52 }
     53 
     54 void NodeEvents::Emit(const detail::node& node, EventHandler& handler,
     55                       AliasManager& am) const {
     56   anchor_t anchor = NullAnchor;
     57   if (IsAliased(node)) {
     58     anchor = am.LookupAnchor(node);
     59     if (anchor) {
     60       handler.OnAlias(Mark(), anchor);
     61       return;
     62     }
     63 
     64     am.RegisterReference(node);
     65     anchor = am.LookupAnchor(node);
     66   }
     67 
     68   switch (node.type()) {
     69     case NodeType::Undefined:
     70       break;
     71     case NodeType::Null:
     72       handler.OnNull(Mark(), anchor);
     73       break;
     74     case NodeType::Scalar:
     75       handler.OnScalar(Mark(), node.tag(), anchor, node.scalar());
     76       break;
     77     case NodeType::Sequence:
     78       handler.OnSequenceStart(Mark(), node.tag(), anchor, node.style());
     79       for (auto element : node)
     80         Emit(*element, handler, am);
     81       handler.OnSequenceEnd();
     82       break;
     83     case NodeType::Map:
     84       handler.OnMapStart(Mark(), node.tag(), anchor, node.style());
     85       for (auto element : node) {
     86         Emit(*element.first, handler, am);
     87         Emit(*element.second, handler, am);
     88       }
     89       handler.OnMapEnd();
     90       break;
     91   }
     92 }
     93 
     94 bool NodeEvents::IsAliased(const detail::node& node) const {
     95   auto it = m_refCount.find(node.ref());
     96   return it != m_refCount.end() && it->second > 1;
     97 }
     98 }  // namespace YAML