emitterstate.cpp 8.99 KB
Newer Older
1
#include "emitterstate.h"
2
#include "yaml-cpp/exceptions.h"
3
#include <limits>
4
5
6

namespace YAML
{
7
	EmitterState::EmitterState(): m_isGood(true), m_curIndent(0), m_hasAnchor(false), m_hasTag(false), m_hasNonContent(false), m_docCount(0)
8
9
	{
		// set default global manipulators
10
		m_charset.set(EmitNonAscii);
11
12
13
14
15
16
17
18
19
20
21
		m_strFmt.set(Auto);
		m_boolFmt.set(TrueFalseBool);
		m_boolLengthFmt.set(LongBool);
		m_boolCaseFmt.set(LowerCase);
		m_intFmt.set(Dec);
		m_indent.set(2);
		m_preCommentIndent.set(2);
		m_postCommentIndent.set(1);
		m_seqFmt.set(Block);
		m_mapFmt.set(Block);
		m_mapKeyFmt.set(Auto);
22
23
        m_floatPrecision.set(6);
        m_doublePrecision.set(15);
24
25
26
27
28
29
30
31
32
33
34
	}
	
	EmitterState::~EmitterState()
	{
	}

	// SetLocalValue
	// . We blindly tries to set all possible formatters to this value
	// . Only the ones that make sense will be accepted
	void EmitterState::SetLocalValue(EMITTER_MANIP value)
	{
35
36
37
38
39
40
41
42
43
		SetOutputCharset(value, FmtScope::Local);
		SetStringFormat(value, FmtScope::Local);
		SetBoolFormat(value, FmtScope::Local);
		SetBoolCaseFormat(value, FmtScope::Local);
		SetBoolLengthFormat(value, FmtScope::Local);
		SetIntFormat(value, FmtScope::Local);
		SetFlowType(GroupType::Seq, value, FmtScope::Local);
		SetFlowType(GroupType::Map, value, FmtScope::Local);
		SetMapKeyFormat(value, FmtScope::Local);
44
45
	}
	
Jesse Beder's avatar
Jesse Beder committed
46
47
48
49
50
51
52
53
54
55
    void EmitterState::SetAnchor()
    {
        m_hasAnchor = true;
    }
        
    void EmitterState::SetTag()
    {
        m_hasTag = true;
    }

Jesse Beder's avatar
Jesse Beder committed
56
57
58
59
60
    void EmitterState::SetNonContent()
    {
        m_hasNonContent = true;
    }

61
    void EmitterState::SetLongKey()
Jesse Beder's avatar
Jesse Beder committed
62
    {
63
        assert(!m_groups.empty());        
64
        if(m_groups.empty())
65
66
67
68
69
            return;
        
        assert(m_groups.top().type == GroupType::Map);
        m_groups.top().longKey = true;
    }
Jesse Beder's avatar
Jesse Beder committed
70
71
72
73
74
75
76
77
78
    
    void EmitterState::ForceFlow()
    {
        assert(!m_groups.empty());
        if(m_groups.empty())
            return;
        
        m_groups.top().flowType = FlowType::Flow;
    }
79
80
81
82

    void EmitterState::StartedNode()
    {
        if(m_groups.empty()) {
83
            m_docCount++;
84
        } else {
Jesse Beder's avatar
Jesse Beder committed
85
            m_groups.top().childCount++;
86
87
88
            if(m_groups.top().childCount % 2 == 0)
                m_groups.top().longKey = false;
        }
Jesse Beder's avatar
Jesse Beder committed
89
90
91
        
        m_hasAnchor = false;
        m_hasTag = false;
Jesse Beder's avatar
Jesse Beder committed
92
        m_hasNonContent = false;
Jesse Beder's avatar
Jesse Beder committed
93
94
    }

95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
    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;
    }
    
Jesse Beder's avatar
Jesse Beder committed
114
115
116
117
118
119
120
121
122
123
124
125
126
127
    void EmitterState::StartedDoc()
    {
        m_hasAnchor = false;
        m_hasTag = false;
        m_hasNonContent = false;
    }
    
    void EmitterState::EndedDoc()
    {
        m_hasAnchor = false;
        m_hasTag = false;
        m_hasNonContent = false;
    }

128
    void EmitterState::StartedScalar()
