diff --git a/include/yaml-cpp/emitter.h b/include/yaml-cpp/emitter.h index 43101da..754192d 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 @@ -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 m_stream; - std::auto_ptr m_pState; + std::auto_ptr m_pState; + ostream_wrapper m_stream; }; template diff --git a/include/yaml-cpp/ostream.h b/include/yaml-cpp/ostream.h deleted file mode 100644 index 5f11ce6..0000000 --- a/include/yaml-cpp/ostream.h +++ /dev/null @@ -1,43 +0,0 @@ -#ifndef OSTREAM_H_62B23520_7C8E_11DE_8A39_0800200C9A66 -#define OSTREAM_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 -#endif - - -#include - -namespace YAML -{ - class ostream - { - public: - ostream(); - ~ostream(); - - void reserve(unsigned 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; } - bool comment() const { return m_comment; } - - private: - char *m_buffer; - unsigned m_pos; - unsigned m_size; - - unsigned m_row, m_col; - bool m_comment; - }; - - ostream& operator << (ostream& out, const char *str); - ostream& operator << (ostream& out, const std::string& str); - ostream& operator << (ostream& out, char ch); -} - -#endif // OSTREAM_H_62B23520_7C8E_11DE_8A39_0800200C9A66 diff --git a/include/yaml-cpp/ostream_wrapper.h b/include/yaml-cpp/ostream_wrapper.h new file mode 100644 index 0000000..a6d96c5 --- /dev/null +++ b/include/yaml-cpp/ostream_wrapper.h @@ -0,0 +1,69 @@ +#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 +#endif + + +#include +#include + +namespace YAML +{ + class ostream_wrapper + { + public: + ostream_wrapper(); + explicit ostream_wrapper(std::ostream& stream); + ~ostream_wrapper(); + + void write(const std::string& str); + void write(const char *str, std::size_t size); + + void set_comment() { m_comment = true; } + + const char *str() const { + if(m_pStream) { + return 0; + } else { + m_buffer[m_pos] = '\0'; + return &m_buffer[0]; + } + } + + 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: + mutable std::vector m_buffer; + std::ostream *m_pStream; + + std::size_t m_pos; + std::size_t m_row, m_col; + bool m_comment; + }; + + template + inline ostream_wrapper& operator << (ostream_wrapper& stream, const char (&str)[N]) { + stream.write(str, N-1); + 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/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/emitterutils.cpp b/src/emitterutils.cpp index 5dfaec9..09780d0 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,30 +185,28 @@ 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"; + 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& 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 +245,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 +265,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 +295,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 +312,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 +332,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 +352,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 +384,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 +414,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) - { - reserve(1024); - } - - ostream::~ostream() - { - delete [] m_buffer; - } - - void ostream::reserve(unsigned 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::put(char ch) - { - if(m_pos >= m_size - 1) // an extra space for the NULL terminator - reserve(m_size * 2); - - m_buffer[m_pos] = ch; - m_pos++; - - if(ch == '\n') { - m_row++; - m_col = 0; - m_comment = false; - } else - m_col++; - } - - ostream& operator << (ostream& out, const char *str) - { - std::size_t length = std::strlen(str); - for(std::size_t i=0;i +#include + +namespace YAML +{ + 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) + { + 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