OSDN Git Service

First version
[st-ro/stro.git] / 3rdparty / yaml-cpp / src / emitterstate.cpp
1 #include <limits>
2
3 #include "emitterstate.h"
4 #include "yaml-cpp/exceptions.h"  // IWYU pragma: keep
5
6 namespace YAML {
7 EmitterState::EmitterState()
8     : m_isGood(true),
9       m_curIndent(0),
10       m_hasAnchor(false),
11       m_hasTag(false),
12       m_hasNonContent(false),
13       m_docCount(0) {
14   // set default global manipulators
15   m_charset.set(EmitNonAscii);
16   m_strFmt.set(Auto);
17   m_boolFmt.set(TrueFalseBool);
18   m_nullFmt.set(NullAsTilde);
19   m_boolLengthFmt.set(LongBool);
20   m_boolCaseFmt.set(LowerCase);
21   m_intFmt.set(Dec);
22   m_indent.set(2);
23   m_preCommentIndent.set(2);
24   m_postCommentIndent.set(1);
25   m_seqFmt.set(Block);
26   m_mapFmt.set(Block);
27   m_mapKeyFmt.set(Auto);
28   m_floatPrecision.set(std::numeric_limits<float>::digits10 + 1);
29   m_doublePrecision.set(std::numeric_limits<double>::digits10 + 1);
30 }
31
32 EmitterState::~EmitterState() {}
33
34 // SetLocalValue
35 // . We blindly tries to set all possible formatters to this value
36 // . Only the ones that make sense will be accepted
37 void EmitterState::SetLocalValue(EMITTER_MANIP value) {
38   SetOutputCharset(value, FmtScope::Local);
39   SetStringFormat(value, FmtScope::Local);
40   SetBoolFormat(value, FmtScope::Local);
41   SetBoolCaseFormat(value, FmtScope::Local);
42   SetBoolLengthFormat(value, FmtScope::Local);
43   SetNullFormat(value, FmtScope::Local);
44   SetIntFormat(value, FmtScope::Local);
45   SetFlowType(GroupType::Seq, value, FmtScope::Local);
46   SetFlowType(GroupType::Map, value, FmtScope::Local);
47   SetMapKeyFormat(value, FmtScope::Local);
48 }
49
50 void EmitterState::SetAnchor() { m_hasAnchor = true; }
51
52 void EmitterState::SetTag() { m_hasTag = true; }
53
54 void EmitterState::SetNonContent() { m_hasNonContent = true; }
55
56 void EmitterState::SetLongKey() {
57   assert(!m_groups.empty());
58   if (m_groups.empty()) {
59     return;
60   }
61
62   assert(m_groups.back()->type == GroupType::Map);
63   m_groups.back()->longKey = true;
64 }
65
66 void EmitterState::ForceFlow() {
67   assert(!m_groups.empty());
68   if (m_groups.empty()) {
69     return;
70   }
71
72   m_groups.back()->flowType = FlowType::Flow;
73 }
74
75 void EmitterState::StartedNode() {
76   if (m_groups.empty()) {
77     m_docCount++;
78   } else {
79     m_groups.back()->childCount++;
80     if (m_groups.back()->childCount % 2 == 0) {
81       m_groups.back()->longKey = false;
82     }
83   }
84
85   m_hasAnchor = false;
86   m_hasTag = false;
87   m_hasNonContent = false;
88 }
89
90 EmitterNodeType::value EmitterState::NextGroupType(
91     GroupType::value type) const {
92   if (type == GroupType::Seq) {
93     if (GetFlowType(type) == Block)
94       return EmitterNodeType::BlockSeq;
95     else
96       return EmitterNodeType::FlowSeq;
97   } else {
98     if (GetFlowType(type) == Block)
99       return EmitterNodeType::BlockMap;
100     else
101       return EmitterNodeType::FlowMap;
102   }
103
104   // can't happen
105   assert(false);
106   return EmitterNodeType::NoType;
107 }
108
109 void EmitterState::StartedDoc() {
110   m_hasAnchor = false;
111   m_hasTag = false;
112   m_hasNonContent = false;
113 }
114
115 void EmitterState::EndedDoc() {
116   m_hasAnchor = false;
117   m_hasTag = false;
118   m_hasNonContent = false;
119 }
120
121 void EmitterState::StartedScalar() {
122   StartedNode();
123   ClearModifiedSettings();
124 }
125
126 void EmitterState::StartedGroup(GroupType::value type) {
127   StartedNode();
128
129   const std::size_t lastGroupIndent =
130       (m_groups.empty() ? 0 : m_groups.back()->indent);
131   m_curIndent += lastGroupIndent;
132
133   // TODO: Create move constructors for settings types to simplify transfer
134   std::unique_ptr<Group> pGroup(new Group(type));
135
136   // transfer settings (which last until this group is done)
137   //
138   // NB: if pGroup->modifiedSettings == m_modifiedSettings,
139   // m_modifiedSettings is not changed!
140   pGroup->modifiedSettings = std::move(m_modifiedSettings);
141
142   // set up group
143   if (GetFlowType(type) == Block) {
144     pGroup->flowType = FlowType::Block;
145   } else {
146     pGroup->flowType = FlowType::Flow;
147   }
148   pGroup->indent = GetIndent();
149
150   m_groups.push_back(std::move(pGroup));
151 }
152
153 void EmitterState::EndedGroup(GroupType::value type) {
154   if (m_groups.empty()) {
155     if (type == GroupType::Seq) {
156       return SetError(ErrorMsg::UNEXPECTED_END_SEQ);
157     } else {
158       return SetError(ErrorMsg::UNEXPECTED_END_MAP);
159     }
160   }
161
162   // get rid of the current group
163   {
164     std::unique_ptr<Group> pFinishedGroup = std::move(m_groups.back());
165     m_groups.pop_back();
166     if (pFinishedGroup->type != type) {
167       return SetError(ErrorMsg::UNMATCHED_GROUP_TAG);
168     }
169   }
170
171   // reset old settings
172   std::size_t lastIndent = (m_groups.empty() ? 0 : m_groups.back()->indent);
173   assert(m_curIndent >= lastIndent);
174   m_curIndent -= lastIndent;
175
176   // some global settings that we changed may have been overridden
177   // by a local setting we just popped, so we need to restore them
178   m_globalModifiedSettings.restore();
179
180   ClearModifiedSettings();
181 }
182
183 EmitterNodeType::value EmitterState::CurGroupNodeType() const {
184   if (m_groups.empty()) {
185     return EmitterNodeType::NoType;
186   }
187
188   return m_groups.back()->NodeType();
189 }
190
191 GroupType::value EmitterState::CurGroupType() const {
192   return m_groups.empty() ? GroupType::NoType : m_groups.back()->type;
193 }
194
195 FlowType::value EmitterState::CurGroupFlowType() const {
196   return m_groups.empty() ? FlowType::NoType : m_groups.back()->flowType;
197 }
198
199 std::size_t EmitterState::CurGroupIndent() const {
200   return m_groups.empty() ? 0 : m_groups.back()->indent;
201 }
202
203 std::size_t EmitterState::CurGroupChildCount() const {
204   return m_groups.empty() ? m_docCount : m_groups.back()->childCount;
205 }
206
207 bool EmitterState::CurGroupLongKey() const {
208   return m_groups.empty() ? false : m_groups.back()->longKey;
209 }
210
211 std::size_t EmitterState::LastIndent() const {
212   if (m_groups.size() <= 1) {
213     return 0;
214   }
215
216   return m_curIndent - m_groups[m_groups.size() - 2]->indent;
217 }
218
219 void EmitterState::ClearModifiedSettings() { m_modifiedSettings.clear(); }
220
221 bool EmitterState::SetOutputCharset(EMITTER_MANIP value,
222                                     FmtScope::value scope) {
223   switch (value) {
224     case EmitNonAscii:
225     case EscapeNonAscii:
226     case EscapeAsJson:
227       _Set(m_charset, value, scope);
228       return true;
229     default:
230       return false;
231   }
232 }
233
234 bool EmitterState::SetStringFormat(EMITTER_MANIP value, FmtScope::value scope) {
235   switch (value) {
236     case Auto:
237     case SingleQuoted:
238     case DoubleQuoted:
239     case Literal:
240       _Set(m_strFmt, value, scope);
241       return true;
242     default:
243       return false;
244   }
245 }
246
247 bool EmitterState::SetBoolFormat(EMITTER_MANIP value, FmtScope::value scope) {
248   switch (value) {
249     case OnOffBool:
250     case TrueFalseBool:
251     case YesNoBool:
252       _Set(m_boolFmt, value, scope);
253       return true;
254     default:
255       return false;
256   }
257 }
258
259 bool EmitterState::SetBoolLengthFormat(EMITTER_MANIP value,
260                                        FmtScope::value scope) {
261   switch (value) {
262     case LongBool:
263     case ShortBool:
264       _Set(m_boolLengthFmt, value, scope);
265       return true;
266     default:
267       return false;
268   }
269 }
270
271 bool EmitterState::SetBoolCaseFormat(EMITTER_MANIP value,
272                                      FmtScope::value scope) {
273   switch (value) {
274     case UpperCase:
275     case LowerCase:
276     case CamelCase:
277       _Set(m_boolCaseFmt, value, scope);
278       return true;
279     default:
280       return false;
281   }
282 }
283
284 bool EmitterState::SetNullFormat(EMITTER_MANIP value, FmtScope::value scope) {
285   switch (value) {
286   case NullAsTilde:
287   case NullAsNull:
288     _Set(m_nullFmt, value, scope);
289     return true;
290   default:
291     return false;
292   }
293 }
294
295 bool EmitterState::SetIntFormat(EMITTER_MANIP value, FmtScope::value scope) {
296   switch (value) {
297     case Dec:
298     case Hex:
299     case Oct:
300       _Set(m_intFmt, value, scope);
301       return true;
302     default:
303       return false;
304   }
305 }
306
307 bool EmitterState::SetIndent(std::size_t value, FmtScope::value scope) {
308   if (value <= 1)
309     return false;
310
311   _Set(m_indent, value, scope);
312   return true;
313 }
314
315 bool EmitterState::SetPreCommentIndent(std::size_t value,
316                                        FmtScope::value scope) {
317   if (value == 0)
318     return false;
319
320   _Set(m_preCommentIndent, value, scope);
321   return true;
322 }
323
324 bool EmitterState::SetPostCommentIndent(std::size_t value,
325                                         FmtScope::value scope) {
326   if (value == 0)
327     return false;
328
329   _Set(m_postCommentIndent, value, scope);
330   return true;
331 }
332
333 bool EmitterState::SetFlowType(GroupType::value groupType, EMITTER_MANIP value,
334                                FmtScope::value scope) {
335   switch (value) {
336     case Block:
337     case Flow:
338       _Set(groupType == GroupType::Seq ? m_seqFmt : m_mapFmt, value, scope);
339       return true;
340     default:
341       return false;
342   }
343 }
344
345 EMITTER_MANIP EmitterState::GetFlowType(GroupType::value groupType) const {
346   // force flow style if we're currently in a flow
347   if (CurGroupFlowType() == FlowType::Flow)
348     return Flow;
349
350   // otherwise, go with what's asked of us
351   return (groupType == GroupType::Seq ? m_seqFmt.get() : m_mapFmt.get());
352 }
353
354 bool EmitterState::SetMapKeyFormat(EMITTER_MANIP value, FmtScope::value scope) {
355   switch (value) {
356     case Auto:
357     case LongKey:
358       _Set(m_mapKeyFmt, value, scope);
359       return true;
360     default:
361       return false;
362   }
363 }
364
365 bool EmitterState::SetFloatPrecision(std::size_t value, FmtScope::value scope) {
366   if (value > std::numeric_limits<float>::digits10 + 1)
367     return false;
368   _Set(m_floatPrecision, value, scope);
369   return true;
370 }
371
372 bool EmitterState::SetDoublePrecision(std::size_t value,
373                                       FmtScope::value scope) {
374   if (value > std::numeric_limits<double>::digits10 + 1)
375     return false;
376   _Set(m_doublePrecision, value, scope);
377   return true;
378 }
379 }