diff --git a/include/yaml-cpp/node/detail/impl.h b/include/yaml-cpp/node/detail/impl.h index 43eaa38..c64f6d8 100644 --- a/include/yaml-cpp/node/detail/impl.h +++ b/include/yaml-cpp/node/detail/impl.h @@ -58,28 +58,28 @@ struct get_idx >::type> { // indexing template -inline node& node_data::get(const Key& key, +inline node* node_data::get(const Key& key, shared_memory_holder pMemory) const { switch (m_type) { case NodeType::Map: break; case NodeType::Undefined: case NodeType::Null: - return pMemory->create_node(); + return NULL; case NodeType::Sequence: if (node* pNode = get_idx::get(m_sequence, key, pMemory)) - return *pNode; - return pMemory->create_node(); + return pNode; + return NULL; case NodeType::Scalar: throw BadSubscript(); } for (node_map::const_iterator it = m_map.begin(); it != m_map.end(); ++it) { if (equals(*it->first, key, pMemory)) - return *it->second; + return it->second; } - return pMemory->create_node(); + return NULL; } template diff --git a/include/yaml-cpp/node/detail/node.h b/include/yaml-cpp/node/detail/node.h index 29605dd..59338f7 100644 --- a/include/yaml-cpp/node/detail/node.h +++ b/include/yaml-cpp/node/detail/node.h @@ -110,7 +110,10 @@ class node : private boost::noncopyable { // indexing template - node& get(const Key& key, shared_memory_holder pMemory) const { + node* get(const Key& key, shared_memory_holder pMemory) const { + // NOTE: this returns a non-const node so that the top-level Node can wrap + // it, and returns a pointer so that it can be NULL (if there is no such + // key). return static_cast(*m_pRef).get(key, pMemory); } template @@ -124,7 +127,10 @@ class node : private boost::noncopyable { return m_pRef->remove(key, pMemory); } - node& get(node& key, shared_memory_holder pMemory) const { + node* get(node& key, shared_memory_holder pMemory) const { + // NOTE: this returns a non-const node so that the top-level Node can wrap + // it, and returns a pointer so that it can be NULL (if there is no such + // key). return static_cast(*m_pRef).get(key, pMemory); } node& get(node& key, shared_memory_holder pMemory) { diff --git a/include/yaml-cpp/node/detail/node_data.h b/include/yaml-cpp/node/detail/node_data.h index b6c12b3..6023aab 100644 --- a/include/yaml-cpp/node/detail/node_data.h +++ b/include/yaml-cpp/node/detail/node_data.h @@ -63,13 +63,13 @@ class YAML_CPP_API node_data : private boost::noncopyable { // indexing template - node& get(const Key& key, shared_memory_holder pMemory) const; + node* get(const Key& key, shared_memory_holder pMemory) const; template node& get(const Key& key, shared_memory_holder pMemory); template bool remove(const Key& key, shared_memory_holder pMemory); - node& get(node& key, shared_memory_holder pMemory) const; + node* get(node& key, shared_memory_holder pMemory) const; node& get(node& key, shared_memory_holder pMemory); bool remove(node& key, shared_memory_holder pMemory); diff --git a/include/yaml-cpp/node/detail/node_ref.h b/include/yaml-cpp/node/detail/node_ref.h index 4530cf8..eb50a25 100644 --- a/include/yaml-cpp/node/detail/node_ref.h +++ b/include/yaml-cpp/node/detail/node_ref.h @@ -57,7 +57,7 @@ class node_ref : private boost::noncopyable { // indexing template - node& get(const Key& key, shared_memory_holder pMemory) const { + node* get(const Key& key, shared_memory_holder pMemory) const { return static_cast(*m_pData).get(key, pMemory); } template @@ -69,7 +69,7 @@ class node_ref : private boost::noncopyable { return m_pData->remove(key, pMemory); } - node& get(node& key, shared_memory_holder pMemory) const { + node* get(node& key, shared_memory_holder pMemory) const { return static_cast(*m_pData).get(key, pMemory); } node& get(node& key, shared_memory_holder pMemory) { diff --git a/include/yaml-cpp/node/impl.h b/include/yaml-cpp/node/impl.h index 3b1400a..092351e 100644 --- a/include/yaml-cpp/node/impl.h +++ b/include/yaml-cpp/node/impl.h @@ -366,9 +366,12 @@ inline const Node Node::operator[](const Key& key) const { if (!m_isValid) throw InvalidNode(); EnsureNodeExists(); - detail::node& value = static_cast(*m_pNode) + detail::node* value = static_cast(*m_pNode) .get(detail::to_value(key), m_pMemory); - return Node(value, m_pMemory); + if (!value) { + return Node(ZombieNode); + } + return Node(*value, m_pMemory); } template @@ -394,9 +397,12 @@ inline const Node Node::operator[](const Node& key) const { EnsureNodeExists(); key.EnsureNodeExists(); m_pMemory->merge(*key.m_pMemory); - detail::node& value = + detail::node* value = static_cast(*m_pNode).get(*key.m_pNode, m_pMemory); - return Node(value, m_pMemory); + if (!value) { + return Node(ZombieNode); + } + return Node(*value, m_pMemory); } inline Node Node::operator[](const Node& key) { diff --git a/include/yaml-cpp/node/node.h b/include/yaml-cpp/node/node.h index 15de6f0..2b85e84 100644 --- a/include/yaml-cpp/node/node.h +++ b/include/yaml-cpp/node/node.h @@ -129,6 +129,7 @@ class YAML_CPP_API Node { bool m_isValid; mutable detail::shared_memory_holder m_pMemory; mutable detail::node* m_pNode; + mutable const detail::node* m_pConstNode; }; YAML_CPP_API bool operator==(const Node& lhs, const Node& rhs); diff --git a/src/node_data.cpp b/src/node_data.cpp index 379c1ef..4c07532 100644 --- a/src/node_data.cpp +++ b/src/node_data.cpp @@ -192,16 +192,17 @@ void node_data::insert(node& key, node& value, shared_memory_holder pMemory) { } // indexing -node& node_data::get(node& key, shared_memory_holder pMemory) const { - if (m_type != NodeType::Map) - return pMemory->create_node(); +node* node_data::get(node& key, shared_memory_holder /* pMemory */) const { + if (m_type != NodeType::Map) { + return NULL; + } for (node_map::const_iterator it = m_map.begin(); it != m_map.end(); ++it) { if (it->first->is(key)) - return *it->second; + return it->second; } - return pMemory->create_node(); + return NULL; } node& node_data::get(node& key, shared_memory_holder pMemory) { diff --git a/util/sandbox.cpp b/util/sandbox.cpp index 4f844ef..3565389 100644 --- a/util/sandbox.cpp +++ b/util/sandbox.cpp @@ -26,10 +26,11 @@ class NullEventHandler : public YAML::EventHandler { }; int main() { - std::stringstream stream("---{header: {id: 1"); - YAML::Parser parser(stream); - // parser.PrintTokens(std::cout); - NullEventHandler handler; - parser.HandleNextDocument(handler); + const YAML::Node node; + + std::string key = "doesnotexist"; + for (;;) { + node[key]; + } return 0; }