emitterstate.h 6.2 KB

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