mirror of
https://github.com/jbeder/yaml-cpp.git
synced 2025-09-09 20:51:16 +00:00
Refactored tags so we can emit secondary tags (and named local tags)
This commit is contained in:
@@ -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_) {}
|
||||||
|
@@ -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);
|
||||||
|
@@ -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+/";
|
||||||
|
@@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user