// EmitEndMap void Emitter::EmitEndMap() { if(!good()) return; if(m_pState->GetCurGroupType() != GT_MAP) return m_pState->SetError(ErrorMsg::UNEXPECTED_END_MAP); EMITTER_STATE curState = m_pState->GetCurState(); FLOW_TYPE flowType = m_pState->GetCurGroupFlowType(); if(flowType == FT_BLOCK) { // Note: block sequences are *not* allowed to be empty, but we convert it // to a flow sequence if it is assert(curState == ES_DONE_WITH_BLOCK_MAP_VALUE || curState == ES_WAITING_FOR_BLOCK_MAP_ENTRY); if(curState == ES_WAITING_FOR_BLOCK_MAP_ENTRY) { // Note: only one of these will actually output anything for a given situation EmitSeparationIfNecessary(); unsigned curIndent = m_pState->GetCurIndent(); m_stream << IndentTo(curIndent); m_stream << "{}"; } } else if(flowType == FT_FLOW) { // Note: flow maps are allowed to be empty assert(curState == ES_DONE_WITH_FLOW_MAP_VALUE || curState == ES_WAITING_FOR_FLOW_MAP_ENTRY); m_stream << "}"; } else assert(false); m_pState->PopState(); m_pState->EndGroup(GT_MAP); PostAtomicWrite(); }
Emitter& Emitter::Write(int i) { if(!good()) return *this; PreAtomicWrite(); EmitSeparationIfNecessary(); EMITTER_MANIP intFmt = m_pState->GetIntFormat(); std::stringstream str; switch(intFmt) { case Dec: str << std::dec; break; case Hex: str << std::hex; break; case Oct: str << std::oct; break; default: assert(false); } str << i; m_stream << str.str(); PostAtomicWrite(); return *this; }
Emitter& Emitter::Write(const _Null& /*null*/) { if(!good()) return *this; PreAtomicWrite(); EmitSeparationIfNecessary(); m_stream << "~"; PostAtomicWrite(); return *this; }
Emitter& Emitter::Write(const Binary& binary) { Write(SecondaryTag("binary")); if(!good()) return *this; PreAtomicWrite(); EmitSeparationIfNecessary(); Utils::WriteBinary(m_stream, binary); PostAtomicWrite(); return *this; }
Emitter& Emitter::Write(char ch) { if(!good()) return *this; PreAtomicWrite(); EmitSeparationIfNecessary(); Utils::WriteChar(m_stream, ch); PostAtomicWrite(); return *this; }
Emitter& Emitter::Write(const _Alias& alias) { if(!good()) return *this; PreAtomicWrite(); EmitSeparationIfNecessary(); if(!Utils::WriteAlias(m_stream, alias.content)) { m_pState->SetError(ErrorMsg::INVALID_ALIAS); return *this; } PostAtomicWrite(); return *this; }
Emitter& Emitter::Write(double d) { if(!good()) return *this; PreAtomicWrite(); EmitSeparationIfNecessary(); std::stringstream str; str << d; m_stream << str.str(); PostAtomicWrite(); return *this; }
Emitter& Emitter::Write(bool b) { if(!good()) return *this; PreAtomicWrite(); EmitSeparationIfNecessary(); const char *name = ComputeFullBoolName(b); if(m_pState->GetBoolLengthFormat() == ShortBool) m_stream << name[0]; else m_stream << name; PostAtomicWrite(); return *this; }
Emitter& Emitter::Write(const std::string& str) { if(!good()) return *this; // literal scalars must use long keys if(m_pState->GetStringFormat() == Literal && m_pState->GetCurGroupFlowType() != FT_FLOW) m_pState->StartLongKey(); PreAtomicWrite(); EmitSeparationIfNecessary(); bool escapeNonAscii = m_pState->GetOutputCharset() == EscapeNonAscii; EMITTER_MANIP strFmt = m_pState->GetStringFormat(); FLOW_TYPE flowType = m_pState->GetCurGroupFlowType(); unsigned curIndent = m_pState->GetCurIndent(); switch(strFmt) { case Auto: Utils::WriteString(m_stream, str, flowType == FT_FLOW, escapeNonAscii); break; case SingleQuoted: if(!Utils::WriteSingleQuotedString(m_stream, str)) { m_pState->SetError(ErrorMsg::SINGLE_QUOTED_CHAR); return *this; } break; case DoubleQuoted: Utils::WriteDoubleQuotedString(m_stream, str, escapeNonAscii); break; case Literal: if(flowType == FT_FLOW) Utils::WriteString(m_stream, str, flowType == FT_FLOW, escapeNonAscii); else Utils::WriteLiteralString(m_stream, str, curIndent + m_pState->GetIndent()); break; default: assert(false); } PostAtomicWrite(); return *this; }
Emitter& Emitter::Write(bool b) { if(!good()) return *this; PreAtomicWrite(); EmitSeparationIfNecessary(); // set up all possible bools to write struct BoolName { std::string trueName, falseName; }; struct BoolFormatNames { BoolName upper, lower, camel; }; struct BoolTypes { BoolFormatNames yesNo, trueFalse, onOff; }; static const BoolTypes boolTypes = { { { "YES", "NO" }, { "yes", "no" }, { "Yes", "No" } }, { { "TRUE", "FALSE" }, { "true", "false" }, { "True", "False" } }, { { "ON", "OFF" }, { "on", "off" }, { "On", "Off" } } }; // select the right one EMITTER_MANIP boolFmt = m_pState->GetBoolFormat(); EMITTER_MANIP boolLengthFmt = m_pState->GetBoolLengthFormat(); EMITTER_MANIP boolCaseFmt = m_pState->GetBoolCaseFormat(); const BoolFormatNames& fmtNames = (boolFmt == YesNoBool ? boolTypes.yesNo : boolFmt == TrueFalseBool ? boolTypes.trueFalse : boolTypes.onOff); const BoolName& boolName = (boolCaseFmt == UpperCase ? fmtNames.upper : boolCaseFmt == LowerCase ? fmtNames.lower : fmtNames.camel); const std::string& name = (b ? boolName.trueName : boolName.falseName); // and say it! // TODO: should we disallow writing OnOffBool with ShortBool? (it'll just print "o" for both, which is silly) if(boolLengthFmt == ShortBool) m_stream << name[0]; else m_stream << name; PostAtomicWrite(); return *this; }
// EmitEndMap void Emitter::EmitEndMap() { if(!good()) return; if(m_pState->GetCurGroupType() != GT_MAP) return m_pState->SetError(ErrorMsg::UNEXPECTED_END_MAP); EMITTER_STATE curState = m_pState->GetCurState(); FLOW_TYPE flowType = m_pState->GetCurGroupFlowType(); if(flowType == FT_BLOCK) assert(curState == ES_DONE_WITH_BLOCK_MAP_VALUE); else if(flowType == FT_FLOW) { m_stream << "}"; // Note: flow maps are allowed to be empty assert(curState == ES_DONE_WITH_FLOW_MAP_VALUE || curState == ES_WAITING_FOR_FLOW_MAP_ENTRY); } else assert(false); m_pState->PopState(); m_pState->EndGroup(GT_MAP); PostAtomicWrite(); }
void Emitter::PostWriteIntegralType(const std::stringstream& str) { m_stream << str.str(); PostAtomicWrite(); }
void Emitter::PostWriteStreamable(const std::stringstream& str) { m_stream << str.str(); PostAtomicWrite(); }