mirror of
https://github.com/jbeder/yaml-cpp.git
synced 2025-09-10 13:01:18 +00:00
Implemented (untested) the value builder
This commit is contained in:
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);
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user