Go to the documentation of this file.00001 #include "nodebuilder.h"
00002 #include "yaml-cpp-pm/mark.h"
00003 #include "yaml-cpp-pm/node.h"
00004 #include <cassert>
00005
00006 namespace YAML_PM
00007 {
00008 NodeBuilder::NodeBuilder(Node& root): m_root(root), m_initializedRoot(false), m_finished(false)
00009 {
00010 m_root.Clear();
00011 m_anchors.push_back(0);
00012 }
00013
00014 NodeBuilder::~NodeBuilder()
00015 {
00016 }
00017
00018 void NodeBuilder::OnDocumentStart(const Mark&)
00019 {
00020 }
00021
00022 void NodeBuilder::OnDocumentEnd()
00023 {
00024 assert(m_finished);
00025 }
00026
00027 void NodeBuilder::OnNull(const Mark& mark, anchor_t anchor)
00028 {
00029 Node& node = Push(anchor);
00030 node.Init(NodeType::Null, mark, "");
00031 Pop();
00032 }
00033
00034 void NodeBuilder::OnAlias(const Mark& , anchor_t anchor)
00035 {
00036 Node& node = *m_anchors[anchor];
00037 Insert(node);
00038 node.MarkAsAliased();
00039 }
00040
00041 void NodeBuilder::OnScalar(const Mark& mark, const std::string& tag, anchor_t anchor, const std::string& value)
00042 {
00043 Node& node = Push(anchor);
00044 node.Init(NodeType::Scalar, mark, tag);
00045 node.SetScalarData(value);
00046 Pop();
00047 }
00048
00049 void NodeBuilder::OnSequenceStart(const Mark& mark, const std::string& tag, anchor_t anchor)
00050 {
00051 Node& node = Push(anchor);
00052 node.Init(NodeType::Sequence, mark, tag);
00053 }
00054
00055 void NodeBuilder::OnSequenceEnd()
00056 {
00057 Pop();
00058 }
00059
00060 void NodeBuilder::OnMapStart(const Mark& mark, const std::string& tag, anchor_t anchor)
00061 {
00062 Node& node = Push(anchor);
00063 node.Init(NodeType::Map, mark, tag);
00064 m_didPushKey.push(false);
00065 }
00066
00067 void NodeBuilder::OnMapEnd()
00068 {
00069 m_didPushKey.pop();
00070 Pop();
00071 }
00072
00073 Node& NodeBuilder::Push(anchor_t anchor)
00074 {
00075 Node& node = Push();
00076 RegisterAnchor(anchor, node);
00077 return node;
00078 }
00079
00080 Node& NodeBuilder::Push()
00081 {
00082 if(!m_initializedRoot) {
00083 m_initializedRoot = true;
00084 return m_root;
00085 }
00086
00087 Node& node = m_root.CreateNode();
00088 m_stack.push(&node);
00089 return node;
00090 }
00091
00092 Node& NodeBuilder::Top()
00093 {
00094 return m_stack.empty() ? m_root : *m_stack.top();
00095 }
00096
00097 void NodeBuilder::Pop()
00098 {
00099 assert(!m_finished);
00100 if(m_stack.empty()) {
00101 m_finished = true;
00102 return;
00103 }
00104
00105 Node& node = *m_stack.top();
00106 m_stack.pop();
00107 Insert(node);
00108 }
00109
00110 void NodeBuilder::Insert(Node& node)
00111 {
00112 Node& curTop = Top();
00113 switch(curTop.Type()) {
00114 case NodeType::Null:
00115 case NodeType::Scalar:
00116 assert(false);
00117 break;
00118 case NodeType::Sequence:
00119 curTop.Append(node);
00120 break;
00121 case NodeType::Map:
00122 assert(!m_didPushKey.empty());
00123 if(m_didPushKey.top()) {
00124 assert(!m_pendingKeys.empty());
00125
00126 Node& key = *m_pendingKeys.top();
00127 m_pendingKeys.pop();
00128 curTop.Insert(key, node);
00129 m_didPushKey.top() = false;
00130 } else {
00131 m_pendingKeys.push(&node);
00132 m_didPushKey.top() = true;
00133 }
00134 break;
00135 }
00136 }
00137
00138 void NodeBuilder::RegisterAnchor(anchor_t anchor, Node& node)
00139 {
00140 if(anchor) {
00141 assert(anchor == m_anchors.size());
00142 m_anchors.push_back(&node);
00143 }
00144 }
00145 }