mirror of
https://github.com/jbeder/yaml-cpp.git
synced 2025-09-09 20:51:16 +00:00
Merged emitter branch into trunk, changes r105:r151
This commit is contained in:
195
src/emitterstate.h
Normal file
195
src/emitterstate.h
Normal file
@@ -0,0 +1,195 @@
|
||||
#pragma once
|
||||
|
||||
#include "setting.h"
|
||||
#include "emittermanip.h"
|
||||
#include <cassert>
|
||||
#include <vector>
|
||||
#include <stack>
|
||||
#include <memory>
|
||||
|
||||
namespace YAML
|
||||
{
|
||||
enum FMT_SCOPE {
|
||||
LOCAL,
|
||||
GLOBAL
|
||||
};
|
||||
|
||||
enum GROUP_TYPE {
|
||||
GT_NONE,
|
||||
GT_SEQ,
|
||||
GT_MAP
|
||||
};
|
||||
|
||||
enum FLOW_TYPE {
|
||||
FT_NONE,
|
||||
FT_FLOW,
|
||||
FT_BLOCK
|
||||
};
|
||||
|
||||
enum NODE_STATE {
|
||||
NS_START,
|
||||
NS_READY_FOR_ATOM,
|
||||
NS_END
|
||||
};
|
||||
|
||||
enum EMITTER_STATE {
|
||||
ES_WAITING_FOR_DOC,
|
||||
ES_WRITING_DOC,
|
||||
ES_DONE_WITH_DOC,
|
||||
|
||||
// block seq
|
||||
ES_WAITING_FOR_BLOCK_SEQ_ENTRY,
|
||||
ES_WRITING_BLOCK_SEQ_ENTRY,
|
||||
ES_DONE_WITH_BLOCK_SEQ_ENTRY,
|
||||
|
||||
// flow seq
|
||||
ES_WAITING_FOR_FLOW_SEQ_ENTRY,
|
||||
ES_WRITING_FLOW_SEQ_ENTRY,
|
||||
ES_DONE_WITH_FLOW_SEQ_ENTRY,
|
||||
|
||||
// block map
|
||||
ES_WAITING_FOR_BLOCK_MAP_ENTRY,
|
||||
ES_WAITING_FOR_BLOCK_MAP_KEY,
|
||||
ES_WRITING_BLOCK_MAP_KEY,
|
||||
ES_DONE_WITH_BLOCK_MAP_KEY,
|
||||
ES_WAITING_FOR_BLOCK_MAP_VALUE,
|
||||
ES_WRITING_BLOCK_MAP_VALUE,
|
||||
ES_DONE_WITH_BLOCK_MAP_VALUE,
|
||||
|
||||
// flow map
|
||||
ES_WAITING_FOR_FLOW_MAP_ENTRY,
|
||||
ES_WAITING_FOR_FLOW_MAP_KEY,
|
||||
ES_WRITING_FLOW_MAP_KEY,
|
||||
ES_DONE_WITH_FLOW_MAP_KEY,
|
||||
ES_WAITING_FOR_FLOW_MAP_VALUE,
|
||||
ES_WRITING_FLOW_MAP_VALUE,
|
||||
ES_DONE_WITH_FLOW_MAP_VALUE,
|
||||
};
|
||||
|
||||
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; }
|
||||
|
||||
// main state of the machine
|
||||
EMITTER_STATE GetCurState() const { return m_stateStack.top(); }
|
||||
void SwitchState(EMITTER_STATE state) { PopState(); PushState(state); }
|
||||
void PushState(EMITTER_STATE state) { m_stateStack.push(state); }
|
||||
void PopState() { m_stateStack.pop(); }
|
||||
|
||||
void SetLocalValue(EMITTER_MANIP value);
|
||||
|
||||
// group handling
|
||||
void BeginGroup(GROUP_TYPE type);
|
||||
void EndGroup(GROUP_TYPE type);
|
||||
|
||||
GROUP_TYPE GetCurGroupType() const;
|
||||
FLOW_TYPE GetCurGroupFlowType() const;
|
||||
int GetCurIndent() const { return m_curIndent; }
|
||||
|
||||
bool CurrentlyInLongKey();
|
||||
void StartLongKey();
|
||||
void StartSimpleKey();
|
||||
|
||||
bool RequiresSeparation() const { return m_requiresSeparation; }
|
||||
void RequireSeparation() { m_requiresSeparation = true; }
|
||||
void UnsetSeparation() { m_requiresSeparation = false; }
|
||||
|
||||
void ClearModifiedSettings();
|
||||
|
||||
// formatters
|
||||
bool SetStringFormat(EMITTER_MANIP value, FMT_SCOPE scope);
|
||||
EMITTER_MANIP GetStringFormat() const { return m_strFmt.get(); }
|
||||
|
||||
bool SetBoolFormat(EMITTER_MANIP value, FMT_SCOPE scope);
|
||||
EMITTER_MANIP GetBoolFormat() const { return m_boolFmt.get(); }
|
||||
|
||||
bool SetBoolLengthFormat(EMITTER_MANIP value, FMT_SCOPE scope);
|
||||
EMITTER_MANIP GetBoolLengthFormat() const { return m_boolLengthFmt.get(); }
|
||||
|
||||
bool SetBoolCaseFormat(EMITTER_MANIP value, FMT_SCOPE scope);
|
||||
EMITTER_MANIP GetBoolCaseFormat() const { return m_boolCaseFmt.get(); }
|
||||
|
||||
bool SetIntFormat(EMITTER_MANIP value, FMT_SCOPE scope);
|
||||
EMITTER_MANIP GetIntFormat() const { return m_intFmt.get(); }
|
||||
|
||||
bool SetIndent(unsigned value, FMT_SCOPE scope);
|
||||
int GetIndent() const { return m_indent.get(); }
|
||||
|
||||
bool SetPreCommentIndent(unsigned value, FMT_SCOPE scope);
|
||||
int GetPreCommentIndent() const { return m_preCommentIndent.get(); }
|
||||
bool SetPostCommentIndent(unsigned value, FMT_SCOPE scope);
|
||||
int GetPostCommentIndent() const { return m_postCommentIndent.get(); }
|
||||
|
||||
bool SetFlowType(GROUP_TYPE groupType, EMITTER_MANIP value, FMT_SCOPE scope);
|
||||
EMITTER_MANIP GetFlowType(GROUP_TYPE groupType) const;
|
||||
|
||||
bool SetMapKeyFormat(EMITTER_MANIP value, FMT_SCOPE scope);
|
||||
EMITTER_MANIP GetMapKeyFormat() const { return m_mapKeyFmt.get(); }
|
||||
|
||||
private:
|
||||
template <typename T>
|
||||
void _Set(Setting<T>& fmt, T value, FMT_SCOPE scope);
|
||||
|
||||
private:
|
||||
// basic state ok?
|
||||
bool m_isGood;
|
||||
std::string m_lastError;
|
||||
|
||||
// other state
|
||||
std::stack <EMITTER_STATE> m_stateStack;
|
||||
|
||||
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;
|
||||
Setting <unsigned> m_indent;
|
||||
Setting <unsigned> m_preCommentIndent, m_postCommentIndent;
|
||||
Setting <EMITTER_MANIP> m_seqFmt;
|
||||
Setting <EMITTER_MANIP> m_mapFmt;
|
||||
Setting <EMITTER_MANIP> m_mapKeyFmt;
|
||||
|
||||
SettingChanges m_modifiedSettings;
|
||||
SettingChanges m_globalModifiedSettings;
|
||||
|
||||
struct Group {
|
||||
Group(GROUP_TYPE type_): type(type_), usingLongKey(false), indent(0) {}
|
||||
|
||||
GROUP_TYPE type;
|
||||
EMITTER_MANIP flow;
|
||||
bool usingLongKey;
|
||||
int indent;
|
||||
|
||||
SettingChanges modifiedSettings;
|
||||
};
|
||||
|
||||
std::auto_ptr <Group> _PopGroup();
|
||||
|
||||
std::stack <Group *> m_groups;
|
||||
unsigned m_curIndent;
|
||||
bool m_requiresSeparation;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
void EmitterState::_Set(Setting<T>& fmt, T value, FMT_SCOPE scope) {
|
||||
switch(scope) {
|
||||
case LOCAL:
|
||||
m_modifiedSettings.push(fmt.set(value));
|
||||
break;
|
||||
case 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);
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user