123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972 |
- #include <sstream>
- #include "emitterutils.h"
- #include "indentation.h" // IWYU pragma: keep
- #include "yaml-cpp/emitter.h"
- #include "yaml-cpp/emitterdef.h"
- #include "yaml-cpp/emittermanip.h"
- #include "yaml-cpp/exceptions.h" // IWYU pragma: keep
- namespace YAML {
- class Binary;
- struct _Null;
- Emitter::Emitter() : m_pState(new EmitterState), m_stream{} {}
- Emitter::Emitter(std::ostream& stream)
- : m_pState(new EmitterState), m_stream(stream) {}
- Emitter::~Emitter() = default;
- const char* Emitter::c_str() const { return m_stream.str(); }
- std::size_t Emitter::size() const { return m_stream.pos(); }
- // state checking
- bool Emitter::good() const { return m_pState->good(); }
- const std::string Emitter::GetLastError() const {
- return m_pState->GetLastError();
- }
- // global setters
- bool Emitter::SetOutputCharset(EMITTER_MANIP value) {
- return m_pState->SetOutputCharset(value, FmtScope::Global);
- }
- bool Emitter::SetStringFormat(EMITTER_MANIP value) {
- return m_pState->SetStringFormat(value, FmtScope::Global);
- }
- bool Emitter::SetBoolFormat(EMITTER_MANIP value) {
- bool ok = false;
- if (m_pState->SetBoolFormat(value, FmtScope::Global))
- ok = true;
- if (m_pState->SetBoolCaseFormat(value, FmtScope::Global))
- ok = true;
- if (m_pState->SetBoolLengthFormat(value, FmtScope::Global))
- ok = true;
- return ok;
- }
- bool Emitter::SetNullFormat(EMITTER_MANIP value) {
- return m_pState->SetNullFormat(value, FmtScope::Global);
- }
- bool Emitter::SetIntBase(EMITTER_MANIP value) {
- return m_pState->SetIntFormat(value, FmtScope::Global);
- }
- bool Emitter::SetSeqFormat(EMITTER_MANIP value) {
- return m_pState->SetFlowType(GroupType::Seq, value, FmtScope::Global);
- }
- bool Emitter::SetMapFormat(EMITTER_MANIP value) {
- bool ok = false;
- if (m_pState->SetFlowType(GroupType::Map, value, FmtScope::Global))
- ok = true;
- if (m_pState->SetMapKeyFormat(value, FmtScope::Global))
- ok = true;
- return ok;
- }
- bool Emitter::SetIndent(std::size_t n) {
- return m_pState->SetIndent(n, FmtScope::Global);
- }
- bool Emitter::SetPreCommentIndent(std::size_t n) {
- return m_pState->SetPreCommentIndent(n, FmtScope::Global);
- }
- bool Emitter::SetPostCommentIndent(std::size_t n) {
- return m_pState->SetPostCommentIndent(n, FmtScope::Global);
- }
- bool Emitter::SetFloatPrecision(std::size_t n) {
- return m_pState->SetFloatPrecision(n, FmtScope::Global);
- }
- bool Emitter::SetDoublePrecision(std::size_t n) {
- return m_pState->SetDoublePrecision(n, FmtScope::Global);
- }
- void Emitter::RestoreGlobalModifiedSettings() {
- m_pState->RestoreGlobalModifiedSettings();
- }
- // SetLocalValue
- // . Either start/end a group, or set a modifier locally
- Emitter& Emitter::SetLocalValue(EMITTER_MANIP value) {
- if (!good())
- return *this;
- switch (value) {
- case BeginDoc:
- EmitBeginDoc();
- break;
- case EndDoc:
- EmitEndDoc();
- break;
- case BeginSeq:
- EmitBeginSeq();
- break;
- case EndSeq:
- EmitEndSeq();
- break;
- case BeginMap:
- EmitBeginMap();
- break;
- case EndMap:
- EmitEndMap();
- break;
- case Key:
- case Value:
- // deprecated (these can be deduced by the parity of nodes in a map)
- break;
- case TagByKind:
- EmitKindTag();
- break;
- case Newline:
- EmitNewline();
- break;
- default:
- m_pState->SetLocalValue(value);
- break;
- }
- return *this;
- }
- Emitter& Emitter::SetLocalIndent(const _Indent& indent) {
- m_pState->SetIndent(indent.value, FmtScope::Local);
- return *this;
- }
- Emitter& Emitter::SetLocalPrecision(const _Precision& precision) {
- if (precision.floatPrecision >= 0)
- m_pState->SetFloatPrecision(precision.floatPrecision, FmtScope::Local);
- if (precision.doublePrecision >= 0)
- m_pState->SetDoublePrecision(precision.doublePrecision, FmtScope::Local);
- return *this;
- }
- // EmitBeginDoc
- void Emitter::EmitBeginDoc() {
- if (!good())
- return;
- if (m_pState->CurGroupType() != GroupType::NoType) {
- m_pState->SetError("Unexpected begin document");
- return;
- }
- if (m_pState->HasAnchor() || m_pState->HasTag()) {
- m_pState->SetError("Unexpected begin document");
- return;
- }
- if (m_stream.col() > 0)
- m_stream << "\n";
- m_stream << "---\n";
- m_pState->StartedDoc();
- }
- // EmitEndDoc
- void Emitter::EmitEndDoc() {
- if (!good())
- return;
- if (m_pState->CurGroupType() != GroupType::NoType) {
- m_pState->SetError("Unexpected begin document");
- return;
- }
- if (m_pState->HasAnchor() || m_pState->HasTag()) {
- m_pState->SetError("Unexpected begin document");
- return;
- }
- if (m_stream.col() > 0)
- m_stream << "\n";
- m_stream << "...\n";
- }
- // EmitBeginSeq
- void Emitter::EmitBeginSeq() {
- if (!good())
- return;
- PrepareNode(m_pState->NextGroupType(GroupType::Seq));
- m_pState->StartedGroup(GroupType::Seq);
- }
- // EmitEndSeq
- void Emitter::EmitEndSeq() {
- if (!good())
- return;
- FlowType::value originalType = m_pState->CurGroupFlowType();
- if (m_pState->CurGroupChildCount() == 0)
- m_pState->ForceFlow();
- if (m_pState->CurGroupFlowType() == FlowType::Flow) {
- if (m_stream.comment())
- m_stream << "\n";
- m_stream << IndentTo(m_pState->CurIndent());
- if (originalType == FlowType::Block) {
- m_stream << "[";
- } else {
- if (m_pState->CurGroupChildCount() == 0 && !m_pState->HasBegunNode())
- m_stream << "[";
- }
- m_stream << "]";
- }
- m_pState->EndedGroup(GroupType::Seq);
- }
- // EmitBeginMap
- void Emitter::EmitBeginMap() {
- if (!good())
- return;
- PrepareNode(m_pState->NextGroupType(GroupType::Map));
- m_pState->StartedGroup(GroupType::Map);
- }
- // EmitEndMap
- void Emitter::EmitEndMap() {
- if (!good())
- return;
- FlowType::value originalType = m_pState->CurGroupFlowType();
- if (m_pState->CurGroupChildCount() == 0)
- m_pState->ForceFlow();
- if (m_pState->CurGroupFlowType() == FlowType::Flow) {
- if (m_stream.comment())
- m_stream << "\n";
- m_stream << IndentTo(m_pState->CurIndent());
- if (originalType == FlowType::Block) {
- m_stream << "{";
- } else {
- if (m_pState->CurGroupChildCount() == 0 && !m_pState->HasBegunNode())
- m_stream << "{";
- }
- m_stream << "}";
- }
- m_pState->EndedGroup(GroupType::Map);
- }
- // EmitNewline
- void Emitter::EmitNewline() {
- if (!good())
- return;
- PrepareNode(EmitterNodeType::NoType);
- m_stream << "\n";
- m_pState->SetNonContent();
- }
- bool Emitter::CanEmitNewline() const { return true; }
- // Put the stream in a state so we can simply write the next node
- // E.g., if we're in a sequence, write the "- "
- void Emitter::PrepareNode(EmitterNodeType::value child) {
- switch (m_pState->CurGroupNodeType()) {
- case EmitterNodeType::NoType:
- PrepareTopNode(child);
- break;
- case EmitterNodeType::FlowSeq:
- FlowSeqPrepareNode(child);
- break;
- case EmitterNodeType::BlockSeq:
- BlockSeqPrepareNode(child);
- break;
- case EmitterNodeType::FlowMap:
- FlowMapPrepareNode(child);
- break;
- case EmitterNodeType::BlockMap:
- BlockMapPrepareNode(child);
- break;
- case EmitterNodeType::Property:
- case EmitterNodeType::Scalar:
- assert(false);
- break;
- }
- }
- void Emitter::PrepareTopNode(EmitterNodeType::value child) {
- if (child == EmitterNodeType::NoType)
- return;
- if (m_pState->CurGroupChildCount() > 0 && m_stream.col() > 0)
- EmitBeginDoc();
- switch (child) {
- case EmitterNodeType::NoType:
- break;
- case EmitterNodeType::Property:
- case EmitterNodeType::Scalar:
- case EmitterNodeType::FlowSeq:
- case EmitterNodeType::FlowMap:
- // TODO: if we were writing null, and
- // we wanted it blank, we wouldn't want a space
- SpaceOrIndentTo(m_pState->HasBegunContent(), 0);
- break;
- case EmitterNodeType::BlockSeq:
- case EmitterNodeType::BlockMap:
- if (m_pState->HasBegunNode())
- m_stream << "\n";
- break;
- }
- }
- void Emitter::FlowSeqPrepareNode(EmitterNodeType::value child) {
- const std::size_t lastIndent = m_pState->LastIndent();
- if (!m_pState->HasBegunNode()) {
- if (m_stream.comment())
- m_stream << "\n";
- m_stream << IndentTo(lastIndent);
- if (m_pState->CurGroupChildCount() == 0)
- m_stream << "[";
- else
- m_stream << ",";
- }
- switch (child) {
- case EmitterNodeType::NoType:
- break;
- case EmitterNodeType::Property:
- case EmitterNodeType::Scalar:
- case EmitterNodeType::FlowSeq:
- case EmitterNodeType::FlowMap:
- SpaceOrIndentTo(
- m_pState->HasBegunContent() || m_pState->CurGroupChildCount() > 0,
- lastIndent);
- break;
- case EmitterNodeType::BlockSeq:
- case EmitterNodeType::BlockMap:
- assert(false);
- break;
- }
- }
- void Emitter::BlockSeqPrepareNode(EmitterNodeType::value child) {
- const std::size_t curIndent = m_pState->CurIndent();
- const std::size_t nextIndent = curIndent + m_pState->CurGroupIndent();
- if (child == EmitterNodeType::NoType)
- return;
- if (!m_pState->HasBegunContent()) {
- if (m_pState->CurGroupChildCount() > 0 || m_stream.comment()) {
- m_stream << "\n";
- }
- m_stream << IndentTo(curIndent);
- m_stream << "-";
- }
- switch (child) {
- case EmitterNodeType::NoType:
- break;
- case EmitterNodeType::Property:
- case EmitterNodeType::Scalar:
- case EmitterNodeType::FlowSeq:
- case EmitterNodeType::FlowMap:
- SpaceOrIndentTo(m_pState->HasBegunContent(), nextIndent);
- break;
- case EmitterNodeType::BlockSeq:
- m_stream << "\n";
- break;
- case EmitterNodeType::BlockMap:
- if (m_pState->HasBegunContent() || m_stream.comment())
- m_stream << "\n";
- break;
- }
- }
- void Emitter::FlowMapPrepareNode(EmitterNodeType::value child) {
- if (m_pState->CurGroupChildCount() % 2 == 0) {
- if (m_pState->GetMapKeyFormat() == LongKey)
- m_pState->SetLongKey();
- if (m_pState->CurGroupLongKey())
- FlowMapPrepareLongKey(child);
- else
- FlowMapPrepareSimpleKey(child);
- } else {
- if (m_pState->CurGroupLongKey())
- FlowMapPrepareLongKeyValue(child);
- else
- FlowMapPrepareSimpleKeyValue(child);
- }
- }
- void Emitter::FlowMapPrepareLongKey(EmitterNodeType::value child) {
- const std::size_t lastIndent = m_pState->LastIndent();
- if (!m_pState->HasBegunNode()) {
- if (m_stream.comment())
- m_stream << "\n";
- m_stream << IndentTo(lastIndent);
- if (m_pState->CurGroupChildCount() == 0)
- m_stream << "{ ?";
- else
- m_stream << ", ?";
- }
- switch (child) {
- case EmitterNodeType::NoType:
- break;
- case EmitterNodeType::Property:
- case EmitterNodeType::Scalar:
- case EmitterNodeType::FlowSeq:
- case EmitterNodeType::FlowMap:
- SpaceOrIndentTo(
- m_pState->HasBegunContent() || m_pState->CurGroupChildCount() > 0,
- lastIndent);
- break;
- case EmitterNodeType::BlockSeq:
- case EmitterNodeType::BlockMap:
- assert(false);
- break;
- }
- }
- void Emitter::FlowMapPrepareLongKeyValue(EmitterNodeType::value child) {
- const std::size_t lastIndent = m_pState->LastIndent();
- if (!m_pState->HasBegunNode()) {
- if (m_stream.comment())
- m_stream << "\n";
- m_stream << IndentTo(lastIndent);
- m_stream << ":";
- }
- switch (child) {
- case EmitterNodeType::NoType:
- break;
- case EmitterNodeType::Property:
- case EmitterNodeType::Scalar:
- case EmitterNodeType::FlowSeq:
- case EmitterNodeType::FlowMap:
- SpaceOrIndentTo(
- m_pState->HasBegunContent() || m_pState->CurGroupChildCount() > 0,
- lastIndent);
- break;
- case EmitterNodeType::BlockSeq:
- case EmitterNodeType::BlockMap:
- assert(false);
- break;
- }
- }
- void Emitter::FlowMapPrepareSimpleKey(EmitterNodeType::value child) {
- const std::size_t lastIndent = m_pState->LastIndent();
- if (!m_pState->HasBegunNode()) {
- if (m_stream.comment())
- m_stream << "\n";
- m_stream << IndentTo(lastIndent);
- if (m_pState->CurGroupChildCount() == 0)
- m_stream << "{";
- else
- m_stream << ",";
- }
- switch (child) {
- case EmitterNodeType::NoType:
- break;
- case EmitterNodeType::Property:
- case EmitterNodeType::Scalar:
- case EmitterNodeType::FlowSeq:
- case EmitterNodeType::FlowMap:
- SpaceOrIndentTo(
- m_pState->HasBegunContent() || m_pState->CurGroupChildCount() > 0,
- lastIndent);
- break;
- case EmitterNodeType::BlockSeq:
- case EmitterNodeType::BlockMap:
- assert(false);
- break;
- }
- }
- void Emitter::FlowMapPrepareSimpleKeyValue(EmitterNodeType::value child) {
- const std::size_t lastIndent = m_pState->LastIndent();
- if (!m_pState->HasBegunNode()) {
- if (m_stream.comment())
- m_stream << "\n";
- m_stream << IndentTo(lastIndent);
- if (m_pState->HasAlias()) {
- m_stream << " ";
- }
- m_stream << ":";
- }
- switch (child) {
- case EmitterNodeType::NoType:
- break;
- case EmitterNodeType::Property:
- case EmitterNodeType::Scalar:
- case EmitterNodeType::FlowSeq:
- case EmitterNodeType::FlowMap:
- SpaceOrIndentTo(
- m_pState->HasBegunContent() || m_pState->CurGroupChildCount() > 0,
- lastIndent);
- break;
- case EmitterNodeType::BlockSeq:
- case EmitterNodeType::BlockMap:
- assert(false);
- break;
- }
- }
- void Emitter::BlockMapPrepareNode(EmitterNodeType::value child) {
- if (m_pState->CurGroupChildCount() % 2 == 0) {
- if (m_pState->GetMapKeyFormat() == LongKey)
- m_pState->SetLongKey();
- if (child == EmitterNodeType::BlockSeq ||
- child == EmitterNodeType::BlockMap ||
- child == EmitterNodeType::Property)
- m_pState->SetLongKey();
- if (m_pState->CurGroupLongKey())
- BlockMapPrepareLongKey(child);
- else
- BlockMapPrepareSimpleKey(child);
- } else {
- if (m_pState->CurGroupLongKey())
- BlockMapPrepareLongKeyValue(child);
- else
- BlockMapPrepareSimpleKeyValue(child);
- }
- }
- void Emitter::BlockMapPrepareLongKey(EmitterNodeType::value child) {
- const std::size_t curIndent = m_pState->CurIndent();
- const std::size_t childCount = m_pState->CurGroupChildCount();
- if (child == EmitterNodeType::NoType)
- return;
- if (!m_pState->HasBegunContent()) {
- if (childCount > 0) {
- m_stream << "\n";
- }
- if (m_stream.comment()) {
- m_stream << "\n";
- }
- m_stream << IndentTo(curIndent);
- m_stream << "?";
- }
- switch (child) {
- case EmitterNodeType::NoType:
- break;
- case EmitterNodeType::Property:
- case EmitterNodeType::Scalar:
- case EmitterNodeType::FlowSeq:
- case EmitterNodeType::FlowMap:
- SpaceOrIndentTo(true, curIndent + 1);
- break;
- case EmitterNodeType::BlockSeq:
- case EmitterNodeType::BlockMap:
- if (m_pState->HasBegunContent())
- m_stream << "\n";
- break;
- }
- }
- void Emitter::BlockMapPrepareLongKeyValue(EmitterNodeType::value child) {
- const std::size_t curIndent = m_pState->CurIndent();
- if (child == EmitterNodeType::NoType)
- return;
- if (!m_pState->HasBegunContent()) {
- m_stream << "\n";
- m_stream << IndentTo(curIndent);
- m_stream << ":";
- }
- switch (child) {
- case EmitterNodeType::NoType:
- break;
- case EmitterNodeType::Property:
- case EmitterNodeType::Scalar:
- case EmitterNodeType::FlowSeq:
- case EmitterNodeType::FlowMap:
- SpaceOrIndentTo(true, curIndent + 1);
- break;
- case EmitterNodeType::BlockSeq:
- case EmitterNodeType::BlockMap:
- if (m_pState->HasBegunContent())
- m_stream << "\n";
- SpaceOrIndentTo(true, curIndent + 1);
- break;
- }
- }
- void Emitter::BlockMapPrepareSimpleKey(EmitterNodeType::value child) {
- const std::size_t curIndent = m_pState->CurIndent();
- const std::size_t childCount = m_pState->CurGroupChildCount();
- if (child == EmitterNodeType::NoType)
- return;
- if (!m_pState->HasBegunNode()) {
- if (childCount > 0) {
- m_stream << "\n";
- }
- }
- switch (child) {
- case EmitterNodeType::NoType:
- break;
- case EmitterNodeType::Property:
- case EmitterNodeType::Scalar:
- case EmitterNodeType::FlowSeq:
- case EmitterNodeType::FlowMap:
- SpaceOrIndentTo(m_pState->HasBegunContent(), curIndent);
- break;
- case EmitterNodeType::BlockSeq:
- case EmitterNodeType::BlockMap:
- break;
- }
- }
- void Emitter::BlockMapPrepareSimpleKeyValue(EmitterNodeType::value child) {
- const std::size_t curIndent = m_pState->CurIndent();
- const std::size_t nextIndent = curIndent + m_pState->CurGroupIndent();
- if (!m_pState->HasBegunNode()) {
- if (m_pState->HasAlias()) {
- m_stream << " ";
- }
- m_stream << ":";
- }
- switch (child) {
- case EmitterNodeType::NoType:
- break;
- case EmitterNodeType::Property:
- case EmitterNodeType::Scalar:
- case EmitterNodeType::FlowSeq:
- case EmitterNodeType::FlowMap:
- SpaceOrIndentTo(true, nextIndent);
- break;
- case EmitterNodeType::BlockSeq:
- case EmitterNodeType::BlockMap:
- m_stream << "\n";
- break;
- }
- }
- // SpaceOrIndentTo
- // . Prepares for some more content by proper spacing
- void Emitter::SpaceOrIndentTo(bool requireSpace, std::size_t indent) {
- if (m_stream.comment())
- m_stream << "\n";
- if (m_stream.col() > 0 && requireSpace)
- m_stream << " ";
- m_stream << IndentTo(indent);
- }
- void Emitter::PrepareIntegralStream(std::stringstream& stream) const {
- switch (m_pState->GetIntFormat()) {
- case Dec:
- stream << std::dec;
- break;
- case Hex:
- stream << "0x";
- stream << std::hex;
- break;
- case Oct:
- stream << "0";
- stream << std::oct;
- break;
- default:
- assert(false);
- }
- }
- void Emitter::StartedScalar() { m_pState->StartedScalar(); }
- // *******************************************************************************************
- // overloads of Write
- StringEscaping::value GetStringEscapingStyle(const EMITTER_MANIP emitterManip) {
- switch (emitterManip) {
- case EscapeNonAscii:
- return StringEscaping::NonAscii;
- case EscapeAsJson:
- return StringEscaping::JSON;
- default:
- return StringEscaping::None;
- break;
- }
- }
- Emitter& Emitter::Write(const std::string& str) {
- if (!good())
- return *this;
- StringEscaping::value stringEscaping = GetStringEscapingStyle(m_pState->GetOutputCharset());
- const StringFormat::value strFormat =
- Utils::ComputeStringFormat(str, m_pState->GetStringFormat(),
- m_pState->CurGroupFlowType(), stringEscaping == StringEscaping::NonAscii);
- if (strFormat == StringFormat::Literal || str.size() > 1024)
- m_pState->SetMapKeyFormat(YAML::LongKey, FmtScope::Local);
- PrepareNode(EmitterNodeType::Scalar);
- switch (strFormat) {
- case StringFormat::Plain:
- m_stream << str;
- break;
- case StringFormat::SingleQuoted:
- Utils::WriteSingleQuotedString(m_stream, str);
- break;
- case StringFormat::DoubleQuoted:
- Utils::WriteDoubleQuotedString(m_stream, str, stringEscaping);
- break;
- case StringFormat::Literal:
- Utils::WriteLiteralString(m_stream, str,
- m_pState->CurIndent() + m_pState->GetIndent());
- break;
- }
- StartedScalar();
- return *this;
- }
- std::size_t Emitter::GetFloatPrecision() const {
- return m_pState->GetFloatPrecision();
- }
- std::size_t Emitter::GetDoublePrecision() const {
- return m_pState->GetDoublePrecision();
- }
- const char* Emitter::ComputeFullBoolName(bool b) const {
- const EMITTER_MANIP mainFmt = (m_pState->GetBoolLengthFormat() == ShortBool
- ? YesNoBool
- : m_pState->GetBoolFormat());
- const EMITTER_MANIP caseFmt = m_pState->GetBoolCaseFormat();
- switch (mainFmt) {
- case YesNoBool:
- switch (caseFmt) {
- case UpperCase:
- return b ? "YES" : "NO";
- case CamelCase:
- return b ? "Yes" : "No";
- case LowerCase:
- return b ? "yes" : "no";
- default:
- break;
- }
- break;
- case OnOffBool:
- switch (caseFmt) {
- case UpperCase:
- return b ? "ON" : "OFF";
- case CamelCase:
- return b ? "On" : "Off";
- case LowerCase:
- return b ? "on" : "off";
- default:
- break;
- }
- break;
- case TrueFalseBool:
- switch (caseFmt) {
- case UpperCase:
- return b ? "TRUE" : "FALSE";
- case CamelCase:
- return b ? "True" : "False";
- case LowerCase:
- return b ? "true" : "false";
- default:
- break;
- }
- break;
- default:
- break;
- }
- return b ? "y" : "n"; // should never get here, but it can't hurt to give
- // these answers
- }
- const char* Emitter::ComputeNullName() const {
- switch (m_pState->GetNullFormat()) {
- case LowerNull:
- return "null";
- case UpperNull:
- return "NULL";
- case CamelNull:
- return "Null";
- case TildeNull:
- // fallthrough
- default:
- return "~";
- }
- }
- Emitter& Emitter::Write(bool b) {
- if (!good())
- return *this;
- PrepareNode(EmitterNodeType::Scalar);
- const char* name = ComputeFullBoolName(b);
- if (m_pState->GetBoolLengthFormat() == ShortBool)
- m_stream << name[0];
- else
- m_stream << name;
- StartedScalar();
- return *this;
- }
- Emitter& Emitter::Write(char ch) {
- if (!good())
- return *this;
- PrepareNode(EmitterNodeType::Scalar);
- Utils::WriteChar(m_stream, ch, GetStringEscapingStyle(m_pState->GetOutputCharset()));
- StartedScalar();
- return *this;
- }
- Emitter& Emitter::Write(const _Alias& alias) {
- if (!good())
- return *this;
- if (m_pState->HasAnchor() || m_pState->HasTag()) {
- m_pState->SetError(ErrorMsg::INVALID_ALIAS);
- return *this;
- }
- PrepareNode(EmitterNodeType::Scalar);
- if (!Utils::WriteAlias(m_stream, alias.content)) {
- m_pState->SetError(ErrorMsg::INVALID_ALIAS);
- return *this;
- }
- StartedScalar();
- m_pState->SetAlias();
- return *this;
- }
- Emitter& Emitter::Write(const _Anchor& anchor) {
- if (!good())
- return *this;
- if (m_pState->HasAnchor()) {
- m_pState->SetError(ErrorMsg::INVALID_ANCHOR);
- return *this;
- }
- PrepareNode(EmitterNodeType::Property);
- if (!Utils::WriteAnchor(m_stream, anchor.content)) {
- m_pState->SetError(ErrorMsg::INVALID_ANCHOR);
- return *this;
- }
- m_pState->SetAnchor();
- return *this;
- }
- Emitter& Emitter::Write(const _Tag& tag) {
- if (!good())
- return *this;
- if (m_pState->HasTag()) {
- m_pState->SetError(ErrorMsg::INVALID_TAG);
- return *this;
- }
- PrepareNode(EmitterNodeType::Property);
- bool success = false;
- if (tag.type == _Tag::Type::Verbatim)
- success = Utils::WriteTag(m_stream, tag.content, true);
- else if (tag.type == _Tag::Type::PrimaryHandle)
- success = Utils::WriteTag(m_stream, tag.content, false);
- else
- success = Utils::WriteTagWithPrefix(m_stream, tag.prefix, tag.content);
- if (!success) {
- m_pState->SetError(ErrorMsg::INVALID_TAG);
- return *this;
- }
- m_pState->SetTag();
- return *this;
- }
- void Emitter::EmitKindTag() { Write(LocalTag("")); }
- Emitter& Emitter::Write(const _Comment& comment) {
- if (!good())
- return *this;
- PrepareNode(EmitterNodeType::NoType);
- if (m_stream.col() > 0)
- m_stream << Indentation(m_pState->GetPreCommentIndent());
- Utils::WriteComment(m_stream, comment.content,
- m_pState->GetPostCommentIndent());
- m_pState->SetNonContent();
- return *this;
- }
- Emitter& Emitter::Write(const _Null& /*null*/) {
- if (!good())
- return *this;
- PrepareNode(EmitterNodeType::Scalar);
- m_stream << ComputeNullName();
- StartedScalar();
- return *this;
- }
- Emitter& Emitter::Write(const Binary& binary) {
- Write(SecondaryTag("binary"));
- if (!good())
- return *this;
- PrepareNode(EmitterNodeType::Scalar);
- Utils::WriteBinary(m_stream, binary);
- StartedScalar();
- return *this;
- }
- } // namespace YAML
|