From fc22d55b5368c87676fcc0626b94f3de7b191f51 Mon Sep 17 00:00:00 2001 From: jbeder Date: Mon, 24 Aug 2009 20:10:42 +0000 Subject: [PATCH] Added Node::Clone function --- include/node.h | 5 +++++ src/aliascontent.cpp | 5 +++++ src/aliascontent.h | 2 ++ src/content.h | 2 ++ src/map.cpp | 14 ++++++++++++++ src/map.h | 9 +++++++-- src/node.cpp | 15 +++++++++++++++ src/scalar.cpp | 10 ++++++++++ src/scalar.h | 4 ++++ src/sequence.cpp | 11 +++++++++++ src/sequence.h | 3 +++ 11 files changed, 78 insertions(+), 2 deletions(-) diff --git a/include/node.h b/include/node.h index 9b6eb22..1d39ede 100644 --- a/include/node.h +++ b/include/node.h @@ -14,6 +14,7 @@ #include #include #include +#include namespace YAML { @@ -30,6 +31,7 @@ namespace YAML ~Node(); void Clear(); + std::auto_ptr Clone() const; void Parse(Scanner *pScanner, const ParserState& state); CONTENT_TYPE GetType() const; @@ -89,6 +91,9 @@ namespace YAML template const Node *FindValueForKey(const T& key) const; + + // helper for cloning + Node(const Mark& mark, const std::string& anchor, const std::string& tag, const Content *pContent); // helpers for parsing void ParseHeader(Scanner *pScanner, const ParserState& state); diff --git a/src/aliascontent.cpp b/src/aliascontent.cpp index 7d49b71..aa0f399 100644 --- a/src/aliascontent.cpp +++ b/src/aliascontent.cpp @@ -8,6 +8,11 @@ namespace YAML { } + Content *AliasContent::Clone() const + { + return 0; // TODO: how to clone an alias? + } + void AliasContent::Parse(Scanner * /*pScanner*/, const ParserState& /*state*/) { } diff --git a/src/aliascontent.h b/src/aliascontent.h index e6448fe..d4cbb56 100644 --- a/src/aliascontent.h +++ b/src/aliascontent.h @@ -12,6 +12,8 @@ namespace YAML { public: AliasContent(Content *pNodeContent); + + virtual Content *Clone() const; virtual void Parse(Scanner* pScanner, const ParserState& state); virtual void Write(Emitter&) const; diff --git a/src/content.h b/src/content.h index 1574691..71e7037 100644 --- a/src/content.h +++ b/src/content.h @@ -25,6 +25,8 @@ namespace YAML public: Content(); virtual ~Content(); + + virtual Content *Clone() const = 0; virtual void Parse(Scanner *pScanner, const ParserState& state) = 0; virtual void Write(Emitter& out) const = 0; diff --git a/src/map.cpp b/src/map.cpp index 4682829..f0038fc 100644 --- a/src/map.cpp +++ b/src/map.cpp @@ -12,6 +12,15 @@ namespace YAML Map::Map() { } + + Map::Map(const node_map& data) + { + for(node_map::const_iterator it=data.begin();it!=data.end();++it) { + std::auto_ptr pKey = it->first->Clone(); + std::auto_ptr pValue = it->second->Clone(); + m_data[pKey.release()] = pValue.release(); + } + } Map::~Map() { @@ -27,6 +36,11 @@ namespace YAML m_data.clear(); } + Content *Map::Clone() const + { + return new Map(m_data); + } + bool Map::GetBegin(std::map ::const_iterator& it) const { it = m_data.begin(); diff --git a/src/map.h b/src/map.h index d5b4b31..fc448b5 100644 --- a/src/map.h +++ b/src/map.h @@ -13,11 +13,17 @@ namespace YAML class Map: public Content { + private: + typedef std::map node_map; + public: Map(); + Map(const node_map& data); virtual ~Map(); void Clear(); + virtual Content *Clone() const; + virtual bool GetBegin(std::map ::const_iterator& it) const; virtual bool GetEnd(std::map ::const_iterator& it) const; virtual void Parse(Scanner *pScanner, const ParserState& state); @@ -35,8 +41,7 @@ namespace YAML void ParseBlock(Scanner *pScanner, const ParserState& state); void ParseFlow(Scanner *pScanner, const ParserState& state); - protected: - typedef std::map node_map; + private: node_map m_data; }; } diff --git a/src/node.cpp b/src/node.cpp index 165f822..7a460f3 100644 --- a/src/node.cpp +++ b/src/node.cpp @@ -24,6 +24,13 @@ namespace YAML { } + Node::Node(const Mark& mark, const std::string& anchor, const std::string& tag, const Content *pContent) + : m_mark(mark), m_anchor(anchor), m_tag(tag), m_pContent(0), m_alias(false), m_pIdentity(this), m_referenced(false) + { + if(m_pContent) + m_pContent = pContent->Clone(); + } + Node::~Node() { Clear(); @@ -38,6 +45,14 @@ namespace YAML m_anchor.clear(); m_tag.clear(); } + + std::auto_ptr Node::Clone() const + { + if(m_alias) + throw std::runtime_error("yaml-cpp: Can't clone alias"); // TODO: what to do about aliases? + + return std::auto_ptr (new Node(m_mark, m_anchor, m_tag, m_pContent)); + } void Node::Parse(Scanner *pScanner, const ParserState& state) { diff --git a/src/scalar.cpp b/src/scalar.cpp index e8146fa..a7ccda9 100644 --- a/src/scalar.cpp +++ b/src/scalar.cpp @@ -12,10 +12,19 @@ namespace YAML { } + Scalar::Scalar(const std::string& data): m_data(data) + { + } + Scalar::~Scalar() { } + Content *Scalar::Clone() const + { + return new Scalar(m_data); + } + void Scalar::Parse(Scanner *pScanner, const ParserState& /*state*/) { Token& token = pScanner->peek(); @@ -43,3 +52,4 @@ namespace YAML return 0; } } + diff --git a/src/scalar.h b/src/scalar.h index 59bcb7b..fe9a84b 100644 --- a/src/scalar.h +++ b/src/scalar.h @@ -13,8 +13,11 @@ namespace YAML { public: Scalar(); + Scalar(const std::string& data); virtual ~Scalar(); + virtual Content *Clone() const; + virtual void Parse(Scanner *pScanner, const ParserState& state); virtual void Write(Emitter& out) const; @@ -38,3 +41,4 @@ namespace YAML } #endif // SCALAR_H_62B23520_7C8E_11DE_8A39_0800200C9A66 + diff --git a/src/sequence.cpp b/src/sequence.cpp index 70ca5bb..dde05c6 100644 --- a/src/sequence.cpp +++ b/src/sequence.cpp @@ -13,6 +13,12 @@ namespace YAML } + Sequence::Sequence(const std::vector& data) + { + for(std::size_t i=0;iClone().release()); + } + Sequence::~Sequence() { Clear(); @@ -25,6 +31,11 @@ namespace YAML m_data.clear(); } + Content *Sequence::Clone() const + { + return new Sequence(m_data); + } + bool Sequence::GetBegin(std::vector ::const_iterator& it) const { it = m_data.begin(); diff --git a/src/sequence.h b/src/sequence.h index f158882..fcf13dd 100644 --- a/src/sequence.h +++ b/src/sequence.h @@ -15,9 +15,12 @@ namespace YAML { public: Sequence(); + Sequence(const std::vector& data); virtual ~Sequence(); void Clear(); + virtual Content *Clone() const; + virtual bool GetBegin(std::vector ::const_iterator& it) const; virtual bool GetEnd(std::vector ::const_iterator& it) const; virtual Node *GetNode(std::size_t i) const;