Go to the documentation of this file.00001 #include "yaml-cpp-pm/node.h"
00002 #include "yaml-cpp-pm/aliasmanager.h"
00003 #include "yaml-cpp-pm/emitfromevents.h"
00004 #include "yaml-cpp-pm/emitter.h"
00005 #include "yaml-cpp-pm/eventhandler.h"
00006 #include "iterpriv.h"
00007 #include "nodebuilder.h"
00008 #include "nodeownership.h"
00009 #include "scanner.h"
00010 #include "tag.h"
00011 #include "token.h"
00012 #include <cassert>
00013 #include <stdexcept>
00014
00015 namespace YAML_PM
00016 {
00017 bool ltnode::operator()(const Node *pNode1, const Node *pNode2) const {
00018 return *pNode1 < *pNode2;
00019 }
00020
00021 Node::Node(): m_pOwnership(new NodeOwnership), m_type(NodeType::Null)
00022 {
00023 }
00024
00025 Node::Node(NodeOwnership& owner): m_pOwnership(new NodeOwnership(&owner)), m_type(NodeType::Null)
00026 {
00027 }
00028
00029 Node::~Node()
00030 {
00031 Clear();
00032 }
00033
00034 void Node::Clear()
00035 {
00036 m_pOwnership.reset(new NodeOwnership);
00037 m_type = NodeType::Null;
00038 m_tag.clear();
00039 m_scalarData.clear();
00040 m_seqData.clear();
00041 m_mapData.clear();
00042 }
00043
00044 bool Node::IsAliased() const
00045 {
00046 return m_pOwnership->IsAliased(*this);
00047 }
00048
00049 Node& Node::CreateNode()
00050 {
00051 return m_pOwnership->Create();
00052 }
00053
00054 std::auto_ptr<Node> Node::Clone() const
00055 {
00056 std::auto_ptr<Node> pNode(new Node);
00057 NodeBuilder nodeBuilder(*pNode);
00058 EmitEvents(nodeBuilder);
00059 return pNode;
00060 }
00061
00062 void Node::EmitEvents(EventHandler& eventHandler) const
00063 {
00064 eventHandler.OnDocumentStart(m_mark);
00065 AliasManager am;
00066 EmitEvents(am, eventHandler);
00067 eventHandler.OnDocumentEnd();
00068 }
00069
00070 void Node::EmitEvents(AliasManager& am, EventHandler& eventHandler) const
00071 {
00072 anchor_t anchor = NullAnchor;
00073 if(IsAliased()) {
00074 anchor = am.LookupAnchor(*this);
00075 if(anchor) {
00076 eventHandler.OnAlias(m_mark, anchor);
00077 return;
00078 }
00079
00080 am.RegisterReference(*this);
00081 anchor = am.LookupAnchor(*this);
00082 }
00083
00084 switch(m_type) {
00085 case NodeType::Null:
00086 eventHandler.OnNull(m_mark, anchor);
00087 break;
00088 case NodeType::Scalar:
00089 eventHandler.OnScalar(m_mark, m_tag, anchor, m_scalarData);
00090 break;
00091 case NodeType::Sequence:
00092 eventHandler.OnSequenceStart(m_mark, m_tag, anchor);
00093 for(std::size_t i=0;i<m_seqData.size();i++)
00094 m_seqData[i]->EmitEvents(am, eventHandler);
00095 eventHandler.OnSequenceEnd();
00096 break;
00097 case NodeType::Map:
00098 eventHandler.OnMapStart(m_mark, m_tag, anchor);
00099 for(node_map::const_iterator it=m_mapData.begin();it!=m_mapData.end();++it) {
00100 it->first->EmitEvents(am, eventHandler);
00101 it->second->EmitEvents(am, eventHandler);
00102 }
00103 eventHandler.OnMapEnd();
00104 break;
00105 }
00106 }
00107
00108 void Node::Init(NodeType::value type, const Mark& mark, const std::string& tag)
00109 {
00110 Clear();
00111 m_mark = mark;
00112 m_type = type;
00113 m_tag = tag;
00114 }
00115
00116 void Node::MarkAsAliased()
00117 {
00118 m_pOwnership->MarkAsAliased(*this);
00119 }
00120
00121 void Node::SetScalarData(const std::string& data)
00122 {
00123 assert(m_type == NodeType::Scalar);
00124 m_scalarData = data;
00125 }
00126
00127 void Node::Append(Node& node)
00128 {
00129 assert(m_type == NodeType::Sequence);
00130 m_seqData.push_back(&node);
00131 }
00132
00133 void Node::Insert(Node& key, Node& value)
00134 {
00135 assert(m_type == NodeType::Map);
00136 m_mapData[&key] = &value;
00137 }
00138
00139
00140
00141 Iterator Node::begin() const
00142 {
00143 switch(m_type) {
00144 case NodeType::Null:
00145 case NodeType::Scalar:
00146 return Iterator();
00147 case NodeType::Sequence:
00148 return Iterator(std::auto_ptr<IterPriv>(new IterPriv(m_seqData.begin())));
00149 case NodeType::Map:
00150 return Iterator(std::auto_ptr<IterPriv>(new IterPriv(m_mapData.begin())));
00151 }
00152
00153 assert(false);
00154 return Iterator();
00155 }
00156
00157
00158
00159 Iterator Node::end() const
00160 {
00161 switch(m_type) {
00162 case NodeType::Null:
00163 case NodeType::Scalar:
00164 return Iterator();
00165 case NodeType::Sequence:
00166 return Iterator(std::auto_ptr<IterPriv>(new IterPriv(m_seqData.end())));
00167 case NodeType::Map:
00168 return Iterator(std::auto_ptr<IterPriv>(new IterPriv(m_mapData.end())));
00169 }
00170
00171 assert(false);
00172 return Iterator();
00173 }
00174
00175
00176
00177
00178 std::size_t Node::size() const
00179 {
00180 switch(m_type) {
00181 case NodeType::Null:
00182 case NodeType::Scalar:
00183 return 0;
00184 case NodeType::Sequence:
00185 return m_seqData.size();
00186 case NodeType::Map:
00187 return m_mapData.size();
00188 }
00189
00190 assert(false);
00191 return 0;
00192 }
00193
00194 const Node *Node::FindAtIndex(std::size_t i) const
00195 {
00196 if(m_type == NodeType::Sequence)
00197 return m_seqData[i];
00198 return 0;
00199 }
00200
00201 bool Node::GetScalar(std::string& s) const
00202 {
00203 switch(m_type) {
00204 case NodeType::Null:
00205 s = "~";
00206 return true;
00207 case NodeType::Scalar:
00208 s = m_scalarData;
00209 return true;
00210 case NodeType::Sequence:
00211 case NodeType::Map:
00212 return false;
00213 }
00214
00215 assert(false);
00216 return false;
00217 }
00218
00219 Emitter& operator << (Emitter& out, const Node& node)
00220 {
00221 EmitFromEvents emitFromEvents(out);
00222 node.EmitEvents(emitFromEvents);
00223 return out;
00224 }
00225
00226 int Node::Compare(const Node& rhs) const
00227 {
00228 if(m_type != rhs.m_type)
00229 return rhs.m_type - m_type;
00230
00231 switch(m_type) {
00232 case NodeType::Null:
00233 return 0;
00234 case NodeType::Scalar:
00235 return m_scalarData.compare(rhs.m_scalarData);
00236 case NodeType::Sequence:
00237 if(m_seqData.size() < rhs.m_seqData.size())
00238 return 1;
00239 else if(m_seqData.size() > rhs.m_seqData.size())
00240 return -1;
00241 for(std::size_t i=0;i<m_seqData.size();i++)
00242 if(int cmp = m_seqData[i]->Compare(*rhs.m_seqData[i]))
00243 return cmp;
00244 return 0;
00245 case NodeType::Map:
00246 if(m_mapData.size() < rhs.m_mapData.size())
00247 return 1;
00248 else if(m_mapData.size() > rhs.m_mapData.size())
00249 return -1;
00250 node_map::const_iterator it = m_mapData.begin();
00251 node_map::const_iterator jt = rhs.m_mapData.begin();
00252 for(;it!=m_mapData.end() && jt!=rhs.m_mapData.end();it++, jt++) {
00253 if(int cmp = it->first->Compare(*jt->first))
00254 return cmp;
00255 if(int cmp = it->second->Compare(*jt->second))
00256 return cmp;
00257 }
00258 return 0;
00259 }
00260
00261 assert(false);
00262 return 0;
00263 }
00264
00265 bool operator < (const Node& n1, const Node& n2)
00266 {
00267 return n1.Compare(n2) < 0;
00268 }
00269 }