Loading [MathJax]/extensions/tex2jax.js
Free Electron
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
emitterstate.h
1 #ifndef EMITTERSTATE_H_62B23520_7C8E_11DE_8A39_0800200C9A66
2 #define EMITTERSTATE_H_62B23520_7C8E_11DE_8A39_0800200C9A66
3 
4 #if defined(_MSC_VER) || \
5  (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
6  (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
7 #pragma once
8 #endif
9 
10 #include "setting.h"
11 #include "yaml-cpp/emitterdef.h"
12 #include "yaml-cpp/emittermanip.h"
13 
14 #include <cassert>
15 #include <memory>
16 #include <stack>
17 #include <stdexcept>
18 #include <vector>
19 
20 namespace YAML {
21 struct FmtScope {
22  enum value { Local, Global };
23 };
24 struct GroupType {
25  enum value { NoType, Seq, Map };
26 };
27 struct FlowType {
28  enum value { NoType, Flow, Block };
29 };
30 
31 class EmitterState {
32  public:
33  EmitterState();
34  ~EmitterState();
35 
36  // basic state checking
37  bool good() const { return m_isGood; }
38  const std::string GetLastError() const { return m_lastError; }
39  void SetError(const std::string& error) {
40  m_isGood = false;
41  m_lastError = error;
42  }
43 
44  // node handling
45  void SetAnchor();
46  void SetAlias();
47  void SetTag();
48  void SetNonContent();
49  void SetLongKey();
50  void ForceFlow();
51  void StartedDoc();
52  void EndedDoc();
53  void StartedScalar();
54  void StartedGroup(GroupType::value type);
55  void EndedGroup(GroupType::value type);
56 
57  EmitterNodeType::value NextGroupType(GroupType::value type) const;
58  EmitterNodeType::value CurGroupNodeType() const;
59 
60  GroupType::value CurGroupType() const;
61  FlowType::value CurGroupFlowType() const;
62  std::size_t CurGroupIndent() const;
63  std::size_t CurGroupChildCount() const;
64  bool CurGroupLongKey() const;
65 
66  std::size_t LastIndent() const;
67  std::size_t CurIndent() const { return m_curIndent; }
68  bool HasAnchor() const { return m_hasAnchor; }
69  bool HasAlias() const { return m_hasAlias; }
70  bool HasTag() const { return m_hasTag; }
71  bool HasBegunNode() const {
72  return m_hasAnchor || m_hasTag || m_hasNonContent;
73  }
74  bool HasBegunContent() const { return m_hasAnchor || m_hasTag; }
75 
76  void ClearModifiedSettings();
77  void RestoreGlobalModifiedSettings();
78 
79  // formatters
80  void SetLocalValue(EMITTER_MANIP value);
81 
82  bool SetOutputCharset(EMITTER_MANIP value, FmtScope::value scope);
83  EMITTER_MANIP GetOutputCharset() const { return m_charset.get(); }
84 
85  bool SetStringFormat(EMITTER_MANIP value, FmtScope::value scope);
86  EMITTER_MANIP GetStringFormat() const { return m_strFmt.get(); }
87 
88  bool SetBoolFormat(EMITTER_MANIP value, FmtScope::value scope);
89  EMITTER_MANIP GetBoolFormat() const { return m_boolFmt.get(); }
90 
91  bool SetBoolLengthFormat(EMITTER_MANIP value, FmtScope::value scope);
92  EMITTER_MANIP GetBoolLengthFormat() const { return m_boolLengthFmt.get(); }
93 
94  bool SetBoolCaseFormat(EMITTER_MANIP value, FmtScope::value scope);
95  EMITTER_MANIP GetBoolCaseFormat() const { return m_boolCaseFmt.get(); }
96 
97  bool SetNullFormat(EMITTER_MANIP value, FmtScope::value scope);
98  EMITTER_MANIP GetNullFormat() const { return m_nullFmt.get(); }
99 
100  bool SetIntFormat(EMITTER_MANIP value, FmtScope::value scope);
101  EMITTER_MANIP GetIntFormat() const { return m_intFmt.get(); }
102 
103  bool SetIndent(std::size_t value, FmtScope::value scope);
104  std::size_t GetIndent() const { return m_indent.get(); }
105 
106  bool SetPreCommentIndent(std::size_t value, FmtScope::value scope);
107  std::size_t GetPreCommentIndent() const { return m_preCommentIndent.get(); }
108  bool SetPostCommentIndent(std::size_t value, FmtScope::value scope);
109  std::size_t GetPostCommentIndent() const { return m_postCommentIndent.get(); }
110 
111  bool SetFlowType(GroupType::value groupType, EMITTER_MANIP value,
112  FmtScope::value scope);
113  EMITTER_MANIP GetFlowType(GroupType::value groupType) const;
114 
115  bool SetMapKeyFormat(EMITTER_MANIP value, FmtScope::value scope);
116  EMITTER_MANIP GetMapKeyFormat() const { return m_mapKeyFmt.get(); }
117 
118  bool SetFloatPrecision(std::size_t value, FmtScope::value scope);
119  std::size_t GetFloatPrecision() const { return m_floatPrecision.get(); }
120  bool SetDoublePrecision(std::size_t value, FmtScope::value scope);
121  std::size_t GetDoublePrecision() const { return m_doublePrecision.get(); }
122 
123  private:
124  template <typename T>
125  void _Set(Setting<T>& fmt, T value, FmtScope::value scope);
126 
127  void StartedNode();
128 
129  private:
130  // basic state ok?
131  bool m_isGood;
132  std::string m_lastError;
133 
134  // other state
135  Setting<EMITTER_MANIP> m_charset;
136  Setting<EMITTER_MANIP> m_strFmt;
137  Setting<EMITTER_MANIP> m_boolFmt;
138  Setting<EMITTER_MANIP> m_boolLengthFmt;
139  Setting<EMITTER_MANIP> m_boolCaseFmt;
140  Setting<EMITTER_MANIP> m_nullFmt;
141  Setting<EMITTER_MANIP> m_intFmt;
142  Setting<std::size_t> m_indent;
143  Setting<std::size_t> m_preCommentIndent, m_postCommentIndent;
144  Setting<EMITTER_MANIP> m_seqFmt;
145  Setting<EMITTER_MANIP> m_mapFmt;
146  Setting<EMITTER_MANIP> m_mapKeyFmt;
147  Setting<std::size_t> m_floatPrecision;
148  Setting<std::size_t> m_doublePrecision;
149 
150  SettingChanges m_modifiedSettings;
151  SettingChanges m_globalModifiedSettings;
152 
153  struct Group {
154  explicit Group(GroupType::value type_)
155  : type(type_),
156  flowType{},
157  indent(0),
158  childCount(0),
159  longKey(false),
160  modifiedSettings{} {}
161 
162  GroupType::value type;
163  FlowType::value flowType;
164  std::size_t indent;
165  std::size_t childCount;
166  bool longKey;
167 
168  SettingChanges modifiedSettings;
169 
170  EmitterNodeType::value NodeType() const {
171  if (type == GroupType::Seq) {
172  if (flowType == FlowType::Flow)
173  return EmitterNodeType::FlowSeq;
174  else
175  return EmitterNodeType::BlockSeq;
176  } else {
177  if (flowType == FlowType::Flow)
178  return EmitterNodeType::FlowMap;
179  else
180  return EmitterNodeType::BlockMap;
181  }
182 
183  // can't get here
184  assert(false);
185  return EmitterNodeType::NoType;
186  }
187  };
188 
189  std::vector<std::unique_ptr<Group>> m_groups;
190  std::size_t m_curIndent;
191  bool m_hasAnchor;
192  bool m_hasAlias;
193  bool m_hasTag;
194  bool m_hasNonContent;
195  std::size_t m_docCount;
196 };
197 
198 template <typename T>
199 void EmitterState::_Set(Setting<T>& fmt, T value, FmtScope::value scope) {
200  switch (scope) {
201  case FmtScope::Local:
202  m_modifiedSettings.push(fmt.set(value));
203  break;
204  case FmtScope::Global:
205  fmt.set(value);
206  m_globalModifiedSettings.push(
207  fmt.set(value)); // this pushes an identity set, so when we restore,
208  // it restores to the value here, and not the previous one
209  break;
210  default:
211  assert(false);
212  }
213 }
214 } // namespace YAML
215 
216 #endif // EMITTERSTATE_H_62B23520_7C8E_11DE_8A39_0800200C9A66
Definition: anchor.h:12