emitterstate.h 6.23 KB
Newer Older
1
2
3
#ifndef EMITTERSTATE_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define EMITTERSTATE_H_62B23520_7C8E_11DE_8A39_0800200C9A66

4
#if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
5
6
7
#pragma once
#endif

8

9
#include "ptr_stack.h"
10
#include "setting.h"
11
#include "yaml-cpp/emitterdef.h"
12
#include "yaml-cpp/emittermanip.h"
13
14
15
16
#include <cassert>
#include <vector>
#include <stack>
#include <memory>
Jesse Beder's avatar
Jesse Beder committed
17
#include <stdexcept>
18
19
20

namespace YAML
{
21
22
23
24
	struct FmtScope { enum value { Local, Global }; };
	struct GroupType { enum value { None, Seq, Map }; };
	struct FlowType { enum value { None, Flow, Block }; };

25
26
27
28
29
30
31
32
33
	class EmitterState
	{
	public:
		EmitterState();
		~EmitterState();
		
		// basic state checking
		bool good() const { return m_isGood; }
		const std::string GetLastError() const { return m_lastError; }
Jesse Beder's avatar
Jesse Beder committed
34
		void SetError(const std::string& error) { m_isGood = false; m_lastError = error; }
35
		
Jesse Beder's avatar
Jesse Beder committed
36
		// node handling
Jesse Beder's avatar
Jesse Beder committed
37
38
        void SetAnchor();
        void SetTag();
Jesse Beder's avatar
Jesse Beder committed
39
        void SetNonContent();
40
        void SetLongKey();
41
42
43
        void StartedScalar();
		void StartedGroup(GroupType::value type);
		void EndedGroup(GroupType::value type);
44
45
46
47

        EmitterNodeType::value NextGroupType(GroupType::value type) const;
        EmitterNodeType::value CurGroupNodeType() const;

Jesse Beder's avatar
Jesse Beder committed
48
49
		GroupType::value CurGroupType() const;
        FlowType::value CurGroupFlowType() const;
Jesse Beder's avatar
Jesse Beder committed
50
        int CurGroupIndent() const;
51
        std::size_t CurGroupChildCount() const;
52
        bool CurGroupLongKey() const;
53

Jesse Beder's avatar
Jesse Beder committed
54
        int LastIndent() const;
Jesse Beder's avatar
Jesse Beder committed
55
56
57
		int CurIndent() const { return m_curIndent; }
        bool HasAnchor() const { return m_hasAnchor; }
        bool HasTag() const { return m_hasTag; }
Jesse Beder's avatar
Jesse Beder committed
58
        bool HasBegunNode() const { return m_hasAnchor || m_hasTag || m_hasNonContent; }
Jesse Beder's avatar
Jesse Beder committed
59
        bool HasBegunContent() const { return m_hasAnchor || m_hasTag; }
60
61
62
63

		void ClearModifiedSettings();

