1#include "yaml-cpp/emitfromevents.h"
2#include "yaml-cpp/emitter.h"
3#include "yaml-cpp/null.h"
4#include <cassert>
5#include <sstream>
6
7namespace {
8	std::string ToString(YAML::anchor_t anchor) {
9		std::stringstream stream;
10		stream << anchor;
11		return stream.str();
12	}
13}
14
15namespace YAML
16{
17	EmitFromEvents::EmitFromEvents(Emitter& emitter): m_emitter(emitter)
18	{
19	}
20
21	void EmitFromEvents::OnDocumentStart(const Mark&)
22	{
23	}
24
25	void EmitFromEvents::OnDocumentEnd()
26	{
27	}
28
29	void EmitFromEvents::OnNull(const Mark&, anchor_t anchor)
30	{
31		BeginNode();
32		EmitProps("", anchor);
33		m_emitter << Null;
34	}
35
36	void EmitFromEvents::OnAlias(const Mark&, anchor_t anchor)
37	{
38		BeginNode();
39		m_emitter << Alias(ToString(anchor));
40	}
41
42	void EmitFromEvents::OnScalar(const Mark&, const std::string& tag, anchor_t anchor, const std::string& value)
43	{
44		BeginNode();
45		EmitProps(tag, anchor);
46		m_emitter << value;
47	}
48
49	void EmitFromEvents::OnSequenceStart(const Mark&, const std::string& tag, anchor_t anchor)
50	{
51		BeginNode();
52		EmitProps(tag, anchor);
53		m_emitter << BeginSeq;
54		m_stateStack.push(State::WaitingForSequenceEntry);
55	}
56
57	void EmitFromEvents::OnSequenceEnd()
58	{
59		m_emitter << EndSeq;
60		assert(m_stateStack.top() == State::WaitingForSequenceEntry);
61		m_stateStack.pop();
62	}
63
64	void EmitFromEvents::OnMapStart(const Mark&, const std::string& tag, anchor_t anchor)
65	{
66		BeginNode();
67		EmitProps(tag, anchor);
68		m_emitter << BeginMap;
69		m_stateStack.push(State::WaitingForKey);
70	}
71
72	void EmitFromEvents::OnMapEnd()
73	{
74		m_emitter << EndMap;
75		assert(m_stateStack.top() == State::WaitingForKey);
76		m_stateStack.pop();
77	}
78
79	void EmitFromEvents::BeginNode()
80	{
81		if(m_stateStack.empty())
82			return;
83
84		switch(m_stateStack.top()) {
85			case State::WaitingForKey:
86				m_emitter << Key;
87				m_stateStack.top() = State::WaitingForValue;
88				break;
89			case State::WaitingForValue:
90				m_emitter << Value;
91				m_stateStack.top() = State::WaitingForKey;
92				break;
93			default:
94				break;
95		}
96	}
97
98	void EmitFromEvents::EmitProps(const std::string& tag, anchor_t anchor)
99	{
100		if(!tag.empty() && tag != "?")
101			m_emitter << VerbatimTag(tag);
102		if(anchor)
103			m_emitter << Anchor(ToString(anchor));
104	}
105}
106