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

Jesse Beder's avatar
Jesse Beder committed
4
5
6
#if defined(_MSC_VER) ||                                            \
    (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
     (__GNUC__ >= 4))  // GCC supports "pragma once" correctly since 3.4
7
8
9
#pragma once
#endif

10
#include "setting.h"
11
#include "yaml-cpp/emitterdef.h"
12
#include "yaml-cpp/emittermanip.h"
13

14
15
#include <cassert>
#include <memory>
16
#include <stack>
Jesse Beder's avatar
Jesse Beder committed
17
#include <stdexcept>
18
#include <vector>
19

Jesse Beder's avatar
Jesse Beder committed
20
21
namespace YAML {
struct FmtScope {
Jesse Beder's avatar
Jesse Beder committed
22
  enum value { Local, Global };
Jesse Beder's avatar
Jesse Beder committed
23
24
};
struct GroupType {
25
  enum value { NoType, Seq, Map };
Jesse Beder's avatar
Jesse Beder committed
26
27
};
struct FlowType {
28
  enum value { NoType, Flow, Block };
Jesse Beder's avatar
Jesse Beder committed
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
};

class EmitterState {
 public:
  EmitterState();
  ~EmitterState();

  // basic state checking
  bool good() const { return m_isGood; }
  const std::string GetLastError() const { return m_lastError; }
  void SetError(const std::string& error) {
    m_isGood = false;
    m_lastError = error;
  }

  // node handling
  void SetAnchor();
46
  void SetAlias();
Jesse Beder's avatar
Jesse Beder committed
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
  void SetTag();
  void SetNonContent();
  void SetLongKey();
  void ForceFlow();
  void StartedDoc();
  void EndedDoc();
  void StartedScalar();
  void StartedGroup(GroupType::value type);
  void EndedGroup(GroupType::value type);

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

  GroupType::value CurGroupType() const;
  FlowType::value CurGroupFlowType() const;
62
  std::size_t CurGroupIndent() const;
Jesse Beder's avatar
Jesse Beder committed
63
64
65
  std::size_t CurGroupChildCount() const;
  bool CurGroupLongKey() const;

66
67
  std::size_t LastIndent() const;
  std::size_t CurIndent() const { return m_curIndent; }
Jesse Beder's avatar
Jesse Beder committed
68
  bool HasAnchor() const { return m_hasAnchor; }
69
  bool HasAlias() const { return m_hasAlias; }
Jesse Beder's avatar
Jesse Beder committed
70
71
72
73
74
75
76
  bool HasTag() const { return m_hasTag; }
  bool HasBegunNode() const {
    return m_hasAnchor || m_hasTag || m_hasNonContent;
  }
  bool HasBegunContent() const { return m_hasAnchor || m_hasTag; }

  void ClearModifiedSettings();
77
  void RestoreGlobalModifiedSettings();
Jesse Beder's avatar
Jesse Beder committed
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96

  // formatters
  void SetLocalValue(EMITTER_MANIP value);

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

  bool SetStringFormat(EMITTER_MANIP value, FmtScope::value scope);
  EMITTER_MANIP GetStringFormat() const { return m_strFmt.get(); }

  bool SetBoolFormat(EMITTER_MANIP value, FmtScope::value scope);
  EMITTER_MANIP GetBoolFormat() const { return m_boolFmt.get(); }

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

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

97
98
99
  bool SetNullFormat(EMITTER_MANIP value, FmtScope::value scope);
  EMITTER_MANIP GetNullFormat() const { return m_nullFmt.get(); }

Jesse Beder's avatar
Jesse Beder committed
100
101
102
  bool SetIntFormat(EMITTER_MANIP value, FmtScope::value scope);
  EMITTER_MANIP GetIntFormat() const { return m_intFmt.get(); }

103
  bool SetIndent(std::size_t value, FmtScope::value scope);
104
  std::size_t GetIndent() const { return m_indent.get(); }
Jesse Beder's avatar
Jesse Beder committed
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(); }
Jesse Beder's avatar
Jesse Beder committed
110
111
112
113
114
115
116
117

  bool SetFlowType(GroupType::value groupType, EMITTER_MANIP value,
                   FmtScope::value scope);
  EMITTER_MANIP GetFlowType(GroupType::value groupType) const;

  bool SetMapKeyFormat(EMITTER_MANIP value, FmtScope::value scope);
  EMITTER_MANIP GetMapKeyFormat() const { return m_mapKeyFmt.get(); }

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(); }
Jesse Beder's avatar
Jesse Beder committed
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139

 private:
  template <typename T>
  void _Set(Setting<T>& fmt, T value, FmtScope::value scope);

  void StartedNode();

 private:
  // basic state ok?
  bool m_isGood;
  std::string m_lastError;

  // other state
  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;
140
  Setting<EMITTER_MANIP> m_nullFmt;
Jesse Beder's avatar
Jesse Beder committed
141
  Setting<EMITTER_MANIP> m_intFmt;
142
143
  Setting<std::size_t> m_indent;
  Setting<std::size_t> m_preCommentIndent, m_postCommentIndent;
Jesse Beder's avatar
Jesse Beder committed
144
145
146
  Setting<EMITTER_MANIP> m_seqFmt;
  Setting<EMITTER_MANIP> m_mapFmt;
  Setting<EMITTER_MANIP> m_mapKeyFmt;
147
148
  Setting<std::size_t> m_floatPrecision;
  Setting<std::size_t> m_doublePrecision;
Jesse Beder's avatar
Jesse Beder committed
149
150
151
152
153
154

  SettingChanges m_modifiedSettings;
  SettingChanges m_globalModifiedSettings;

  struct Group {
    explicit Group(GroupType::value type_)
155
156
157
158
159
160
        : type(type_),
          flowType{},
          indent(0),
          childCount(0),
          longKey(false),
          modifiedSettings{} {}
Jesse Beder's avatar
Jesse Beder committed
161
162
163

    GroupType::value type;
    FlowType::value flowType;
164
    std::size_t indent;
Jesse Beder's avatar
Jesse Beder committed
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
    std::size_t childCount;
    bool longKey;

    SettingChanges modifiedSettings;

    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);
185
      return EmitterNodeType::NoType;
Jesse Beder's avatar
Jesse Beder committed
186
187
188
    }
  };

189
  std::vector<std::unique_ptr<Group>> m_groups;
190
  std::size_t m_curIndent;
Jesse Beder's avatar
Jesse Beder committed
191
  bool m_hasAnchor;
192
  bool m_hasAlias;
Jesse Beder's avatar
Jesse Beder committed
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
  bool m_hasTag;
  bool m_hasNonContent;
  std::size_t m_docCount;
};

template <typename T>
void EmitterState::_Set(Setting<T>& fmt, T value, FmtScope::value scope) {
  switch (scope) {
    case FmtScope::Local:
      m_modifiedSettings.push(fmt.set(value));
      break;
    case FmtScope::Global:
      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);
  }
}
214
}  // namespace YAML
215

Jesse Beder's avatar
Jesse Beder committed
216
#endif  // EMITTERSTATE_H_62B23520_7C8E_11DE_8A39_0800200C9A66