summaryrefslogtreecommitdiffstats
path: root/yaml-cpp/src/emitterstate.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'yaml-cpp/src/emitterstate.cpp')
-rwxr-xr-xyaml-cpp/src/emitterstate.cpp284
1 files changed, 284 insertions, 0 deletions
diff --git a/yaml-cpp/src/emitterstate.cpp b/yaml-cpp/src/emitterstate.cpp
new file mode 100755
index 00000000..562e82c9
--- /dev/null
+++ b/yaml-cpp/src/emitterstate.cpp
@@ -0,0 +1,284 @@
+#include "emitterstate.h"
+#include "yaml-cpp/exceptions.h"
+#include <limits>
+
+namespace YAML
+{
+ EmitterState::EmitterState(): m_isGood(true), m_curIndent(0), m_requiresSoftSeparation(false), m_requiresHardSeparation(false)
+ {
+ // start up
+ m_stateStack.push(ES_WAITING_FOR_DOC);
+
+ // set default global manipulators
+ m_charset.set(EmitNonAscii);
+ m_strFmt.set(Auto);
+ m_boolFmt.set(TrueFalseBool);
+ m_boolLengthFmt.set(LongBool);
+ m_boolCaseFmt.set(LowerCase);
+ m_intFmt.set(Dec);
+ m_indent.set(2);
+ m_preCommentIndent.set(2);
+ m_postCommentIndent.set(1);
+ m_seqFmt.set(Block);
+ m_mapFmt.set(Block);
+ m_mapKeyFmt.set(Auto);
+ m_floatPrecision.set(6);
+ m_doublePrecision.set(15);
+ }
+
+ EmitterState::~EmitterState()
+ {
+ }
+
+ // SetLocalValue
+ // . We blindly tries to set all possible formatters to this value
+ // . Only the ones that make sense will be accepted
+ void EmitterState::SetLocalValue(EMITTER_MANIP value)
+ {
+ SetOutputCharset(value, LOCAL);
+ SetStringFormat(value, LOCAL);
+ SetBoolFormat(value, LOCAL);
+ SetBoolCaseFormat(value, LOCAL);
+ SetBoolLengthFormat(value, LOCAL);
+ SetIntFormat(value, LOCAL);
+ SetFlowType(GT_SEQ, value, LOCAL);
+ SetFlowType(GT_MAP, value, LOCAL);
+ SetMapKeyFormat(value, LOCAL);
+ }
+
+ void EmitterState::BeginGroup(GROUP_TYPE type)
+ {
+ unsigned lastIndent = (m_groups.empty() ? 0 : m_groups.top().indent);
+ m_curIndent += lastIndent;
+
+ std::auto_ptr<Group> pGroup(new Group(type));
+
+ // transfer settings (which last until this group is done)
+ pGroup->modifiedSettings = m_modifiedSettings;
+
+ // set up group
+ pGroup->flow = GetFlowType(type);
+ pGroup->indent = GetIndent();
+ pGroup->usingLongKey = (GetMapKeyFormat() == LongKey ? true : false);
+
+ m_groups.push(pGroup);
+ }
+
+ void EmitterState::EndGroup(GROUP_TYPE type)
+ {
+ if(m_groups.empty())
+ return SetError(ErrorMsg::UNMATCHED_GROUP_TAG);
+
+ // get rid of the current group
+ {
+ std::auto_ptr<Group> pFinishedGroup = m_groups.pop();
+ if(pFinishedGroup->type != type)
+ return SetError(ErrorMsg::UNMATCHED_GROUP_TAG);
+ }
+
+ // reset old settings
+ unsigned lastIndent = (m_groups.empty() ? 0 : m_groups.top().indent);
+ assert(m_curIndent >= lastIndent);
+ m_curIndent -= lastIndent;
+
+ // some global settings that we changed may have been overridden
+ // by a local setting we just popped, so we need to restore them
+ m_globalModifiedSettings.restore();
+ }
+
+ GROUP_TYPE EmitterState::GetCurGroupType() const
+ {
+ if(m_groups.empty())
+ return GT_NONE;
+
+ return m_groups.top().type;
+ }
+
+ FLOW_TYPE EmitterState::GetCurGroupFlowType() const
+ {
+ if(m_groups.empty())
+ return FT_NONE;
+
+ return (m_groups.top().flow == Flow ? FT_FLOW : FT_BLOCK);
+ }
+
+ bool EmitterState::CurrentlyInLongKey()
+ {
+ if(m_groups.empty())
+ return false;
+ return m_groups.top().usingLongKey;
+ }
+
+ void EmitterState::StartLongKey()
+ {
+ if(!m_groups.empty())
+ m_groups.top().usingLongKey = true;
+ }
+
+ void EmitterState::StartSimpleKey()
+ {
+ if(!m_groups.empty())
+ m_groups.top().usingLongKey = false;
+ }
+
+ void EmitterState::ClearModifiedSettings()
+ {
+ m_modifiedSettings.clear();
+ }
+
+ bool EmitterState::SetOutputCharset(EMITTER_MANIP value, FMT_SCOPE scope)
+ {
+ switch(value) {
+ case EmitNonAscii:
+ case EscapeNonAscii:
+ _Set(m_charset, value, scope);
+ return true;
+ default:
+ return false;
+ }
+ }
+
+ bool EmitterState::SetStringFormat(EMITTER_MANIP value, FMT_SCOPE scope)
+ {
+ switch(value) {
+ case Auto:
+ case SingleQuoted:
+ case DoubleQuoted:
+ case Literal:
+ _Set(m_strFmt, value, scope);
+ return true;
+ default:
+ return false;
+ }
+ }
+
+ bool EmitterState::SetBoolFormat(EMITTER_MANIP value, FMT_SCOPE scope)
+ {
+ switch(value) {
+ case OnOffBool:
+ case TrueFalseBool:
+ case YesNoBool:
+ _Set(m_boolFmt, value, scope);
+ return true;
+ default:
+ return false;
+ }
+ }
+
+ bool EmitterState::SetBoolLengthFormat(EMITTER_MANIP value, FMT_SCOPE scope)
+ {
+ switch(value) {
+ case LongBool:
+ case ShortBool:
+ _Set(m_boolLengthFmt, value, scope);
+ return true;
+ default:
+ return false;
+ }
+ }
+
+ bool EmitterState::SetBoolCaseFormat(EMITTER_MANIP value, FMT_SCOPE scope)
+ {
+ switch(value) {
+ case UpperCase:
+ case LowerCase:
+ case CamelCase:
+ _Set(m_boolCaseFmt, value, scope);
+ return true;
+ default:
+ return false;
+ }
+ }
+
+ bool EmitterState::SetIntFormat(EMITTER_MANIP value, FMT_SCOPE scope)
+ {
+ switch(value) {
+ case Dec:
+ case Hex:
+ case Oct:
+ _Set(m_intFmt, value, scope);
+ return true;
+ default:
+ return false;
+ }
+ }
+
+ bool EmitterState::SetIndent(unsigned value, FMT_SCOPE scope)
+ {
+ if(value == 0)
+ return false;
+
+ _Set(m_indent, value, scope);
+ return true;
+ }
+
+ bool EmitterState::SetPreCommentIndent(unsigned value, FMT_SCOPE scope)
+ {
+ if(value == 0)
+ return false;
+
+ _Set(m_preCommentIndent, value, scope);
+ return true;
+ }
+
+ bool EmitterState::SetPostCommentIndent(unsigned value, FMT_SCOPE scope)
+ {
+ if(value == 0)
+ return false;
+
+ _Set(m_postCommentIndent, value, scope);
+ return true;
+ }
+
+ bool EmitterState::SetFlowType(GROUP_TYPE groupType, EMITTER_MANIP value, FMT_SCOPE scope)
+ {
+ switch(value) {
+ case Block:
+ case Flow:
+ _Set(groupType == GT_SEQ ? m_seqFmt : m_mapFmt, value, scope);
+ return true;
+ default:
+ return false;
+ }
+ }
+
+ EMITTER_MANIP EmitterState::GetFlowType(GROUP_TYPE groupType) const
+ {
+ // force flow style if we're currently in a flow
+ FLOW_TYPE flowType = GetCurGroupFlowType();
+ if(flowType == FT_FLOW)
+ return Flow;
+
+ // otherwise, go with what's asked of use
+ return (groupType == GT_SEQ ? m_seqFmt.get() : m_mapFmt.get());
+ }
+
+ bool EmitterState::SetMapKeyFormat(EMITTER_MANIP value, FMT_SCOPE scope)
+ {
+ switch(value) {
+ case Auto:
+ case LongKey:
+ _Set(m_mapKeyFmt, value, scope);
+ return true;
+ default:
+ return false;
+ }
+ }
+
+ bool EmitterState::SetFloatPrecision(int value, FMT_SCOPE scope)
+ {
+ if(value < 0 || value > std::numeric_limits<float>::digits10)
+ return false;
+ _Set(m_floatPrecision, value, scope);
+ return true;
+ }
+
+ bool EmitterState::SetDoublePrecision(int value, FMT_SCOPE scope)
+ {
+ if(value < 0 || value > std::numeric_limits<double>::digits10)
+ return false;
+ _Set(m_doublePrecision, value, scope);
+ return true;
+ }
+}
+