00001 #include "emitterstate.h"
00002 #include "yaml-cpp-pm/exceptions.h"
00003 #include <limits>
00004
00005 namespace YAML_PM
00006 {
00007 EmitterState::EmitterState(): m_isGood(true), m_curIndent(0), m_requiresSoftSeparation(false), m_requiresHardSeparation(false)
00008 {
00009
00010 m_stateStack.push(ES_WAITING_FOR_DOC);
00011
00012
00013 m_charset.set(EmitNonAscii);
00014 m_strFmt.set(Auto);
00015 m_boolFmt.set(TrueFalseBool);
00016 m_boolLengthFmt.set(LongBool);
00017 m_boolCaseFmt.set(LowerCase);
00018 m_intFmt.set(Dec);
00019 m_indent.set(2);
00020 m_preCommentIndent.set(2);
00021 m_postCommentIndent.set(1);
00022 m_seqFmt.set(Block);
00023 m_mapFmt.set(Block);
00024 m_mapKeyFmt.set(Auto);
00025 m_floatPrecision.set(6);
00026 m_doublePrecision.set(15);
00027 }
00028
00029 EmitterState::~EmitterState()
00030 {
00031 }
00032
00033
00034
00035
00036 void EmitterState::SetLocalValue(EMITTER_MANIP value)
00037 {
00038 SetOutputCharset(value, LOCAL);
00039 SetStringFormat(value, LOCAL);
00040 SetBoolFormat(value, LOCAL);
00041 SetBoolCaseFormat(value, LOCAL);
00042 SetBoolLengthFormat(value, LOCAL);
00043 SetIntFormat(value, LOCAL);
00044 SetFlowType(GT_SEQ, value, LOCAL);
00045 SetFlowType(GT_MAP, value, LOCAL);
00046 SetMapKeyFormat(value, LOCAL);
00047 }
00048
00049 void EmitterState::BeginGroup(GROUP_TYPE type)
00050 {
00051 unsigned lastIndent = (m_groups.empty() ? 0 : m_groups.top().indent);
00052 m_curIndent += lastIndent;
00053
00054 std::auto_ptr<Group> pGroup(new Group(type));
00055
00056
00057 pGroup->modifiedSettings = m_modifiedSettings;
00058
00059
00060 pGroup->flow = GetFlowType(type);
00061 pGroup->indent = GetIndent();
00062 pGroup->usingLongKey = (GetMapKeyFormat() == LongKey ? true : false);
00063
00064 m_groups.push(pGroup);
00065 }
00066
00067 void EmitterState::EndGroup(GROUP_TYPE type)
00068 {
00069 if(m_groups.empty())
00070 return SetError(ErrorMsg::UNMATCHED_GROUP_TAG);
00071
00072
00073 {
00074 std::auto_ptr<Group> pFinishedGroup = m_groups.pop();
00075 if(pFinishedGroup->type != type)
00076 return SetError(ErrorMsg::UNMATCHED_GROUP_TAG);
00077 }
00078
00079
00080 unsigned lastIndent = (m_groups.empty() ? 0 : m_groups.top().indent);
00081 assert(m_curIndent >= lastIndent);
00082 m_curIndent -= lastIndent;
00083
00084
00085
00086 m_globalModifiedSettings.restore();
00087 }
00088
00089 GROUP_TYPE EmitterState::GetCurGroupType() const
00090 {
00091 if(m_groups.empty())
00092 return GT_NONE;
00093
00094 return m_groups.top().type;
00095 }
00096
00097 FLOW_TYPE EmitterState::GetCurGroupFlowType() const
00098 {
00099 if(m_groups.empty())
00100 return FT_NONE;
00101
00102 return (m_groups.top().flow == Flow ? FT_FLOW : FT_BLOCK);
00103 }
00104
00105 bool EmitterState::CurrentlyInLongKey()
00106 {
00107 if(m_groups.empty())
00108 return false;
00109 return m_groups.top().usingLongKey;
00110 }
00111
00112 void EmitterState::StartLongKey()
00113 {
00114 if(!m_groups.empty())
00115 m_groups.top().usingLongKey = true;
00116 }
00117
00118 void EmitterState::StartSimpleKey()
00119 {
00120 if(!m_groups.empty())
00121 m_groups.top().usingLongKey = false;
00122 }
00123
00124 void EmitterState::ClearModifiedSettings()
00125 {
00126 m_modifiedSettings.clear();
00127 }
00128
00129 bool EmitterState::SetOutputCharset(EMITTER_MANIP value, FMT_SCOPE scope)
00130 {
00131 switch(value) {
00132 case EmitNonAscii:
00133 case EscapeNonAscii:
00134 _Set(m_charset, value, scope);
00135 return true;
00136 default:
00137 return false;
00138 }
00139 }
00140
00141 bool EmitterState::SetStringFormat(EMITTER_MANIP value, FMT_SCOPE scope)
00142 {
00143 switch(value) {
00144 case Auto:
00145 case SingleQuoted:
00146 case DoubleQuoted:
00147 case Literal:
00148 _Set(m_strFmt, value, scope);
00149 return true;
00150 default:
00151 return false;
00152 }
00153 }
00154
00155 bool EmitterState::SetBoolFormat(EMITTER_MANIP value, FMT_SCOPE scope)
00156 {
00157 switch(value) {
00158 case OnOffBool:
00159 case TrueFalseBool:
00160 case YesNoBool:
00161 _Set(m_boolFmt, value, scope);
00162 return true;
00163 default:
00164 return false;
00165 }
00166 }
00167
00168 bool EmitterState::SetBoolLengthFormat(EMITTER_MANIP value, FMT_SCOPE scope)
00169 {
00170 switch(value) {
00171 case LongBool:
00172 case ShortBool:
00173 _Set(m_boolLengthFmt, value, scope);
00174 return true;
00175 default:
00176 return false;
00177 }
00178 }
00179
00180 bool EmitterState::SetBoolCaseFormat(EMITTER_MANIP value, FMT_SCOPE scope)
00181 {
00182 switch(value) {
00183 case UpperCase:
00184 case LowerCase:
00185 case CamelCase:
00186 _Set(m_boolCaseFmt, value, scope);
00187 return true;
00188 default:
00189 return false;
00190 }
00191 }
00192
00193 bool EmitterState::SetIntFormat(EMITTER_MANIP value, FMT_SCOPE scope)
00194 {
00195 switch(value) {
00196 case Dec:
00197 case Hex:
00198 case Oct:
00199 _Set(m_intFmt, value, scope);
00200 return true;
00201 default:
00202 return false;
00203 }
00204 }
00205
00206 bool EmitterState::SetIndent(unsigned value, FMT_SCOPE scope)
00207 {
00208 if(value == 0)
00209 return false;
00210
00211 _Set(m_indent, value, scope);
00212 return true;
00213 }
00214
00215 bool EmitterState::SetPreCommentIndent(unsigned value, FMT_SCOPE scope)
00216 {
00217 if(value == 0)
00218 return false;
00219
00220 _Set(m_preCommentIndent, value, scope);
00221 return true;
00222 }
00223
00224 bool EmitterState::SetPostCommentIndent(unsigned value, FMT_SCOPE scope)
00225 {
00226 if(value == 0)
00227 return false;
00228
00229 _Set(m_postCommentIndent, value, scope);
00230 return true;
00231 }
00232
00233 bool EmitterState::SetFlowType(GROUP_TYPE groupType, EMITTER_MANIP value, FMT_SCOPE scope)
00234 {
00235 switch(value) {
00236 case Block:
00237 case Flow:
00238 _Set(groupType == GT_SEQ ? m_seqFmt : m_mapFmt, value, scope);
00239 return true;
00240 default:
00241 return false;
00242 }
00243 }
00244
00245 EMITTER_MANIP EmitterState::GetFlowType(GROUP_TYPE groupType) const
00246 {
00247
00248 FLOW_TYPE flowType = GetCurGroupFlowType();
00249 if(flowType == FT_FLOW)
00250 return Flow;
00251
00252
00253 return (groupType == GT_SEQ ? m_seqFmt.get() : m_mapFmt.get());
00254 }
00255
00256 bool EmitterState::SetMapKeyFormat(EMITTER_MANIP value, FMT_SCOPE scope)
00257 {
00258 switch(value) {
00259 case Auto:
00260 case LongKey:
00261 _Set(m_mapKeyFmt, value, scope);
00262 return true;
00263 default:
00264 return false;
00265 }
00266 }
00267
00268 bool EmitterState::SetFloatPrecision(int value, FMT_SCOPE scope)
00269 {
00270 if(value < 0 || value > std::numeric_limits<float>::digits10)
00271 return false;
00272 _Set(m_floatPrecision, value, scope);
00273 return true;
00274 }
00275
00276 bool EmitterState::SetDoublePrecision(int value, FMT_SCOPE scope)
00277 {
00278 if(value < 0 || value > std::numeric_limits<double>::digits10)
00279 return false;
00280 _Set(m_doublePrecision, value, scope);
00281 return true;
00282 }
00283 }
00284