#include "yaml-cpp/value/detail/node_data.h" #include "yaml-cpp/value/detail/memory.h" #include "yaml-cpp/value/detail/node.h" #include #include namespace YAML { namespace detail { std::string node_data::empty_scalar; node_data::node_data(): m_isDefined(false), m_type(ValueType::Null) { } void node_data::set_type(ValueType::value type) { if(type == ValueType::Undefined) { m_type = type; m_isDefined = false; return; } m_isDefined = true; if(type == m_type) return; m_type = type; switch(m_type) { case ValueType::Null: break; case ValueType::Scalar: m_scalar.clear(); break; case ValueType::Sequence: m_sequence.clear(); break; case ValueType::Map: m_map.clear(); break; case ValueType::Undefined: assert(false); break; } } void node_data::set_null() { m_isDefined = true; m_type = ValueType::Null; } void node_data::set_scalar(const std::string& scalar) { m_isDefined = true; m_type = ValueType::Scalar; m_scalar = scalar; } // size/iterator std::size_t node_data::size() const { return 0; } const_iterator node_data::begin(shared_memory_holder pMemory) const { switch(m_type) { case ValueType::Sequence: return const_iterator(pMemory, m_sequence.begin()); case ValueType::Map: return const_iterator(pMemory, m_map.begin()); default: return const_iterator(); } } iterator node_data::begin(shared_memory_holder pMemory) { switch(m_type) { case ValueType::Sequence: return iterator(pMemory, m_sequence.begin()); case ValueType::Map: return iterator(pMemory, m_map.begin()); default: return iterator(); } } const_iterator node_data::end(shared_memory_holder pMemory) const { switch(m_type) { case ValueType::Sequence: return const_iterator(pMemory, m_sequence.end()); case ValueType::Map: return const_iterator(pMemory, m_map.end()); default: return const_iterator(); } } iterator node_data::end(shared_memory_holder pMemory) { switch(m_type) { case ValueType::Sequence: return iterator(pMemory, m_sequence.end()); case ValueType::Map: return iterator(pMemory, m_map.end()); default: return iterator(); } } // sequence void node_data::append(node& node, shared_memory_holder /* pMemory */) { if(m_type != ValueType::Sequence) throw std::runtime_error("Can't append to a non-sequence node"); m_sequence.push_back(&node); } void node_data::insert(node& key, node& value, shared_memory_holder /* pMemory */) { if(m_type != ValueType::Map) throw std::runtime_error("Can't insert into a non-map node"); m_map.push_back(kv_pair(&key, &value)); } // indexing node& node_data::get(node& key, shared_memory_holder pMemory) const { if(m_type != ValueType::Map) return pMemory->create_node(); for(node_map::const_iterator it=m_map.begin();it!=m_map.end();++it) { if(it->first->is(key)) return *it->second; } return pMemory->create_node(); } node& node_data::get(node& key, shared_memory_holder pMemory) { switch(m_type) { case ValueType::Undefined: case ValueType::Null: case ValueType::Scalar: m_type = ValueType::Map; m_map.clear(); break; case ValueType::Sequence: convert_sequence_to_map(pMemory); break; case ValueType::Map: break; } for(node_map::const_iterator it=m_map.begin();it!=m_map.end();++it) { if(it->first->is(key)) return *it->second; } node& value = pMemory->create_node(); m_map.push_back(kv_pair(&key, &value)); return value; } bool node_data::remove(node& key, shared_memory_holder /* pMemory */) { if(m_type != ValueType::Map) return false; for(node_map::iterator it=m_map.begin();it!=m_map.end();++it) { if(it->first->is(key)) { m_map.erase(it); return true; } } return false; } void node_data::convert_sequence_to_map(shared_memory_holder pMemory) { assert(m_type == ValueType::Sequence); m_map.clear(); for(std::size_t i=0;icreate_node(); key.set_scalar(stream.str()); m_map.push_back(kv_pair(&key, m_sequence[i])); } m_sequence.clear(); m_type = ValueType::Map; } } }