1 #include "graphbuilderadapter.h"
2 #include "yaml-cpp/contrib/graphbuilder.h"
3 
4 namespace YAML {
5 struct Mark;
6 
7 int GraphBuilderAdapter::ContainerFrame::sequenceMarker;
8 
OnNull(const Mark & mark,anchor_t anchor)9 void GraphBuilderAdapter::OnNull(const Mark &mark, anchor_t anchor) {
10   void *pParent = GetCurrentParent();
11   void *pNode = m_builder.NewNull(mark, pParent);
12   RegisterAnchor(anchor, pNode);
13 
14   DispositionNode(pNode);
15 }
16 
OnAlias(const Mark & mark,anchor_t anchor)17 void GraphBuilderAdapter::OnAlias(const Mark &mark, anchor_t anchor) {
18   void *pReffedNode = m_anchors.Get(anchor);
19   DispositionNode(m_builder.AnchorReference(mark, pReffedNode));
20 }
21 
OnScalar(const Mark & mark,const std::string & tag,anchor_t anchor,const std::string & value)22 void GraphBuilderAdapter::OnScalar(const Mark &mark, const std::string &tag,
23                                    anchor_t anchor, const std::string &value) {
24   void *pParent = GetCurrentParent();
25   void *pNode = m_builder.NewScalar(mark, tag, pParent, value);
26   RegisterAnchor(anchor, pNode);
27 
28   DispositionNode(pNode);
29 }
30 
OnSequenceStart(const Mark & mark,const std::string & tag,anchor_t anchor,EmitterStyle::value)31 void GraphBuilderAdapter::OnSequenceStart(const Mark &mark,
32                                           const std::string &tag,
33                                           anchor_t anchor,
34                                           EmitterStyle::value /* style */) {
35   void *pNode = m_builder.NewSequence(mark, tag, GetCurrentParent());
36   m_containers.push(ContainerFrame(pNode));
37   RegisterAnchor(anchor, pNode);
38 }
39 
OnSequenceEnd()40 void GraphBuilderAdapter::OnSequenceEnd() {
41   void *pSequence = m_containers.top().pContainer;
42   m_containers.pop();
43 
44   DispositionNode(pSequence);
45 }
46 
OnMapStart(const Mark & mark,const std::string & tag,anchor_t anchor,EmitterStyle::value)47 void GraphBuilderAdapter::OnMapStart(const Mark &mark, const std::string &tag,
48                                      anchor_t anchor,
49                                      EmitterStyle::value /* style */) {
50   void *pNode = m_builder.NewMap(mark, tag, GetCurrentParent());
51   m_containers.push(ContainerFrame(pNode, m_pKeyNode));
52   m_pKeyNode = nullptr;
53   RegisterAnchor(anchor, pNode);
54 }
55 
OnMapEnd()56 void GraphBuilderAdapter::OnMapEnd() {
57   void *pMap = m_containers.top().pContainer;
58   m_pKeyNode = m_containers.top().pPrevKeyNode;
59   m_containers.pop();
60   DispositionNode(pMap);
61 }
62 
GetCurrentParent() const63 void *GraphBuilderAdapter::GetCurrentParent() const {
64   if (m_containers.empty()) {
65     return nullptr;
66   }
67   return m_containers.top().pContainer;
68 }
69 
RegisterAnchor(anchor_t anchor,void * pNode)70 void GraphBuilderAdapter::RegisterAnchor(anchor_t anchor, void *pNode) {
71   if (anchor) {
72     m_anchors.Register(anchor, pNode);
73   }
74 }
75 
DispositionNode(void * pNode)76 void GraphBuilderAdapter::DispositionNode(void *pNode) {
77   if (m_containers.empty()) {
78     m_pRootNode = pNode;
79     return;
80   }
81 
82   void *pContainer = m_containers.top().pContainer;
83   if (m_containers.top().isMap()) {
84     if (m_pKeyNode) {
85       m_builder.AssignInMap(pContainer, m_pKeyNode, pNode);
86       m_pKeyNode = nullptr;
87     } else {
88       m_pKeyNode = pNode;
89     }
90   } else {
91     m_builder.AppendToSequence(pContainer, pNode);
92   }
93 }
94 }  // namespace YAML
95