mirror of
https://github.com/jbeder/yaml-cpp.git
synced 2025-09-09 12:41:17 +00:00
Implemented (untested) the value builder
This commit is contained in:
@@ -65,7 +65,10 @@ file(GLOB public_headers
|
|||||||
"include/yaml-cpp/value/[a-zA-Z]*.h"
|
"include/yaml-cpp/value/[a-zA-Z]*.h"
|
||||||
"include/yaml-cpp/value/detail/[a-zA-Z]*.h"
|
"include/yaml-cpp/value/detail/[a-zA-Z]*.h"
|
||||||
)
|
)
|
||||||
file(GLOB private_headers "src/[a-zA-Z]*.h")
|
file(GLOB private_headers
|
||||||
|
"src/[a-zA-Z]*.h"
|
||||||
|
"src/value/[a-zA-Z]*.h"
|
||||||
|
)
|
||||||
|
|
||||||
if(YAML_CPP_BUILD_CONTRIB)
|
if(YAML_CPP_BUILD_CONTRIB)
|
||||||
file(GLOB contrib_sources "src/contrib/[a-zA-Z]*.cpp")
|
file(GLOB contrib_sources "src/contrib/[a-zA-Z]*.cpp")
|
||||||
|
@@ -44,6 +44,9 @@ namespace YAML
|
|||||||
|
|
||||||
// sequence
|
// sequence
|
||||||
void append(node& node, shared_memory_holder pMemory) { m_pRef->append(node, pMemory); }
|
void append(node& node, shared_memory_holder pMemory) { m_pRef->append(node, pMemory); }
|
||||||
|
void insert(node& key, node& value, shared_memory_holder pMemory) {
|
||||||
|
m_pRef->insert(key, value, pMemory);
|
||||||
|
}
|
||||||
|
|
||||||
// indexing
|
// indexing
|
||||||
template<typename Key> node& get(const Key& key, shared_memory_holder pMemory) const { return static_cast<const node_ref&>(*m_pRef).get(key, pMemory); }
|
template<typename Key> node& get(const Key& key, shared_memory_holder pMemory) const { return static_cast<const node_ref&>(*m_pRef).get(key, pMemory); }
|
||||||
|
@@ -42,6 +42,7 @@ namespace YAML
|
|||||||
|
|
||||||
// sequence
|
// sequence
|
||||||
void append(node& node, shared_memory_holder pMemory);
|
void append(node& node, shared_memory_holder pMemory);
|
||||||
|
void insert(node& key, node& value, shared_memory_holder pMemory);
|
||||||
|
|
||||||
// indexing
|
// indexing
|
||||||
template<typename Key> node& get(const Key& key, shared_memory_holder pMemory) const;
|
template<typename Key> node& get(const Key& key, shared_memory_holder pMemory) const;
|
||||||
|
@@ -41,6 +41,9 @@ namespace YAML
|
|||||||
|
|
||||||
// sequence
|
// sequence
|
||||||
void append(node& node, shared_memory_holder pMemory) { ensure_data_exists(); m_pData->append(node, pMemory); }
|
void append(node& node, shared_memory_holder pMemory) { ensure_data_exists(); m_pData->append(node, pMemory); }
|
||||||
|
void insert(node& key, node& value, shared_memory_holder pMemory) {
|
||||||
|
ensure_data_exists(); m_pData->insert(key, value, pMemory);
|
||||||
|
}
|
||||||
|
|
||||||
// indexing
|
// indexing
|
||||||
template<typename Key> node& get(const Key& key, shared_memory_holder pMemory) const { return m_pData ? static_cast<const node_data&>(*m_pData).get(key, pMemory) : pMemory->create_node(); }
|
template<typename Key> node& get(const Key& key, shared_memory_holder pMemory) const { return m_pData ? static_cast<const node_data&>(*m_pData).get(key, pMemory) : pMemory->create_node(); }
|
||||||
|
@@ -111,6 +111,14 @@ namespace YAML
|
|||||||
m_sequence.push_back(&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
|
// indexing
|
||||||
node& node_data::get(node& key, shared_memory_holder pMemory) const
|
node& node_data::get(node& key, shared_memory_holder pMemory) const
|
||||||
{
|
{
|
||||||
|
120
src/value/valuebuilder.cpp
Normal file
120
src/value/valuebuilder.cpp
Normal file
@@ -0,0 +1,120 @@
|
|||||||
|
#include "valuebuilder.h"
|
||||||
|
#include "yaml-cpp/mark.h"
|
||||||
|
#include "yaml-cpp/value.h"
|
||||||
|
#include <cassert>
|
||||||
|
|
||||||
|
namespace YAML
|
||||||
|
{
|
||||||
|
ValueBuilder::ValueBuilder(): m_pMemory(new detail::memory_holder), m_pRoot(0), m_mapDepth(0)
|
||||||
|
{
|
||||||
|
m_anchors.push_back(0); // since the anchors start at 1
|
||||||
|
}
|
||||||
|
|
||||||
|
ValueBuilder::~ValueBuilder()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void ValueBuilder::OnDocumentStart(const Mark&)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void ValueBuilder::OnDocumentEnd()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void ValueBuilder::OnNull(const Mark& mark, anchor_t anchor)
|
||||||
|
{
|
||||||
|
detail::node& node = Push(anchor);
|
||||||
|
node.set_null();
|
||||||
|
Pop();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ValueBuilder::OnAlias(const Mark& /*mark*/, anchor_t anchor)
|
||||||
|
{
|
||||||
|
detail::node& node = *m_anchors[anchor];
|
||||||
|
m_stack.push_back(&node);
|
||||||
|
Pop();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ValueBuilder::OnScalar(const Mark& mark, const std::string& tag, anchor_t anchor, const std::string& value)
|
||||||
|
{
|
||||||
|
detail::node& node = Push(anchor);
|
||||||
|
node.set_scalar(value);
|
||||||
|
Pop();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ValueBuilder::OnSequenceStart(const Mark& mark, const std::string& tag, anchor_t anchor)
|
||||||
|
{
|
||||||
|
detail::node& node = Push(anchor);
|
||||||
|
node.set_type(ValueType::Sequence);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ValueBuilder::OnSequenceEnd()
|
||||||
|
{
|
||||||
|
Pop();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ValueBuilder::OnMapStart(const Mark& mark, const std::string& tag, anchor_t anchor)
|
||||||
|
{
|
||||||
|
detail::node& node = Push(anchor);
|
||||||
|
node.set_type(ValueType::Map);
|
||||||
|
m_mapDepth++;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ValueBuilder::OnMapEnd()
|
||||||
|
{
|
||||||
|
assert(m_mapDepth > 0);
|
||||||
|
m_mapDepth--;
|
||||||
|
Pop();
|
||||||
|
}
|
||||||
|
|
||||||
|
detail::node& ValueBuilder::Push(anchor_t anchor)
|
||||||
|
{
|
||||||
|
detail::node& top = *m_stack.back();
|
||||||
|
|
||||||
|
detail::node& node = m_pMemory->create_node();
|
||||||
|
m_stack.push_back(&node);
|
||||||
|
RegisterAnchor(anchor, node);
|
||||||
|
|
||||||
|
if(top.type() == ValueType::Map && m_keys.size() < m_mapDepth)
|
||||||
|
m_keys.push_back(&node);
|
||||||
|
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ValueBuilder::Pop()
|
||||||
|
{
|
||||||
|
assert(!m_stack.empty());
|
||||||
|
if(m_stack.size() == 1) {
|
||||||
|
m_pRoot = m_stack[0];
|
||||||
|
m_stack.pop_back();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
detail::node& node = *m_stack.back();
|
||||||
|
m_stack.pop_back();
|
||||||
|
|
||||||
|
detail::node& collection = *m_stack.back();
|
||||||
|
|
||||||
|
if(collection.type() == ValueType::Sequence) {
|
||||||
|
collection.append(node, m_pMemory);
|
||||||
|
} else if(collection.type() == ValueType::Map) {
|
||||||
|
detail::node& key = *m_keys.back();
|
||||||
|
if(&key != &node) {
|
||||||
|
m_keys.pop_back();
|
||||||
|
collection.insert(key, node, m_pMemory);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
assert(false);
|
||||||
|
m_stack.clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ValueBuilder::RegisterAnchor(anchor_t anchor, detail::node& node)
|
||||||
|
{
|
||||||
|
if(anchor) {
|
||||||
|
assert(anchor == m_anchors.size());
|
||||||
|
m_anchors.push_back(&node);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
54
src/value/valuebuilder.h
Normal file
54
src/value/valuebuilder.h
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
#ifndef VALUE_VALUEBUILDER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||||
|
#define VALUE_VALUEBUILDER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||||
|
|
||||||
|
#if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
|
||||||
|
#pragma once
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "yaml-cpp/eventhandler.h"
|
||||||
|
#include "yaml-cpp/value/ptr.h"
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
namespace YAML
|
||||||
|
{
|
||||||
|
class Value;
|
||||||
|
|
||||||
|
class ValueBuilder: public EventHandler
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ValueBuilder();
|
||||||
|
virtual ~ValueBuilder();
|
||||||
|
|
||||||
|
virtual void OnDocumentStart(const Mark& mark);
|
||||||
|
virtual void OnDocumentEnd();
|
||||||
|
|
||||||
|
virtual void OnNull(const Mark& mark, anchor_t anchor);
|
||||||
|
virtual void OnAlias(const Mark& mark, anchor_t anchor);
|
||||||
|
virtual void OnScalar(const Mark& mark, const std::string& tag, anchor_t anchor, const std::string& value);
|
||||||
|
|
||||||
|
virtual void OnSequenceStart(const Mark& mark, const std::string& tag, anchor_t anchor);
|
||||||
|
virtual void OnSequenceEnd();
|
||||||
|
|
||||||
|
virtual void OnMapStart(const Mark& mark, const std::string& tag, anchor_t anchor);
|
||||||
|
virtual void OnMapEnd();
|
||||||
|
|
||||||
|
private:
|
||||||
|
detail::node& Push(anchor_t anchor);
|
||||||
|
void Pop();
|
||||||
|
void RegisterAnchor(anchor_t anchor, detail::node& node);
|
||||||
|
|
||||||
|
private:
|
||||||
|
detail::shared_memory_holder m_pMemory;
|
||||||
|
detail::node *m_pRoot;
|
||||||
|
|
||||||
|
typedef std::vector<detail::node *> Nodes;
|
||||||
|
Nodes m_stack;
|
||||||
|
Nodes m_anchors;
|
||||||
|
|
||||||
|
Nodes m_keys;
|
||||||
|
std::size_t m_mapDepth;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // VALUE_VALUEBUILDER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||||
|
|
Reference in New Issue
Block a user