emitterstate.h (6600B)
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