Implemented (untested) the value builder

This commit is contained in:
Jesse Beder
2011-09-09 23:28:21 -05:00
parent a7bdf08c7e
commit 6e03bebeb0
7 changed files with 193 additions and 1 deletions

View File

@@ -111,6 +111,14 @@ namespace YAML
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
{

120
src/value/valuebuilder.cpp Normal file
View 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
View 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