Structured emitter node handling better

This commit is contained in:
Jesse Beder
2012-05-21 21:57:25 -05:00
parent 23fb2dc811
commit 35d827f187
6 changed files with 120 additions and 55 deletions

View File

@@ -210,7 +210,7 @@ namespace YAML
if(!good())
return;
PrepareNode();
PrepareNode(m_pState->NextGroupType(GroupType::Seq));
m_pState->BeginGroup(GroupType::Seq);
}
@@ -230,7 +230,7 @@ namespace YAML
if(!good())
return;
PrepareNode();
PrepareNode(m_pState->NextGroupType(GroupType::Map));
m_pState->BeginGroup(GroupType::Map);
}
@@ -258,40 +258,31 @@ namespace YAML
// Put the stream in a state so we can simply write the next node
// E.g., if we're in a sequence, write the "- "
void Emitter::PrepareNode()
void Emitter::PrepareNode(EmitterNodeType::value child)
{
switch(m_pState->CurGroupType()) {
case GroupType::None:
PrepareTopNode();
switch(m_pState->CurGroupNodeType()) {
case EmitterNodeType::None:
PrepareTopNode(child);
break;
case GroupType::Seq:
switch(m_pState->CurGroupFlowType()) {
case FlowType::Flow:
FlowSeqPrepareNode();
break;
case FlowType::Block:
BlockSeqPrepareNode();
break;
case FlowType::None:
assert(false);
}
case EmitterNodeType::FlowSeq:
FlowSeqPrepareNode(child);
break;
case GroupType::Map:
switch(m_pState->CurGroupFlowType()) {
case FlowType::Flow:
FlowMapPrepareNode();
break;
case FlowType::Block:
BlockMapPrepareNode();
break;
case FlowType::None:
assert(false);
}
case EmitterNodeType::BlockSeq:
BlockSeqPrepareNode(child);
break;
case EmitterNodeType::FlowMap:
FlowMapPrepareNode(child);
break;
case EmitterNodeType::BlockMap:
BlockMapPrepareNode(child);
break;
case EmitterNodeType::Scalar:
assert(false);
break;
}
}
void Emitter::PrepareTopNode()
void Emitter::PrepareTopNode(EmitterNodeType::value child)
{
const bool hasAnchor = m_pState->HasAnchor();
const bool hasTag = m_pState->HasTag();
@@ -306,11 +297,11 @@ namespace YAML
m_stream << " ";
}
void Emitter::FlowSeqPrepareNode()
void Emitter::FlowSeqPrepareNode(EmitterNodeType::value child)
{
}
void Emitter::BlockSeqPrepareNode()
void Emitter::BlockSeqPrepareNode(EmitterNodeType::value child)
{
const unsigned curIndent = m_pState->CurIndent();
if(!m_pState->HasTag() && !m_pState->HasAnchor()) {
@@ -319,16 +310,26 @@ namespace YAML
}
m_stream << IndentTo(curIndent);
m_stream << "-";
m_stream << IndentTo(curIndent + m_pState->CurGroupIndent());
}
}
void Emitter::FlowMapPrepareNode()
void Emitter::FlowMapPrepareNode(EmitterNodeType::value child)
{
}
void Emitter::BlockMapPrepareNode()
void Emitter::BlockMapPrepareNode(EmitterNodeType::value child)
{
if(!m_pState->HasTag() && !m_pState->HasAnchor()) {
const std::size_t childCount = m_pState->CurGroupChildCount();
if(childCount % 2 == 0) {
// key
if(childCount > 0) {
m_stream << "\n";
}
} else {
// value
}
}
}
// *******************************************************************************************
@@ -339,7 +340,7 @@ namespace YAML
if(!good())
return *this;
PrepareNode();
PrepareNode(EmitterNodeType::Scalar);
const bool escapeNonAscii = m_pState->GetOutputCharset() == EscapeNonAscii;
const StringFormat::value strFormat = Utils::ComputeStringFormat(str, m_pState->GetStringFormat(), m_pState->CurGroupFlowType(), escapeNonAscii);

