emitterstate.h 6.16 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
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
};

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();
  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;
61
  std::size_t CurGroupIndent() const;
Jesse Beder's avatar
Jesse Beder committed
62
63
64
  std::size_t CurGroupChildCount() const;
  bool CurGroupLongKey() const;

65
66
  std::size_t LastIndent() const;
  std::size_t CurIndent() const { return m_curIndent; }
Jesse Beder's avatar
Jesse Beder committed
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
  bool HasAnchor() const { return m_hasAnchor; }
  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();

  // 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(); }

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

97
  bool SetIndent(std::size_t value, FmtScope::value scope);
98
  std::size_t GetIndent() const { return m_indent.get(); }
Jesse Beder's avatar
Jesse Beder committed
99

100
  bool SetPreCommentIndent(std::size_t value, FmtScope::value scope);
101
  std::size_t GetPreCommentIndent() const { return m_preCommentIndent.get(); }
102
  bool SetPostCommentIndent(std::size_t value, FmtScope::value scope);
103
  std::size_t GetPostCommentIndent() const { return m_postCommentIndent.get(); }
Jesse Beder's avatar
Jesse Beder committed
104
105
106
107
108
109
110
111

  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(); }

112
  bool SetFloatPrecision(std::size_t value, FmtScope::value scope);
113
  std::size_t GetFloatPrecision() const { return m_floatPrecision.get(); }
114
  bool SetDoublePrecision(std::size_t value, FmtScope::value scope);
115
  std::size_t GetDoublePrecision() const { return m_doublePrecision.get(); }
Jesse Beder's avatar
Jesse Beder committed
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134

 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;
  Setting<EMITTER_MANIP> m_intFmt;
135
136
  Setting<std::size_t> m_indent;
  Setting<std::size_t> m_preCommentIndent, m_postCommentIndent;
Jesse Beder's avatar
Jesse Beder committed
137
138
139
  Setting<EMITTER_MANIP> m_seqFmt;
  Setting<EMITTER_MANIP> m_mapFmt;
  Setting<EMITTER_MANIP> m_mapKeyFmt;
140
141
  Setting<std::size_t> m_floatPrecision;
  Setting<std::size_t> m_doublePrecision;
Jesse Beder's avatar
Jesse Beder committed
142
143
144
145
146
147

  SettingChanges m_modifiedSettings;
  SettingChanges m_globalModifiedSettings;

  struct Group {
    explicit Group(GroupType::value type_)
148
149
150
151
152
153
        : type(type_),
          flowType{},
          indent(0),
          childCount(0),
          longKey(false),
          modifiedSettings{} {}
Jesse Beder's avatar
Jesse Beder committed
154
155
156

    GroupType::value type;
    FlowType::value flowType;
157
    std::size_t indent;
Jesse Beder's avatar
Jesse Beder committed
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
    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);
178
      return EmitterNodeType::NoType;
Jesse Beder's avatar
Jesse Beder committed
179
180
181
    }
  };

182
  std::vector<std::unique_ptr<Group>> m_groups;
183
  std::size_t m_curIndent;
Jesse Beder's avatar
Jesse Beder committed
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
  bool m_hasAnchor;
  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);
  }
}
206
}  // namespace YAML
207

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