| #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 != "!"){ | |
| if (tag[0] == '!') { | |
| m_emitter << LocalTag(std::string(tag.begin()+1, tag.end())); | |
| } else { | |
| m_emitter << VerbatimTag(tag); | |
| } | |
| } | |
| if (anchor) | |
| m_emitter << Anchor(ToString(anchor)); | |
| } | |
| } // namespace YAML |