00001 #ifndef EMITTERSTATE_H_62B23520_7C8E_11DE_8A39_0800200C9A66
00002 #define EMITTERSTATE_H_62B23520_7C8E_11DE_8A39_0800200C9A66
00003
00004 #if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
00005 #pragma once
00006 #endif
00007
00008
00009 #include "ptr_stack.h"
00010 #include "setting.h"
00011 #include "yaml-cpp-pm/emittermanip.h"
00012 #include <cassert>
00013 #include <vector>
00014 #include <stack>
00015 #include <memory>
00016
00017 namespace YAML_PM
00018 {
00019 enum FMT_SCOPE {
00020 LOCAL,
00021 GLOBAL
00022 };
00023
00024 enum GROUP_TYPE {
00025 GT_NONE,
00026 GT_SEQ,
00027 GT_MAP
00028 };
00029
00030 enum FLOW_TYPE {
00031 FT_NONE,
00032 FT_FLOW,
00033 FT_BLOCK
00034 };
00035
00036 enum NODE_STATE {
00037 NS_START,
00038 NS_READY_FOR_ATOM,
00039 NS_END
00040 };
00041
00042 enum EMITTER_STATE {
00043 ES_WAITING_FOR_DOC,
00044 ES_WRITING_DOC,
00045 ES_DONE_WITH_DOC,
00046
00047
00048 ES_WAITING_FOR_BLOCK_SEQ_ENTRY,
00049 ES_WRITING_BLOCK_SEQ_ENTRY,
00050 ES_DONE_WITH_BLOCK_SEQ_ENTRY,
00051
00052
00053 ES_WAITING_FOR_FLOW_SEQ_ENTRY,
00054 ES_WRITING_FLOW_SEQ_ENTRY,
00055 ES_DONE_WITH_FLOW_SEQ_ENTRY,
00056
00057
00058 ES_WAITING_FOR_BLOCK_MAP_ENTRY,
00059 ES_WAITING_FOR_BLOCK_MAP_KEY,
00060 ES_WRITING_BLOCK_MAP_KEY,
00061 ES_DONE_WITH_BLOCK_MAP_KEY,
00062 ES_WAITING_FOR_BLOCK_MAP_VALUE,
00063 ES_WRITING_BLOCK_MAP_VALUE,
00064 ES_DONE_WITH_BLOCK_MAP_VALUE,
00065
00066
00067 ES_WAITING_FOR_FLOW_MAP_ENTRY,
00068 ES_WAITING_FOR_FLOW_MAP_KEY,
00069 ES_WRITING_FLOW_MAP_KEY,
00070 ES_DONE_WITH_FLOW_MAP_KEY,
00071 ES_WAITING_FOR_FLOW_MAP_VALUE,
00072 ES_WRITING_FLOW_MAP_VALUE,
00073 ES_DONE_WITH_FLOW_MAP_VALUE
00074 };
00075
00076 class EmitterState
00077 {
00078 public:
00079 EmitterState();
00080 ~EmitterState();
00081
00082
00083 bool good() const { return m_isGood; }
00084 const std::string GetLastError() const { return m_lastError; }
00085 void SetError(const std::string& error) { m_isGood = false; m_lastError = error; }
00086
00087
00088 EMITTER_STATE GetCurState() const { return m_stateStack.top(); }
00089 void SwitchState(EMITTER_STATE state) { PopState(); PushState(state); }
00090 void PushState(EMITTER_STATE state) { m_stateStack.push(state); }
00091 void PopState() { m_stateStack.pop(); }
00092
00093 void SetLocalValue(EMITTER_MANIP value);
00094
00095
00096 void BeginGroup(GROUP_TYPE type);
00097 void EndGroup(GROUP_TYPE type);
00098
00099 GROUP_TYPE GetCurGroupType() const;
00100 FLOW_TYPE GetCurGroupFlowType() const;
00101 int GetCurIndent() const { return m_curIndent; }
00102
00103 bool CurrentlyInLongKey();
00104 void StartLongKey();
00105 void StartSimpleKey();
00106
00107 bool RequiresSoftSeparation() const { return m_requiresSoftSeparation; }
00108 bool RequiresHardSeparation() const { return m_requiresHardSeparation; }
00109 void RequireSoftSeparation() { m_requiresSoftSeparation = true; }
00110 void RequireHardSeparation() { m_requiresSoftSeparation = true; m_requiresHardSeparation = true; }
00111 void ForceHardSeparation() { m_requiresSoftSeparation = false; }
00112 void UnsetSeparation() { m_requiresSoftSeparation = false; m_requiresHardSeparation = false; }
00113
00114 void ClearModifiedSettings();
00115
00116
00117 bool SetOutputCharset(EMITTER_MANIP value, FMT_SCOPE scope);
00118 EMITTER_MANIP GetOutputCharset() const { return m_charset.get(); }
00119
00120 bool SetStringFormat(EMITTER_MANIP value, FMT_SCOPE scope);
00121 EMITTER_MANIP GetStringFormat() const { return m_strFmt.get(); }
00122
00123 bool SetBoolFormat(EMITTER_MANIP value, FMT_SCOPE scope);
00124 EMITTER_MANIP GetBoolFormat() const { return m_boolFmt.get(); }
00125
00126 bool SetBoolLengthFormat(EMITTER_MANIP value, FMT_SCOPE scope);
00127 EMITTER_MANIP GetBoolLengthFormat() const { return m_boolLengthFmt.get(); }
00128
00129 bool SetBoolCaseFormat(EMITTER_MANIP value, FMT_SCOPE scope);
00130 EMITTER_MANIP GetBoolCaseFormat() const { return m_boolCaseFmt.get(); }
00131
00132 bool SetIntFormat(EMITTER_MANIP value, FMT_SCOPE scope);
00133 EMITTER_MANIP GetIntFormat() const { return m_intFmt.get(); }
00134
00135 bool SetIndent(unsigned value, FMT_SCOPE scope);
00136 int GetIndent() const { return m_indent.get(); }
00137
00138 bool SetPreCommentIndent(unsigned value, FMT_SCOPE scope);
00139 int GetPreCommentIndent() const { return m_preCommentIndent.get(); }
00140 bool SetPostCommentIndent(unsigned value, FMT_SCOPE scope);
00141 int GetPostCommentIndent() const { return m_postCommentIndent.get(); }
00142
00143 bool SetFlowType(GROUP_TYPE groupType, EMITTER_MANIP value, FMT_SCOPE scope);
00144 EMITTER_MANIP GetFlowType(GROUP_TYPE groupType) const;
00145
00146 bool SetMapKeyFormat(EMITTER_MANIP value, FMT_SCOPE scope);
00147 EMITTER_MANIP GetMapKeyFormat() const { return m_mapKeyFmt.get(); }
00148
00149 bool SetFloatPrecision(int value, FMT_SCOPE scope);
00150 unsigned GetFloatPrecision() const { return m_floatPrecision.get(); }
00151 bool SetDoublePrecision(int value, FMT_SCOPE scope);
00152 unsigned GetDoublePrecision() const { return m_doublePrecision.get(); }
00153
00154 private:
00155 template <typename T>
00156 void _Set(Setting<T>& fmt, T value, FMT_SCOPE scope);
00157
00158 private:
00159
00160 bool m_isGood;
00161 std::string m_lastError;
00162
00163
00164 std::stack<EMITTER_STATE> m_stateStack;
00165
00166 Setting<EMITTER_MANIP> m_charset;
00167 Setting<EMITTER_MANIP> m_strFmt;
00168 Setting<EMITTER_MANIP> m_boolFmt;
00169 Setting<EMITTER_MANIP> m_boolLengthFmt;
00170 Setting<EMITTER_MANIP> m_boolCaseFmt;
00171 Setting<EMITTER_MANIP> m_intFmt;
00172 Setting<unsigned> m_indent;
00173 Setting<unsigned> m_preCommentIndent, m_postCommentIndent;
00174 Setting<EMITTER_MANIP> m_seqFmt;
00175 Setting<EMITTER_MANIP> m_mapFmt;
00176 Setting<EMITTER_MANIP> m_mapKeyFmt;
00177 Setting<int> m_floatPrecision;
00178 Setting<int> m_doublePrecision;
00179
00180 SettingChanges m_modifiedSettings;
00181 SettingChanges m_globalModifiedSettings;
00182
00183 struct Group {
00184 Group(GROUP_TYPE type_): type(type_), usingLongKey(false), indent(0) {}
00185
00186 GROUP_TYPE type;
00187 EMITTER_MANIP flow;
00188 bool usingLongKey;
00189 int indent;
00190
00191 SettingChanges modifiedSettings;
00192 };
00193
00194 ptr_stack<Group> m_groups;
00195 unsigned m_curIndent;
00196 bool m_requiresSoftSeparation;
00197 bool m_requiresHardSeparation;
00198 };
00199
00200 template <typename T>
00201 void EmitterState::_Set(Setting<T>& fmt, T value, FMT_SCOPE scope) {
00202 switch(scope) {
00203 case LOCAL:
00204 m_modifiedSettings.push(fmt.set(value));
00205 break;
00206 case GLOBAL:
00207 fmt.set(value);
00208 m_globalModifiedSettings.push(fmt.set(value));
00209
00210 break;
00211 default:
00212 assert(false);
00213 }
00214 }
00215 }
00216
00217 #endif // EMITTERSTATE_H_62B23520_7C8E_11DE_8A39_0800200C9A66