mirror of https://github.com/axmolengine/axmol.git
125 lines
3.0 KiB
C++
125 lines
3.0 KiB
C++
|
#include <cassert>
|
||
|
#include <sstream>
|
||
|
|
||
|
#include "yaml-cpp/emitfromevents.h"
|
||
|
#include "yaml-cpp/emitter.h"
|
||
|
#include "yaml-cpp/emittermanip.h"
|
||
|
#include "yaml-cpp/null.h"
|
||
|
|
||
|
namespace YAML {
|
||
|
struct Mark;
|
||
|
} // namespace YAML
|
||
|
|
||
|
namespace {
|
||
|
std::string ToString(YAML::anchor_t anchor) {
|
||
|
std::stringstream stream;
|
||
|
stream << anchor;
|
||
|
return stream.str();
|
||
|
}
|
||
|
} // namespace
|
||
|
|
||
|
namespace YAML {
|
||
|
EmitFromEvents::EmitFromEvents(Emitter& emitter)
|
||
|
: m_emitter(emitter), m_stateStack{} {}
|
||
|
|
||
|
void EmitFromEvents::OnDocumentStart(const Mark&) {}
|
||
|
|
||
|
void EmitFromEvents::OnDocumentEnd() {}
|
||
|
|
||
|
void EmitFromEvents::OnNull(const Mark&, anchor_t anchor) {
|
||
|
BeginNode();
|
||
|
EmitProps("", anchor);
|
||
|
m_emitter << Null;
|
||
|
}
|
||
|
|
||
|
void EmitFromEvents::OnAlias(const Mark&, anchor_t anchor) {
|
||
|
BeginNode();
|
||
|
m_emitter << Alias(ToString(anchor));
|
||
|
}
|
||
|
|
||
|
void EmitFromEvents::OnScalar(const Mark&, const std::string& tag,
|
||
|
anchor_t anchor, const std::string& value) {
|
||
|
BeginNode();
|
||
|
EmitProps(tag, anchor);
|
||
|
m_emitter << value;
|
||
|
}
|
||
|
|
||
|
void EmitFromEvents::OnSequenceStart(const Mark&, const std::string& tag,
|
||
|
anchor_t anchor,
|
||
|
EmitterStyle::value style) {
|
||
|
BeginNode();
|
||
|
EmitProps(tag, anchor);
|
||
|
switch (style) {
|
||
|
case EmitterStyle::Block:
|
||
|
m_emitter << Block;
|
||
|
break;
|
||
|
case EmitterStyle::Flow:
|
||
|
m_emitter << Flow;
|
||
|
break;
|
||
|
default:
|
||
|
break;
|
||
|
}
|
||
|
// Restore the global settings to eliminate the override from node style
|
||
|
m_emitter.RestoreGlobalModifiedSettings();
|
||
|
m_emitter << BeginSeq;
|
||
|
m_stateStack.push(State::WaitingForSequenceEntry);
|
||
|
}
|
||
|
|
||
|
void EmitFromEvents::OnSequenceEnd() {
|
||
|
m_emitter << EndSeq;
|
||
|
assert(m_stateStack.top() == State::WaitingForSequenceEntry);
|
||
|
m_stateStack.pop();
|
||
|
}
|
||
|
|
||
|
void EmitFromEvents::OnMapStart(const Mark&, const std::string& tag,
|
||
|
anchor_t anchor, EmitterStyle::value style) {
|
||
|
BeginNode();
|
||
|
EmitProps(tag, anchor);
|
||
|
switch (style) {
|
||
|
case EmitterStyle::Block:
|
||
|
m_emitter << Block;
|
||
|
break;
|
||
|
case EmitterStyle::Flow:
|
||
|
m_emitter << Flow;
|
||
|
break;
|
||
|
default:
|
||
|
break;
|
||
|
}
|
||
|
// Restore the global settings to eliminate the override from node style
|
||
|
m_emitter.RestoreGlobalModifiedSettings();
|
||
|
m_emitter << BeginMap;
|
||
|
m_stateStack.push(State::WaitingForKey);
|
||
|
}
|
||
|
|
||
|
void EmitFromEvents::OnMapEnd() {
|
||
|
m_emitter << EndMap;
|
||
|
assert(m_stateStack.top() == State::WaitingForKey);
|
||
|
m_stateStack.pop();
|
||
|
}
|
||
|
|
||
|
void EmitFromEvents::BeginNode() {
|
||
|
if (m_stateStack.empty())
|
||
|
return;
|
||
|
|
||
|
switch (m_stateStack.top()) {
|
||
|
case State::WaitingForKey:
|
||
|
m_emitter << Key;
|
||
|
m_stateStack.top() = State::WaitingForValue;
|
||
|
break;
|
||
|
case State::WaitingForValue:
|
||
|
m_emitter << Value;
|
||
|
m_stateStack.top() = State::WaitingForKey;
|
||
|
break;
|
||
|
default:
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void EmitFromEvents::EmitProps(const std::string& tag, anchor_t anchor) {
|
||
|
if (!tag.empty() && tag != "?" && tag != "!")
|
||
|
m_emitter << VerbatimTag(tag);
|
||
|
if (anchor)
|
||
|
m_emitter << Anchor(ToString(anchor));
|
||
|
}
|
||
|
} // namespace YAML
|