View File

@@ -52,6 +52,25 @@ namespace YAML
m_hasTag = false;
}
EmitterNodeType::value EmitterState::NextGroupType(GroupType::value type) const
{
if(type == GroupType::Seq) {
if(GetFlowType(type) == Block)
return EmitterNodeType::BlockSeq;
else
return EmitterNodeType::FlowSeq;
} else {
if(GetFlowType(type) == Block)
return EmitterNodeType::BlockMap;
else
return EmitterNodeType::FlowMap;
}
// can't happen
assert(false);
return EmitterNodeType::None;
}
void EmitterState::BeginScalar()
{
BeginNode();
@@ -70,7 +89,10 @@ namespace YAML
pGroup->modifiedSettings = m_modifiedSettings;
// set up group
pGroup->flow = GetFlowType(type);
if(GetFlowType(type) == Block)
pGroup->flowType = FlowType::Block;
else
pGroup->flowType = FlowType::Flow;
pGroup->indent = GetIndent();
m_groups.push(pGroup);
@@ -97,21 +119,23 @@ namespace YAML
// by a local setting we just popped, so we need to restore them
m_globalModifiedSettings.restore();
}
GroupType::value EmitterState::CurGroupType() const
EmitterNodeType::value EmitterState::CurGroupNodeType() const
{
if(m_groups.empty())
return EmitterNodeType::None;
return m_groups.top().NodeType();
}
GroupType::value EmitterState::CurGroupType() const
{
if(m_groups.empty())
return GroupType::None;
return m_groups.top().type;
return m_groups.empty() ? GroupType::None : m_groups.top().type;
}
FlowType::value EmitterState::CurGroupFlowType() const
{
if(m_groups.empty())
return FlowType::None;
return (m_groups.top().flow == Flow ? FlowType::Flow : FlowType::Block);
return m_groups.empty() ? FlowType::None : m_groups.top().flowType;
}
int EmitterState::CurGroupIndent() const

View File

@@ -8,6 +8,7 @@
#include "ptr_stack.h"
#include "setting.h"
#include "yaml-cpp/emitterdef.h"
#include "yaml-cpp/emittermanip.h"
#include <cassert>
#include <vector>
@@ -36,11 +37,15 @@ namespace YAML
void BeginScalar();
void BeginGroup(GroupType::value type);
void EndGroup(GroupType::value type);
EmitterNodeType::value NextGroupType(GroupType::value type) const;
EmitterNodeType::value CurGroupNodeType() const;
GroupType::value CurGroupType() const;
FlowType::value CurGroupFlowType() const;
int CurGroupIndent() const;
std::size_t CurGroupChildCount() const;
int CurIndent() const { return m_curIndent; }
bool HasAnchor() const { return m_hasAnchor; }
bool HasTag() const { return m_hasTag; }
@@ -120,11 +125,29 @@ namespace YAML
explicit Group(GroupType::value type_): type(type_), indent(0), childCount(0) {}
GroupType::value type;
EMITTER_MANIP flow;
FlowType::value flowType;
int indent;
std::size_t childCount;
SettingChanges modifiedSettings;
EmitterNodeType::value NodeType() const {
if(type == GroupType::Seq) {
if(flowType == FlowType::Flow)
return EmitterNodeType::FlowSeq;
else
return EmitterNodeType::BlockSeq;
} else {
if(flowType == FlowType::Flow)
return EmitterNodeType::FlowMap;
else
return EmitterNodeType::BlockMap;
}
// can't get here
assert(false);
return EmitterNodeType::None;
}
};
ptr_stack<Group> m_groups;

View File

@@ -38,7 +38,10 @@ public:
}
T& top() { return *m_data.back(); }
const T& top() const { return *m_data.back(); }
T& top(std::ptrdiff_t diff) { return **(m_data.end() - 1 + diff); }
const T& top(std::ptrdiff_t diff) const { return **(m_data.end() - 1 + diff); }
private:
std::vector<T*> m_data;
};