		// formatters
64
65
		void SetLocalValue(EMITTER_MANIP value);

66
		bool SetOutputCharset(EMITTER_MANIP value, FmtScope::value scope);
67
68
		EMITTER_MANIP GetOutputCharset() const { return m_charset.get(); }

69
		bool SetStringFormat(EMITTER_MANIP value, FmtScope::value scope);
70
71
		EMITTER_MANIP GetStringFormat() const { return m_strFmt.get(); }
		
72
		bool SetBoolFormat(EMITTER_MANIP value, FmtScope::value scope);
73
74
		EMITTER_MANIP GetBoolFormat() const { return m_boolFmt.get(); }

75
		bool SetBoolLengthFormat(EMITTER_MANIP value, FmtScope::value scope);
76
77
		EMITTER_MANIP GetBoolLengthFormat() const { return m_boolLengthFmt.get(); }

78
		bool SetBoolCaseFormat(EMITTER_MANIP value, FmtScope::value scope);
79
80
		EMITTER_MANIP GetBoolCaseFormat() const { return m_boolCaseFmt.get(); }

81
		bool SetIntFormat(EMITTER_MANIP value, FmtScope::value scope);
82
83
		EMITTER_MANIP GetIntFormat() const { return m_intFmt.get(); }

84
		bool SetIndent(unsigned value, FmtScope::value scope);
85
86
		int GetIndent() const { return m_indent.get(); }
		
87
		bool SetPreCommentIndent(unsigned value, FmtScope::value scope);
88
		int GetPreCommentIndent() const { return m_preCommentIndent.get(); }
89
		bool SetPostCommentIndent(unsigned value, FmtScope::value scope);
90
91
		int GetPostCommentIndent() const { return m_postCommentIndent.get(); }
		
92
93
		bool SetFlowType(GroupType::value groupType, EMITTER_MANIP value, FmtScope::value scope);
		EMITTER_MANIP GetFlowType(GroupType::value groupType) const;
94
		
95
		bool SetMapKeyFormat(EMITTER_MANIP value, FmtScope::value scope);
96
		EMITTER_MANIP GetMapKeyFormat() const { return m_mapKeyFmt.get(); }
97
        
98
        bool SetFloatPrecision(int value, FmtScope::value scope);
99
        unsigned GetFloatPrecision() const { return m_floatPrecision.get(); }
100
        bool SetDoublePrecision(int value, FmtScope::value scope);
101
        unsigned GetDoublePrecision() const { return m_doublePrecision.get(); }
102
103
104
		
	private:
		template <typename T>
105
		void _Set(Setting<T>& fmt, T value, FmtScope::value scope);
Jesse Beder's avatar
Jesse Beder committed
106
        
107
        void StartedNode();
108
109
110
111
112
113
114
		
	private:
		// basic state ok?
		bool m_isGood;
		std::string m_lastError;
		
		// other state
115
116
117
118
119
120
121
122
123
124
125
		Setting<EMITTER_MANIP> m_charset;
		Setting<EMITTER_MANIP> m_strFmt;
		Setting<EMITTER_MANIP> m_boolFmt;
		Setting<EMITTER_MANIP> m_boolLengthFmt;
		Setting<EMITTER_MANIP> m_boolCaseFmt;
		Setting<EMITTER_MANIP> m_intFmt;
		Setting<unsigned> m_indent;
		Setting<unsigned> m_preCommentIndent, m_postCommentIndent;
		Setting<EMITTER_MANIP> m_seqFmt;
		Setting<EMITTER_MANIP> m_mapFmt;
		Setting<EMITTER_MANIP> m_mapKeyFmt;
126
127
        Setting<int> m_floatPrecision;
        Setting<int> m_doublePrecision;
128
129
130
131
132
		
		SettingChanges m_modifiedSettings;
		SettingChanges m_globalModifiedSettings;
		
		struct Group {
133
			explicit Group(GroupType::value type_): type(type_), indent(0), childCount(0), longKey(false) {}
134
			
135
            GroupType::value type;
136
            FlowType::value flowType;
137
			int indent;
Jesse Beder's avatar
Jesse Beder committed
138
            std::size_t childCount;
139
            bool longKey;
140
141
			
			SettingChanges modifiedSettings;
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
            
            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;
            }
160
		};
161
162

		ptr_stack<Group> m_groups;
163
		unsigned m_curIndent;
Jesse Beder's avatar
Jesse Beder committed
164
165
        bool m_hasAnchor;
        bool m_hasTag;
Jesse Beder's avatar
Jesse Beder committed
166
        bool m_hasNonContent;
167
        std::size_t m_docCount;
168
169
170
	};

	template <typename T>
171
	void EmitterState::_Set(Setting<T>& fmt, T value, FmtScope::value scope) {
172
		switch(scope) {
173
			case FmtScope::Local:
174
175
				m_modifiedSettings.push(fmt.set(value));
				break;
176
			case FmtScope::Global:
177
178
179
180
181
182
183
184
185
				fmt.set(value);
				m_globalModifiedSettings.push(fmt.set(value));  // this pushes an identity set, so when we restore,
				                                                // it restores to the value here, and not the previous one
				break;
			default:
				assert(false);
		}
	}
}
186
187

#endif // EMITTERSTATE_H_62B23520_7C8E_11DE_8A39_0800200C9A66