From a6afaabcb009e06391a696017cff83c653a6bd68 Mon Sep 17 00:00:00 2001 From: Jesse Beder Date: Thu, 28 Oct 2010 23:06:16 +0000 Subject: [PATCH] Refactored tags so we can emit secondary tags (and named local tags) --- include/yaml-cpp/emittermanip.h | 34 ++++++++++++++++++++------------- src/emitter.cpp | 32 +++++++++++++++++-------------- src/emitterutils.cpp | 30 +++++++++++++++++++++++++++++ src/emitterutils.h | 1 + 4 files changed, 70 insertions(+), 27 deletions(-) diff --git a/include/yaml-cpp/emittermanip.h b/include/yaml-cpp/emittermanip.h index 5ce0503..fc29655 100644 --- a/include/yaml-cpp/emittermanip.h +++ b/include/yaml-cpp/emittermanip.h @@ -84,24 +84,32 @@ namespace YAML } struct _Tag { - explicit _Tag(const std::string& content_) - : content(content_), verbatim(true) + struct Type { enum value { Verbatim, PrimaryHandle, NamedHandle }; }; + + explicit _Tag(const std::string& prefix_, const std::string& content_, Type::value type_) + : prefix(prefix_), content(content_), type(type_) { } + std::string prefix; std::string content; - bool verbatim; + Type::value type; }; - typedef _Tag VerbatimTag; - - struct LocalTag : public _Tag - { - explicit LocalTag(const std::string& content_) - : _Tag(content_) - { - verbatim = false; - } - }; + inline _Tag VerbatimTag(const std::string content) { + return _Tag("", content, _Tag::Type::Verbatim); + } + + inline _Tag LocalTag(const std::string content) { + return _Tag("", content, _Tag::Type::PrimaryHandle); + } + + inline _Tag LocalTag(const std::string& prefix, const std::string content) { + return _Tag(prefix, content, _Tag::Type::NamedHandle); + } + + inline _Tag SecondaryTag(const std::string content) { + return _Tag("", content, _Tag::Type::NamedHandle); + } struct _Comment { _Comment(const std::string& content_): content(content_) {} diff --git a/src/emitter.cpp b/src/emitter.cpp index 91500a8..30e422d 100644 --- a/src/emitter.cpp +++ b/src/emitter.cpp @@ -680,27 +680,31 @@ namespace YAML { if(!good()) return *this; - - EmitTag(tag.verbatim, tag); - return *this; - } - - void Emitter::EmitTag(bool verbatim, const _Tag& tag) - { + PreAtomicWrite(); EmitSeparationIfNecessary(); - if(!Utils::WriteTag(m_stream, tag.content, verbatim)) { + + 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; + return *this; } + m_pState->RequireSeparation(); // Note: no PostAtomicWrite() because we need another value for this node + return *this; } - + void Emitter::EmitKindTag() { - _Tag tag(""); - EmitTag(false, tag); + Write(LocalTag("")); } Emitter& Emitter::Write(const _Comment& comment) @@ -727,10 +731,10 @@ namespace YAML Emitter& Emitter::Write(const _Binary& binary) { + Write(SecondaryTag("binary")); + if(!good()) return *this; - - // TODO: write tag !!binary PreAtomicWrite(); EmitSeparationIfNecessary(); diff --git a/src/emitterutils.cpp b/src/emitterutils.cpp index 7bd03d8..38bd18f 100644 --- a/src/emitterutils.cpp +++ b/src/emitterutils.cpp @@ -314,6 +314,36 @@ namespace YAML return true; } + bool WriteTagWithPrefix(ostream& out, const std::string& prefix, const std::string& tag) + { + out << "!"; + StringCharSource prefixBuffer(prefix.c_str(), prefix.size()); + while(prefixBuffer) { + int n = Exp::URI().Match(prefixBuffer); + if(n <= 0) + return false; + + while(--n >= 0) { + out << prefixBuffer[0]; + ++prefixBuffer; + } + } + + out << "!"; + StringCharSource tagBuffer(tag.c_str(), tag.size()); + while(tagBuffer) { + int n = Exp::Tag().Match(tagBuffer); + if(n <= 0) + return false; + + while(--n >= 0) { + out << tagBuffer[0]; + ++tagBuffer; + } + } + return true; + } + bool WriteBinary(ostream& out, const char *data, std::size_t size) { static const char encoding[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; diff --git a/src/emitterutils.h b/src/emitterutils.h index aa108c1..a44ae2c 100644 --- a/src/emitterutils.h +++ b/src/emitterutils.h @@ -19,6 +19,7 @@ namespace YAML bool WriteAlias(ostream& out, const std::string& str); bool WriteAnchor(ostream& out, const std::string& str); bool WriteTag(ostream& out, const std::string& str, bool verbatim); + bool WriteTagWithPrefix(ostream& out, const std::string& prefix, const std::string& tag); bool WriteBinary(ostream& out, const char *data, std::size_t size); } }