1 #ifndef GRAPHBUILDERADAPTER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
2 #define GRAPHBUILDERADAPTER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
3 
4 #if defined(_MSC_VER) ||                                            \
5     (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
6      (__GNUC__ >= 4))  // GCC supports "pragma once" correctly since 3.4
7 #pragma once
8 #endif
9 
10 #include <cstdlib>
11 #include <map>
12 #include <stack>
13 
14 #include "yaml-cpp/anchor.h"
15 #include "yaml-cpp/contrib/anchordict.h"
16 #include "yaml-cpp/contrib/graphbuilder.h"
17 #include "yaml-cpp/emitterstyle.h"
18 #include "yaml-cpp/eventhandler.h"
19 
20 namespace YAML {
21 class GraphBuilderInterface;
22 struct Mark;
23 }  // namespace YAML
24 
25 namespace YAML {
26 class GraphBuilderAdapter : public EventHandler {
27  public:
GraphBuilderAdapter(GraphBuilderInterface & builder)28   GraphBuilderAdapter(GraphBuilderInterface& builder)
29       : m_builder(builder),
30         m_containers{},
31         m_anchors{},
32         m_pRootNode(nullptr),
33         m_pKeyNode(nullptr) {}
34   GraphBuilderAdapter(const GraphBuilderAdapter&) = delete;
35   GraphBuilderAdapter(GraphBuilderAdapter&&) = delete;
36   GraphBuilderAdapter& operator=(const GraphBuilderAdapter&) = delete;
37   GraphBuilderAdapter& operator=(GraphBuilderAdapter&&) = delete;
38 
OnDocumentStart(const Mark & mark)39   virtual void OnDocumentStart(const Mark& mark) { (void)mark; }
OnDocumentEnd()40   virtual void OnDocumentEnd() {}
41 
42   virtual void OnNull(const Mark& mark, anchor_t anchor);
43   virtual void OnAlias(const Mark& mark, anchor_t anchor);
44   virtual void OnScalar(const Mark& mark, const std::string& tag,
45                         anchor_t anchor, const std::string& value);
46 
47   virtual void OnSequenceStart(const Mark& mark, const std::string& tag,
48                                anchor_t anchor, EmitterStyle::value style);
49   virtual void OnSequenceEnd();
50 
51   virtual void OnMapStart(const Mark& mark, const std::string& tag,
52                           anchor_t anchor, EmitterStyle::value style);
53   virtual void OnMapEnd();
54 
RootNode()55   void* RootNode() const { return m_pRootNode; }
56 
57  private:
58   struct ContainerFrame {
ContainerFrameContainerFrame59     ContainerFrame(void* pSequence)
60         : pContainer(pSequence), pPrevKeyNode(&sequenceMarker) {}
ContainerFrameContainerFrame61     ContainerFrame(void* pMap, void* pPreviousKeyNode)
62         : pContainer(pMap), pPrevKeyNode(pPreviousKeyNode) {}
63 
64     void* pContainer;
65     void* pPrevKeyNode;
66 
isMapContainerFrame67     bool isMap() const { return pPrevKeyNode != &sequenceMarker; }
68 
69    private:
70     static int sequenceMarker;
71   };
72   typedef std::stack<ContainerFrame> ContainerStack;
73   typedef AnchorDict<void*> AnchorMap;
74 
75   GraphBuilderInterface& m_builder;
76   ContainerStack m_containers;
77   AnchorMap m_anchors;
78   void* m_pRootNode;
79   void* m_pKeyNode;
80 
81   void* GetCurrentParent() const;
82   void RegisterAnchor(anchor_t anchor, void* pNode);
83   void DispositionNode(void* pNode);
84 };
85 }  // namespace YAML
86 
87 #endif  // GRAPHBUILDERADAPTER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
88