From 1602f7897444e2541cfa5722c27da85c222e909b Mon Sep 17 00:00:00 2001 From: Jesse Beder Date: Fri, 25 May 2012 17:28:35 -0500 Subject: [PATCH 1/6] Renamed ostream -> ostream_wrapper --- include/yaml-cpp/emitter.h | 6 ++--- .../yaml-cpp/{ostream.h => ostream_wrapper.h} | 18 ++++++------- src/emitterutils.cpp | 26 +++++++++---------- src/emitterutils.h | 22 ++++++++-------- src/indentation.h | 6 ++--- src/{ostream.cpp => ostream_wrapper.cpp} | 16 ++++++------ 6 files changed, 47 insertions(+), 47 deletions(-) rename include/yaml-cpp/{ostream.h => ostream_wrapper.h} (59%) rename src/{ostream.cpp => ostream_wrapper.cpp} (62%) diff --git a/include/yaml-cpp/emitter.h b/include/yaml-cpp/emitter.h index 43101da..28ece0a 100644 --- a/include/yaml-cpp/emitter.h +++ b/include/yaml-cpp/emitter.h @@ -10,9 +10,9 @@ #include "yaml-cpp/binary.h" #include "yaml-cpp/emitterdef.h" #include "yaml-cpp/emittermanip.h" -#include "yaml-cpp/ostream.h" #include "yaml-cpp/noncopyable.h" #include "yaml-cpp/null.h" +#include "yaml-cpp/ostream_wrapper.h" #include #include #include @@ -114,8 +114,8 @@ namespace YAML bool CanEmitNewline() const; private: - ostream m_stream; - std::auto_ptr m_pState; + ostream_wrapper m_stream; + std::auto_ptr m_pState; }; template diff --git a/include/yaml-cpp/ostream.h b/include/yaml-cpp/ostream_wrapper.h similarity index 59% rename from include/yaml-cpp/ostream.h rename to include/yaml-cpp/ostream_wrapper.h index 5f11ce6..8d33a3b 100644 --- a/include/yaml-cpp/ostream.h +++ b/include/yaml-cpp/ostream_wrapper.h @@ -1,5 +1,5 @@ -#ifndef OSTREAM_H_62B23520_7C8E_11DE_8A39_0800200C9A66 -#define OSTREAM_H_62B23520_7C8E_11DE_8A39_0800200C9A66 +#ifndef OSTREAM_WRAPPER_H_62B23520_7C8E_11DE_8A39_0800200C9A66 +#define OSTREAM_WRAPPER_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 #pragma once @@ -10,11 +10,11 @@ namespace YAML { - class ostream + class ostream_wrapper { public: - ostream(); - ~ostream(); + ostream_wrapper(); + ~ostream_wrapper(); void reserve(unsigned size); void put(char ch); @@ -35,9 +35,9 @@ namespace YAML bool m_comment; }; - ostream& operator << (ostream& out, const char *str); - ostream& operator << (ostream& out, const std::string& str); - ostream& operator << (ostream& out, char ch); + ostream_wrapper& operator << (ostream_wrapper& out, const char *str); + ostream_wrapper& operator << (ostream_wrapper& out, const std::string& str); + ostream_wrapper& operator << (ostream_wrapper& out, char ch); } -#endif // OSTREAM_H_62B23520_7C8E_11DE_8A39_0800200C9A66 +#endif // OSTREAM_WRAPPER_H_62B23520_7C8E_11DE_8A39_0800200C9A66 diff --git a/src/emitterutils.cpp b/src/emitterutils.cpp index 5dfaec9..0f2800c 100644 --- a/src/emitterutils.cpp +++ b/src/emitterutils.cpp @@ -107,7 +107,7 @@ namespace YAML return true; } - void WriteCodePoint(ostream& out, int codePoint) { + void WriteCodePoint(ostream_wrapper& out, int codePoint) { if (codePoint < 0 || codePoint > 0x10FFFF) { codePoint = REPLACEMENT_CHARACTER; } @@ -185,7 +185,7 @@ namespace YAML return true; } - void WriteDoubleQuoteEscapeSequence(ostream& out, int codePoint) { + void WriteDoubleQuoteEscapeSequence(ostream_wrapper& out, int codePoint) { static const char hexDigits[] = "0123456789abcdef"; char escSeq[] = "\\U00000000"; @@ -208,7 +208,7 @@ namespace YAML out << escSeq; } - bool WriteAliasName(ostream& out, const std::string& str) { + bool WriteAliasName(ostream_wrapper& out, const std::string& str) { int codePoint; for(std::string::const_iterator i = str.begin(); GetNextCodePointAndAdvance(codePoint, i, str.end()); @@ -247,7 +247,7 @@ namespace YAML return StringFormat::DoubleQuoted; } - bool WriteSingleQuotedString(ostream& out, const std::string& str) + bool WriteSingleQuotedString(ostream_wrapper& out, const std::string& str) { out << "'"; int codePoint; @@ -267,7 +267,7 @@ namespace YAML return true; } - bool WriteDoubleQuotedString(ostream& out, const std::string& str, bool escapeNonAscii) + bool WriteDoubleQuotedString(ostream_wrapper& out, const std::string& str, bool escapeNonAscii) { out << "\""; int codePoint; @@ -297,7 +297,7 @@ namespace YAML return true; } - bool WriteLiteralString(ostream& out, const std::string& str, int indent) + bool WriteLiteralString(ostream_wrapper& out, const std::string& str, int indent) { out << "|\n"; out << IndentTo(indent); @@ -314,7 +314,7 @@ namespace YAML return true; } - bool WriteChar(ostream& out, char ch) + bool WriteChar(ostream_wrapper& out, char ch) { if(('a' <= ch && ch <= 'z') || ('A' <= ch && ch <= 'Z')) out << ch; @@ -334,7 +334,7 @@ namespace YAML return true; } - bool WriteComment(ostream& out, const std::string& str, int postCommentIndent) + bool WriteComment(ostream_wrapper& out, const std::string& str, int postCommentIndent) { const unsigned curIndent = out.col(); out << "#" << Indentation(postCommentIndent); @@ -354,19 +354,19 @@ namespace YAML return true; } - bool WriteAlias(ostream& out, const std::string& str) + bool WriteAlias(ostream_wrapper& out, const std::string& str) { out << "*"; return WriteAliasName(out, str); } - bool WriteAnchor(ostream& out, const std::string& str) + bool WriteAnchor(ostream_wrapper& out, const std::string& str) { out << "&"; return WriteAliasName(out, str); } - bool WriteTag(ostream& out, const std::string& str, bool verbatim) + bool WriteTag(ostream_wrapper& out, const std::string& str, bool verbatim) { out << (verbatim ? "!<" : "!"); StringCharSource buffer(str.c_str(), str.size()); @@ -386,7 +386,7 @@ namespace YAML return true; } - bool WriteTagWithPrefix(ostream& out, const std::string& prefix, const std::string& tag) + bool WriteTagWithPrefix(ostream_wrapper& out, const std::string& prefix, const std::string& tag) { out << "!"; StringCharSource prefixBuffer(prefix.c_str(), prefix.size()); @@ -416,7 +416,7 @@ namespace YAML return true; } - bool WriteBinary(ostream& out, const Binary& binary) + bool WriteBinary(ostream_wrapper& out, const Binary& binary) { WriteDoubleQuotedString(out, EncodeBase64(binary.data(), binary.size()), false); return true; diff --git a/src/emitterutils.h b/src/emitterutils.h index 67200f8..50b37f0 100644 --- a/src/emitterutils.h +++ b/src/emitterutils.h @@ -7,7 +7,7 @@ #include "emitterstate.h" -#include "yaml-cpp/ostream.h" +#include "yaml-cpp/ostream_wrapper.h" #include namespace YAML @@ -20,16 +20,16 @@ namespace YAML { StringFormat::value ComputeStringFormat(const std::string& str, EMITTER_MANIP strFormat, FlowType::value flowType, bool escapeNonAscii); - bool WriteSingleQuotedString(ostream& out, const std::string& str); - bool WriteDoubleQuotedString(ostream& out, const std::string& str, bool escapeNonAscii); - bool WriteLiteralString(ostream& out, const std::string& str, int indent); - bool WriteChar(ostream& out, char ch); - bool WriteComment(ostream& out, const std::string& str, int postCommentIndent); - 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 Binary& binary); + bool WriteSingleQuotedString(ostream_wrapper& out, const std::string& str); + bool WriteDoubleQuotedString(ostream_wrapper& out, const std::string& str, bool escapeNonAscii); + bool WriteLiteralString(ostream_wrapper& out, const std::string& str, int indent); + bool WriteChar(ostream_wrapper& out, char ch); + bool WriteComment(ostream_wrapper& out, const std::string& str, int postCommentIndent); + bool WriteAlias(ostream_wrapper& out, const std::string& str); + bool WriteAnchor(ostream_wrapper& out, const std::string& str); + bool WriteTag(ostream_wrapper& out, const std::string& str, bool verbatim); + bool WriteTagWithPrefix(ostream_wrapper& out, const std::string& prefix, const std::string& tag); + bool WriteBinary(ostream_wrapper& out, const Binary& binary); } } diff --git a/src/indentation.h b/src/indentation.h index 25f684f..426fcb5 100644 --- a/src/indentation.h +++ b/src/indentation.h @@ -6,7 +6,7 @@ #endif -#include "yaml-cpp/ostream.h" +#include "yaml-cpp/ostream_wrapper.h" #include namespace YAML @@ -16,7 +16,7 @@ namespace YAML unsigned n; }; - inline ostream& operator << (ostream& out, const Indentation& indent) { + inline ostream_wrapper& operator << (ostream_wrapper& out, const Indentation& indent) { for(unsigned i=0;i namespace YAML { - ostream::ostream(): m_buffer(0), m_pos(0), m_size(0), m_row(0), m_col(0), m_comment(false) + ostream_wrapper::ostream_wrapper(): m_buffer(0), m_pos(0), m_size(0), m_row(0), m_col(0), m_comment(false) { reserve(1024); } - ostream::~ostream() + ostream_wrapper::~ostream_wrapper() { delete [] m_buffer; } - void ostream::reserve(unsigned size) + void ostream_wrapper::reserve(unsigned size) { if(size <= m_size) return; @@ -26,7 +26,7 @@ namespace YAML m_size = size; } - void ostream::put(char ch) + void ostream_wrapper::put(char ch) { if(m_pos >= m_size - 1) // an extra space for the NULL terminator reserve(m_size * 2); @@ -42,7 +42,7 @@ namespace YAML m_col++; } - ostream& operator << (ostream& out, const char *str) + ostream_wrapper& operator << (ostream_wrapper& out, const char *str) { std::size_t length = std::strlen(str); for(std::size_t i=0;i Date: Fri, 25 May 2012 17:39:14 -0500 Subject: [PATCH 2/6] Updated ostream wrapper with a write() and update_pos --- include/yaml-cpp/ostream_wrapper.h | 20 ++++++++++----- src/ostream_wrapper.cpp | 41 ++++++++++++++++++++++++------ 2 files changed, 46 insertions(+), 15 deletions(-) diff --git a/include/yaml-cpp/ostream_wrapper.h b/include/yaml-cpp/ostream_wrapper.h index 8d33a3b..fb40f18 100644 --- a/include/yaml-cpp/ostream_wrapper.h +++ b/include/yaml-cpp/ostream_wrapper.h @@ -16,22 +16,28 @@ namespace YAML ostream_wrapper(); ~ostream_wrapper(); - void reserve(unsigned size); + void reserve(std::size_t size); + void write(const std::string& str); + void write(const char *str, std::size_t size); void put(char ch); + void set_comment() { m_comment = true; } const char *str() const { return m_buffer; } - unsigned row() const { return m_row; } - unsigned col() const { return m_col; } - unsigned pos() const { return m_pos; } + std::size_t row() const { return m_row; } + std::size_t col() const { return m_col; } + std::size_t pos() const { return m_pos; } bool comment() const { return m_comment; } + + private: + void update_pos(char ch); private: char *m_buffer; - unsigned m_pos; - unsigned m_size; + std::size_t m_pos; + std::size_t m_size; - unsigned m_row, m_col; + std::size_t m_row, m_col; bool m_comment; }; diff --git a/src/ostream_wrapper.cpp b/src/ostream_wrapper.cpp index 34cbb3e..58432ae 100644 --- a/src/ostream_wrapper.cpp +++ b/src/ostream_wrapper.cpp @@ -13,7 +13,7 @@ namespace YAML delete [] m_buffer; } - void ostream_wrapper::reserve(unsigned size) + void ostream_wrapper::reserve(std::size_t size) { if(size <= m_size) return; @@ -25,6 +25,28 @@ namespace YAML m_buffer = newBuffer; m_size = size; } + + void ostream_wrapper::write(const std::string& str) + { + while(m_pos + str.size() + 1 >= m_size) + reserve(m_size * 2); + + std::copy(str.begin(), str.end(), m_buffer + m_pos); + + for(std::size_t i=0;i= m_size) + reserve(m_size * 2); + + std::copy(str, str + size, m_buffer + m_pos); + + for(std::size_t i=0;i Date: Fri, 25 May 2012 18:17:14 -0500 Subject: [PATCH 3/6] Switched the ostream wrapper to wrap a std::vector instead of our manually managed memory --- include/yaml-cpp/ostream_wrapper.h | 14 +++++----- src/ostream_wrapper.cpp | 41 +++++------------------------- util/sandbox.cpp | 3 ++- 3 files changed, 17 insertions(+), 41 deletions(-) diff --git a/include/yaml-cpp/ostream_wrapper.h b/include/yaml-cpp/ostream_wrapper.h index fb40f18..2e5deb6 100644 --- a/include/yaml-cpp/ostream_wrapper.h +++ b/include/yaml-cpp/ostream_wrapper.h @@ -7,6 +7,7 @@ #include +#include namespace YAML { @@ -16,13 +17,15 @@ namespace YAML ostream_wrapper(); ~ostream_wrapper(); - void reserve(std::size_t size); void write(const std::string& str); void write(const char *str, std::size_t size); - void put(char ch); void set_comment() { m_comment = true; } - const char *str() const { return m_buffer; } + + const char *str() const { + m_buffer[m_pos] = NULL; + return &m_buffer[0]; + } std::size_t row() const { return m_row; } std::size_t col() const { return m_col; } @@ -33,10 +36,9 @@ namespace YAML void update_pos(char ch); private: - char *m_buffer; + mutable std::vector m_buffer; + std::size_t m_pos; - std::size_t m_size; - std::size_t m_row, m_col; bool m_comment; }; diff --git a/src/ostream_wrapper.cpp b/src/ostream_wrapper.cpp index 58432ae..fe319e1 100644 --- a/src/ostream_wrapper.cpp +++ b/src/ostream_wrapper.cpp @@ -1,37 +1,21 @@ #include "yaml-cpp/ostream_wrapper.h" #include +#include namespace YAML { - ostream_wrapper::ostream_wrapper(): m_buffer(0), m_pos(0), m_size(0), m_row(0), m_col(0), m_comment(false) + ostream_wrapper::ostream_wrapper(): m_pos(0), m_row(0), m_col(0), m_comment(false) { - reserve(1024); } ostream_wrapper::~ostream_wrapper() { - delete [] m_buffer; } - void ostream_wrapper::reserve(std::size_t size) - { - if(size <= m_size) - return; - - char *newBuffer = new char[size]; - std::memset(newBuffer, 0, size * sizeof(char)); - std::memcpy(newBuffer, m_buffer, m_size * sizeof(char)); - delete [] m_buffer; - m_buffer = newBuffer; - m_size = size; - } - void ostream_wrapper::write(const std::string& str) { - while(m_pos + str.size() + 1 >= m_size) - reserve(m_size * 2); - - std::copy(str.begin(), str.end(), m_buffer + m_pos); + m_buffer.resize(std::max(m_buffer.size(), m_pos + str.size() + 1)); + std::copy(str.begin(), str.end(), &m_buffer[m_pos]); for(std::size_t i=0;i= m_size) - reserve(m_size * 2); - - std::copy(str, str + size, m_buffer + m_pos); + m_buffer.resize(std::max(m_buffer.size(), m_pos + size + 1)); + std::copy(str, str + size, &m_buffer[m_pos]); for(std::size_t i=0;i= m_size - 1) // an extra space for the NULL terminator - reserve(m_size * 2); - - m_buffer[m_pos] = ch; - update_pos(ch); - } - void ostream_wrapper::update_pos(char ch) { m_pos++; @@ -83,7 +56,7 @@ namespace YAML ostream_wrapper& operator << (ostream_wrapper& out, char ch) { - out.put(ch); + out.write(&ch, 1); return out; } } diff --git a/util/sandbox.cpp b/util/sandbox.cpp index be24ae1..63b0146 100644 --- a/util/sandbox.cpp +++ b/util/sandbox.cpp @@ -5,7 +5,8 @@ int main() { YAML::Emitter out; out << YAML::BeginSeq; - out << ':'; + out << "item 1"; + out << YAML::BeginSeq << "foo 1" << "bar 2" << YAML::EndSeq; out << YAML::EndSeq; std::cout << out.c_str() << "\n"; From 2ffdc5b4d1cbeb2f224d87764dcc53a65e4529ff Mon Sep 17 00:00:00 2001 From: Jesse Beder Date: Fri, 25 May 2012 18:22:33 -0500 Subject: [PATCH 4/6] Added constructor to the Emitter with a stream, so you can write directly to a stream instead of our temp --- include/yaml-cpp/emitter.h | 3 ++- include/yaml-cpp/ostream_wrapper.h | 10 ++++++++-- src/emitter.cpp | 4 ++++ src/ostream_wrapper.cpp | 22 +++++++++++++++++----- util/sandbox.cpp | 4 +--- 5 files changed, 32 insertions(+), 11 deletions(-) diff --git a/include/yaml-cpp/emitter.h b/include/yaml-cpp/emitter.h index 28ece0a..754192d 100644 --- a/include/yaml-cpp/emitter.h +++ b/include/yaml-cpp/emitter.h @@ -25,6 +25,7 @@ namespace YAML { public: Emitter(); + explicit Emitter(std::ostream& stream); ~Emitter(); // output @@ -114,8 +115,8 @@ namespace YAML bool CanEmitNewline() const; private: - ostream_wrapper m_stream; std::auto_ptr m_pState; + ostream_wrapper m_stream; }; template diff --git a/include/yaml-cpp/ostream_wrapper.h b/include/yaml-cpp/ostream_wrapper.h index 2e5deb6..f2446a5 100644 --- a/include/yaml-cpp/ostream_wrapper.h +++ b/include/yaml-cpp/ostream_wrapper.h @@ -15,6 +15,7 @@ namespace YAML { public: ostream_wrapper(); + explicit ostream_wrapper(std::ostream& stream); ~ostream_wrapper(); void write(const std::string& str); @@ -23,8 +24,12 @@ namespace YAML void set_comment() { m_comment = true; } const char *str() const { - m_buffer[m_pos] = NULL; - return &m_buffer[0]; + if(m_pStream) { + return NULL; + } else { + m_buffer[m_pos] = NULL; + return &m_buffer[0]; + } } std::size_t row() const { return m_row; } @@ -37,6 +42,7 @@ namespace YAML private: mutable std::vector m_buffer; + std::ostream *m_pStream; std::size_t m_pos; std::size_t m_row, m_col; diff --git a/src/emitter.cpp b/src/emitter.cpp index ed5993a..7e0067a 100644 --- a/src/emitter.cpp +++ b/src/emitter.cpp @@ -11,6 +11,10 @@ namespace YAML { } + Emitter::Emitter(std::ostream& stream): m_pState(new EmitterState), m_stream(stream) + { + } + Emitter::~Emitter() { } diff --git a/src/ostream_wrapper.cpp b/src/ostream_wrapper.cpp index fe319e1..e30ac59 100644 --- a/src/ostream_wrapper.cpp +++ b/src/ostream_wrapper.cpp @@ -4,18 +4,26 @@ namespace YAML { - ostream_wrapper::ostream_wrapper(): m_pos(0), m_row(0), m_col(0), m_comment(false) + ostream_wrapper::ostream_wrapper(): m_pStream(0), m_pos(0), m_row(0), m_col(0), m_comment(false) { } + ostream_wrapper::ostream_wrapper(std::ostream& stream): m_pStream(&stream), m_pos(0), m_row(0), m_col(0), m_comment(false) + { + } + ostream_wrapper::~ostream_wrapper() { } void ostream_wrapper::write(const std::string& str) { - m_buffer.resize(std::max(m_buffer.size(), m_pos + str.size() + 1)); - std::copy(str.begin(), str.end(), &m_buffer[m_pos]); + if(m_pStream) { + m_pStream->write(str.c_str(), str.size()); + } else { + m_buffer.resize(std::max(m_buffer.size(), m_pos + str.size() + 1)); + std::copy(str.begin(), str.end(), &m_buffer[m_pos]); + } for(std::size_t i=0;iwrite(str, size); + } else { + m_buffer.resize(std::max(m_buffer.size(), m_pos + size + 1)); + std::copy(str, str + size, &m_buffer[m_pos]); + } for(std::size_t i=0;i Date: Fri, 25 May 2012 18:24:07 -0500 Subject: [PATCH 5/6] Refactored stream overloads --- include/yaml-cpp/ostream_wrapper.h | 17 ++++++++++++++--- src/ostream_wrapper.cpp | 18 ------------------ 2 files changed, 14 insertions(+), 21 deletions(-) diff --git a/include/yaml-cpp/ostream_wrapper.h b/include/yaml-cpp/ostream_wrapper.h index f2446a5..b168c1c 100644 --- a/include/yaml-cpp/ostream_wrapper.h +++ b/include/yaml-cpp/ostream_wrapper.h @@ -49,9 +49,20 @@ namespace YAML bool m_comment; }; - ostream_wrapper& operator << (ostream_wrapper& out, const char *str); - ostream_wrapper& operator << (ostream_wrapper& out, const std::string& str); - ostream_wrapper& operator << (ostream_wrapper& out, char ch); + inline ostream_wrapper& operator << (ostream_wrapper& stream, const char *str) { + stream.write(str, std::strlen(str)); + return stream; + } + + inline ostream_wrapper& operator << (ostream_wrapper& stream, const std::string& str) { + stream.write(str); + return stream; + } + + inline ostream_wrapper& operator << (ostream_wrapper& stream, char ch) { + stream.write(&ch, 1); + return stream; + } } #endif // OSTREAM_WRAPPER_H_62B23520_7C8E_11DE_8A39_0800200C9A66 diff --git a/src/ostream_wrapper.cpp b/src/ostream_wrapper.cpp index e30ac59..15d9f0f 100644 --- a/src/ostream_wrapper.cpp +++ b/src/ostream_wrapper.cpp @@ -53,22 +53,4 @@ namespace YAML m_comment = false; } } - - ostream_wrapper& operator << (ostream_wrapper& out, const char *str) - { - out.write(str, std::strlen(str)); - return out; - } - - ostream_wrapper& operator << (ostream_wrapper& out, const std::string& str) - { - out.write(str); - return out; - } - - ostream_wrapper& operator << (ostream_wrapper& out, char ch) - { - out.write(&ch, 1); - return out; - } } From bc3f72b5656fc7284135765db7b5135d25cda858 Mon Sep 17 00:00:00 2001 From: Jesse Beder Date: Fri, 25 May 2012 19:33:34 -0500 Subject: [PATCH 6/6] Switched the stream << for c-strings to take a templated array param (since we never stream user-built c-strings, only string literals). For this, refactored the escape character display --- include/yaml-cpp/ostream_wrapper.h | 9 +++++---- src/emitterutils.cpp | 24 +++++++++++------------- 2 files changed, 16 insertions(+), 17 deletions(-) diff --git a/include/yaml-cpp/ostream_wrapper.h b/include/yaml-cpp/ostream_wrapper.h index b168c1c..a6d96c5 100644 --- a/include/yaml-cpp/ostream_wrapper.h +++ b/include/yaml-cpp/ostream_wrapper.h @@ -25,9 +25,9 @@ namespace YAML const char *str() const { if(m_pStream) { - return NULL; + return 0; } else { - m_buffer[m_pos] = NULL; + m_buffer[m_pos] = '\0'; return &m_buffer[0]; } } @@ -49,8 +49,9 @@ namespace YAML bool m_comment; }; - inline ostream_wrapper& operator << (ostream_wrapper& stream, const char *str) { - stream.write(str, std::strlen(str)); + template + inline ostream_wrapper& operator << (ostream_wrapper& stream, const char (&str)[N]) { + stream.write(str, N-1); return stream; } diff --git a/src/emitterutils.cpp b/src/emitterutils.cpp index 0f2800c..09780d0 100644 --- a/src/emitterutils.cpp +++ b/src/emitterutils.cpp @@ -188,24 +188,22 @@ namespace YAML void WriteDoubleQuoteEscapeSequence(ostream_wrapper& out, int codePoint) { static const char hexDigits[] = "0123456789abcdef"; - char escSeq[] = "\\U00000000"; + out << "\\"; int digits = 8; - if (codePoint < 0xFF) { - escSeq[1] = 'x'; + if(codePoint < 0xFF) { + out << "x"; digits = 2; - } else if (codePoint < 0xFFFF) { - escSeq[1] = 'u'; + } else if(codePoint < 0xFFFF) { + out << "u"; digits = 4; - } + } else { + out << "U"; + digits = 8; + } // Write digits into the escape sequence - int i = 2; - for (; digits > 0; --digits, ++i) { - escSeq[i] = hexDigits[(codePoint >> (4 * (digits - 1))) & 0xF]; - } - - escSeq[i] = 0; // terminate with NUL character - out << escSeq; + for (; digits > 0; --digits) + out << hexDigits[(codePoint >> (4 * (digits - 1))) & 0xF]; } bool WriteAliasName(ostream_wrapper& out, const std::string& str) {