void Emitter::PrepareTopNode(EmitterNodeType::value child) { if (child == EmitterNodeType::None) return; if (m_pState->CurGroupChildCount() > 0 && m_stream.col() > 0) { if (child != EmitterNodeType::None) EmitBeginDoc(); } switch (child) { case EmitterNodeType::None: 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; } }
// 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: EmitKey(); break; case Value: EmitValue(); break; case TagByKind: EmitKindTag(); break; case Newline: EmitNewline(); break; default: m_pState->SetLocalValue(value); break; } return *this; }
// 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; }
// GotoNextPreAtomicState // . Runs the state machine, emitting if necessary, and returns 'true' if done (i.e., ready to emit an atom) bool Emitter::GotoNextPreAtomicState() { if(!good()) return true; unsigned curIndent = m_pState->GetCurIndent(); EMITTER_STATE curState = m_pState->GetCurState(); switch(curState) { // document-level case ES_WAITING_FOR_DOC: m_pState->SwitchState(ES_WRITING_DOC); return true; case ES_WRITING_DOC: return true; case ES_DONE_WITH_DOC: EmitBeginDoc(); return false; // block sequence case ES_WAITING_FOR_BLOCK_SEQ_ENTRY: m_stream << IndentTo(curIndent) << "-"; m_pState->RequireSoftSeparation(); m_pState->SwitchState(ES_WRITING_BLOCK_SEQ_ENTRY); return true; case ES_WRITING_BLOCK_SEQ_ENTRY: return true; case ES_DONE_WITH_BLOCK_SEQ_ENTRY: m_stream << '\n'; m_pState->SwitchState(ES_WAITING_FOR_BLOCK_SEQ_ENTRY); return false; // flow sequence case ES_WAITING_FOR_FLOW_SEQ_ENTRY: m_pState->SwitchState(ES_WRITING_FLOW_SEQ_ENTRY); return true; case ES_WRITING_FLOW_SEQ_ENTRY: return true; case ES_DONE_WITH_FLOW_SEQ_ENTRY: EmitSeparationIfNecessary(); m_stream << ','; m_pState->RequireSoftSeparation(); m_pState->SwitchState(ES_WAITING_FOR_FLOW_SEQ_ENTRY); return false; // block map case ES_WAITING_FOR_BLOCK_MAP_ENTRY: m_pState->SetError(ErrorMsg::EXPECTED_KEY_TOKEN); return true; case ES_WAITING_FOR_BLOCK_MAP_KEY: if(m_pState->CurrentlyInLongKey()) { m_stream << IndentTo(curIndent) << '?'; m_pState->RequireSoftSeparation(); } m_pState->SwitchState(ES_WRITING_BLOCK_MAP_KEY); return true; case ES_WRITING_BLOCK_MAP_KEY: return true; case ES_DONE_WITH_BLOCK_MAP_KEY: m_pState->SetError(ErrorMsg::EXPECTED_VALUE_TOKEN); return true; case ES_WAITING_FOR_BLOCK_MAP_VALUE: m_pState->SwitchState(ES_WRITING_BLOCK_MAP_VALUE); return true; case ES_WRITING_BLOCK_MAP_VALUE: return true; case ES_DONE_WITH_BLOCK_MAP_VALUE: m_pState->SetError(ErrorMsg::EXPECTED_KEY_TOKEN); return true; // flow map case ES_WAITING_FOR_FLOW_MAP_ENTRY: m_pState->SetError(ErrorMsg::EXPECTED_KEY_TOKEN); return true; case ES_WAITING_FOR_FLOW_MAP_KEY: EmitSeparationIfNecessary(); m_pState->SwitchState(ES_WRITING_FLOW_MAP_KEY); if(m_pState->CurrentlyInLongKey()) { m_stream << '?'; m_pState->RequireSoftSeparation(); } return true; case ES_WRITING_FLOW_MAP_KEY: return true; case ES_DONE_WITH_FLOW_MAP_KEY: m_pState->SetError(ErrorMsg::EXPECTED_VALUE_TOKEN); return true; case ES_WAITING_FOR_FLOW_MAP_VALUE: EmitSeparationIfNecessary(); m_stream << ':'; m_pState->RequireSoftSeparation(); m_pState->SwitchState(ES_WRITING_FLOW_MAP_VALUE); return true; case ES_WRITING_FLOW_MAP_VALUE: return true; case ES_DONE_WITH_FLOW_MAP_VALUE: m_pState->SetError(ErrorMsg::EXPECTED_KEY_TOKEN); return true; default: assert(false); } assert(false); return true; }