Refactored tags so we can emit secondary tags (and named local tags)

This commit is contained in:
Jesse Beder
2010-10-28 23:06:16 +00:00
parent d508203ed8
commit a6afaabcb0
4 changed files with 70 additions and 27 deletions

View File

@@ -84,24 +84,32 @@ namespace YAML
} }
struct _Tag { struct _Tag {
explicit _Tag(const std::string& content_) struct Type { enum value { Verbatim, PrimaryHandle, NamedHandle }; };
: content(content_), verbatim(true)
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; std::string content;
bool verbatim; Type::value type;
}; };
typedef _Tag VerbatimTag; inline _Tag VerbatimTag(const std::string content) {
return _Tag("", content, _Tag::Type::Verbatim);
}
struct LocalTag : public _Tag inline _Tag LocalTag(const std::string content) {
{ return _Tag("", content, _Tag::Type::PrimaryHandle);
explicit LocalTag(const std::string& content_) }
: _Tag(content_)
{ inline _Tag LocalTag(const std::string& prefix, const std::string content) {
verbatim = false; return _Tag(prefix, content, _Tag::Type::NamedHandle);
} }
};
inline _Tag SecondaryTag(const std::string content) {
return _Tag("", content, _Tag::Type::NamedHandle);
}
struct _Comment { struct _Comment {
_Comment(const std::string& content_): content(content_) {} _Comment(const std::string& content_): content(content_) {}

View File

@@ -681,26 +681,30 @@ namespace YAML
if(!good()) if(!good())
return *this; return *this;
EmitTag(tag.verbatim, tag);
return *this;
}
void Emitter::EmitTag(bool verbatim, const _Tag& tag)
{
PreAtomicWrite(); PreAtomicWrite();
EmitSeparationIfNecessary(); 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); m_pState->SetError(ErrorMsg::INVALID_TAG);
return; return *this;
} }
m_pState->RequireSeparation(); m_pState->RequireSeparation();
// Note: no PostAtomicWrite() because we need another value for this node // Note: no PostAtomicWrite() because we need another value for this node
return *this;
} }
void Emitter::EmitKindTag() void Emitter::EmitKindTag()
{ {
_Tag tag(""); Write(LocalTag(""));
EmitTag(false, tag);
} }
Emitter& Emitter::Write(const _Comment& comment) Emitter& Emitter::Write(const _Comment& comment)
@@ -727,11 +731,11 @@ namespace YAML
Emitter& Emitter::Write(const _Binary& binary) Emitter& Emitter::Write(const _Binary& binary)
{ {
Write(SecondaryTag("binary"));
if(!good()) if(!good())
return *this; return *this;
// TODO: write tag !!binary
PreAtomicWrite(); PreAtomicWrite();
EmitSeparationIfNecessary(); EmitSeparationIfNecessary();
Utils::WriteBinary(m_stream, binary.data, binary.size); Utils::WriteBinary(m_stream, binary.data, binary.size);

View File

@@ -314,6 +314,36 @@ namespace YAML
return true; 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) bool WriteBinary(ostream& out, const char *data, std::size_t size)
{ {
static const char encoding[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; static const char encoding[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";

View File

@@ -19,6 +19,7 @@ namespace YAML
bool WriteAlias(ostream& out, const std::string& str); bool WriteAlias(ostream& out, const std::string& str);
bool WriteAnchor(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 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); bool WriteBinary(ostream& out, const char *data, std::size_t size);
} }
} }