Jesse Beder's avatar
Jesse Beder committed
129
    {
130
        StartedNode();
131
        ClearModifiedSettings();
Jesse Beder's avatar
Jesse Beder committed
132
133
    }

134
	void EmitterState::StartedGroup(GroupType::value type)
135
	{
136
        StartedNode();
Jesse Beder's avatar
Jesse Beder committed
137

Jesse Beder's avatar
Jesse Beder committed
138
139
		const int lastGroupIndent = (m_groups.empty() ? 0 : m_groups.top().indent);
		m_curIndent += lastGroupIndent;
140
		
141
		std::auto_ptr<Group> pGroup(new Group(type));
142
143
144
145
146
		
		// transfer settings (which last until this group is done)
		pGroup->modifiedSettings = m_modifiedSettings;

		// set up group
147
148
149
150
        if(GetFlowType(type) == Block)
            pGroup->flowType = FlowType::Block;
        else
            pGroup->flowType = FlowType::Flow;
151
152
		pGroup->indent = GetIndent();

153
		m_groups.push(pGroup);
154
155
	}
	
156
	void EmitterState::EndedGroup(GroupType::value type)
157
	{
Jesse Beder's avatar
Jesse Beder committed
158
159
160
161
162
163
		if(m_groups.empty()) {
            if(type == GroupType::Seq)
                return SetError(ErrorMsg::UNEXPECTED_END_SEQ);
            else
                return SetError(ErrorMsg::UNEXPECTED_END_MAP);
        }
164
165
166
		
		// get rid of the current group
		{
167
			std::auto_ptr<Group> pFinishedGroup = m_groups.pop();
168
169
170
171
172
			if(pFinishedGroup->type != type)
				return SetError(ErrorMsg::UNMATCHED_GROUP_TAG);
		}

		// reset old settings
173
		unsigned lastIndent = (m_groups.empty() ? 0 : m_groups.top().indent);
174
175
176
177
178
179
		assert(m_curIndent >= lastIndent);
		m_curIndent -= lastIndent;
		
		// some global settings that we changed may have been overridden
		// by a local setting we just popped, so we need to restore them
		m_globalModifiedSettings.restore();
180
181

        ClearModifiedSettings();
182
	}
183
184
185
186
187
188
189
190
191
192

    EmitterNodeType::value EmitterState::CurGroupNodeType() const
    {
        if(m_groups.empty())
            return EmitterNodeType::None;
        
        return m_groups.top().NodeType();
    }

    GroupType::value EmitterState::CurGroupType() const
193
	{
194
        return m_groups.empty() ? GroupType::None : m_groups.top().type;
195
196
	}
	
Jesse Beder's avatar
Jesse Beder committed
197
    FlowType::value EmitterState::CurGroupFlowType() const
198
	{
199
        return m_groups.empty() ? FlowType::None : m_groups.top().flowType;
200
201
	}

Jesse Beder's avatar
Jesse Beder committed
202
203
204
205
206
    int EmitterState::CurGroupIndent() const
    {
        return m_groups.empty() ? 0 : m_groups.top().indent;
    }

207
208
    std::size_t EmitterState::CurGroupChildCount() const
    {
209
        return m_groups.empty() ? m_docCount : m_groups.top().childCount;
210
211
    }

212
213
214
215
216
    bool EmitterState::CurGroupLongKey() const
    {
        return m_groups.empty() ? false : m_groups.top().longKey;
    }

Jesse Beder's avatar
Jesse Beder committed
217
218
219
220
221
222
223
224
    int EmitterState::LastIndent() const
    {
        if(m_groups.size() <= 1)
            return 0;
        
        return m_curIndent - m_groups.top(-1).indent;
    }

225
226
227
228
	void EmitterState::ClearModifiedSettings()
	{
		m_modifiedSettings.clear();
	}
229

230
	bool EmitterState::SetOutputCharset(EMITTER_MANIP value, FmtScope::value scope)
231
232
233
234
235
236
237
238
239
240
	{
		switch(value) {
			case EmitNonAscii:
			case EscapeNonAscii:
				_Set(m_charset, value, scope);
				return true;
			default:
				return false;
		}
	}
241
	
242
	bool EmitterState::SetStringFormat(EMITTER_MANIP value, FmtScope::value scope)
