nodeevents.cpp 2.65 KB
Newer Older
1
2
3
4
5
6
#include "nodeevents.h"
#include "yaml-cpp/node/node.h"
#include "yaml-cpp/node/impl.h"
#include "yaml-cpp/eventhandler.h"
#include "yaml-cpp/mark.h"

Jesse Beder's avatar
Jesse Beder committed
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
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;
31

Jesse Beder's avatar
Jesse Beder committed
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
  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();
}
52

Jesse Beder's avatar
Jesse Beder committed
53
54
55
56
57
58
59
60
61
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;
    }
62

Jesse Beder's avatar
Jesse Beder committed
63
64
65
    am.RegisterReference(node);
    anchor = am.LookupAnchor(node);
  }
66

Jesse Beder's avatar
Jesse Beder committed
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
  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);
      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);
      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;
  }
}
94

Jesse Beder's avatar
Jesse Beder committed
95
96
97
98
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;
}
99
}