243
244
245
246
247
248
249
250
251
252
253
254
255
	{
		switch(value) {
			case Auto:
			case SingleQuoted:
			case DoubleQuoted:
			case Literal:
				_Set(m_strFmt, value, scope);
				return true;
			default:
				return false;
		}
	}
	
256
	bool EmitterState::SetBoolFormat(EMITTER_MANIP value, FmtScope::value scope)
257
258
259
260
261
262
263
264
265
266
267
268
	{
		switch(value) {
			case OnOffBool:
			case TrueFalseBool:
			case YesNoBool:
				_Set(m_boolFmt, value, scope);
				return true;
			default:
				return false;
		}
	}

269
	bool EmitterState::SetBoolLengthFormat(EMITTER_MANIP value, FmtScope::value scope)
270
271
272
273
274
275
276
277
278
279
280
	{
		switch(value) {
			case LongBool:
			case ShortBool:
				_Set(m_boolLengthFmt, value, scope);
				return true;
			default:
				return false;
		}
	}

281
	bool EmitterState::SetBoolCaseFormat(EMITTER_MANIP value, FmtScope::value scope)
282
283
284
285
286
287
288
289
290
291
292
293
	{
		switch(value) {
			case UpperCase:
			case LowerCase:
			case CamelCase:
				_Set(m_boolCaseFmt, value, scope);
				return true;
			default:
				return false;
		}
	}

294
	bool EmitterState::SetIntFormat(EMITTER_MANIP value, FmtScope::value scope)
295
296
297
298
299
300
301
302
303
304
305
306
	{
		switch(value) {
			case Dec:
			case Hex:
			case Oct:
				_Set(m_intFmt, value, scope);
				return true;
			default:
				return false;
		}
	}

307
	bool EmitterState::SetIndent(unsigned value, FmtScope::value scope)
308
	{
Jesse Beder's avatar
Jesse Beder committed
309
		if(value <= 1)
310
311
312
313
314
315
			return false;
		
		_Set(m_indent, value, scope);
		return true;
	}

316
	bool EmitterState::SetPreCommentIndent(unsigned value, FmtScope::value scope)
317
318
319
320
321
322
323
324
	{
		if(value == 0)
			return false;
		
		_Set(m_preCommentIndent, value, scope);
		return true;
	}
	
325
	bool EmitterState::SetPostCommentIndent(unsigned value, FmtScope::value scope)
326
327
328
329
330
331
332
333
	{
		if(value == 0)
			return false;
		
		_Set(m_postCommentIndent, value, scope);
		return true;
	}

334
	bool EmitterState::SetFlowType(GroupType::value groupType, EMITTER_MANIP value, FmtScope::value scope)
335
336
337
338
	{
		switch(value) {
			case Block:
			case Flow:
339
				_Set(groupType == GroupType::Seq ? m_seqFmt : m_mapFmt, value, scope);
340
341
342
343
344
345
				return true;
			default:
				return false;
		}
	}

346
	EMITTER_MANIP EmitterState::GetFlowType(GroupType::value groupType) const
347
348
	{
		// force flow style if we're currently in a flow
Jesse Beder's avatar
Jesse Beder committed
349
		if(CurGroupFlowType() == FlowType::Flow)
350
351
			return Flow;
		
352
353
		// otherwise, go with what's asked of us
		return (groupType == GroupType::Seq ? m_seqFmt.get() : m_mapFmt.get());
354
355
	}
	
356
	bool EmitterState::SetMapKeyFormat(EMITTER_MANIP value, FmtScope::value scope)
357
358
359
360
361
362
363
364
365
366
	{
		switch(value) {
			case Auto:
			case LongKey:
				_Set(m_mapKeyFmt, value, scope);
				return true;
			default:
				return false;
		}
	}
367

368
    bool EmitterState::SetFloatPrecision(int value, FmtScope::value scope)
369
    {
370
        if(value < 0 || value > std::numeric_limits<float>::digits10)
371
372
373
374
375
            return false;
        _Set(m_floatPrecision, value, scope);
        return true;
    }
    
376
    bool EmitterState::SetDoublePrecision(int value, FmtScope::value scope)
377
    {
378
        if(value < 0 || value > std::numeric_limits<double>::digits10)
379
380
381
382
            return false;
        _Set(m_doublePrecision, value, scope);
        return true;
    }
383
384
}