From 489707ff602217cbfa9e6699078a54787c9dd73d Mon Sep 17 00:00:00 2001 From: Christopher Dunn Date: Thu, 22 Jan 2015 15:25:30 -0600 Subject: [PATCH] StreamWriter::Builder --- include/json/writer.h | 45 +++++++++++++++++++++++++++--------- src/lib_json/json_writer.cpp | 30 +++++++++++++++++++++++- 2 files changed, 63 insertions(+), 12 deletions(-) diff --git a/include/json/writer.h b/include/json/writer.h index 4198498..d5306c9 100644 --- a/include/json/writer.h +++ b/include/json/writer.h @@ -22,30 +22,53 @@ namespace Json { class Value; +class StreamWriterBuilder; + +/** + +Usage: + + using namespace Json; + Value value; + StreamWriterBuilderFactory f; + StreamWriter::Builder builder(&f); + builder.setCommentStyle(StreamWriter::CommentStyle::None); + std::shared_ptr writer(builder.newStreamWriter(&std::cout)); + writer.write(value); +*/ +class JSON_API StreamWriterBuilderFactory { +public: + virtual ~StreamWriterBuilderFactory(); + virtual StreamWriterBuilder* newStreamWriterBuilder() const; +}; class JSON_API StreamWriter { protected: std::ostream& sout_; // not owned; will not delete public: + enum class CommentStyle {None, Some, All}; + StreamWriter(std::ostream* sout); virtual ~StreamWriter(); /// Write Value into document as configured in sub-class. /// \return zero on success /// \throw std::exception possibly, depending on configuration virtual int write(Value const& root) const = 0; -}; -class JSON_API StreamWriterBuilder { -public: - virtual ~StreamWriterBuilder(); - /// Do not delete stream (i.e. not owned), but keep a reference. - virtual StreamWriter* newStreamWriter(std::ostream* stream) const; -}; + /// Because this Builder is non-virtual, we can safely add + /// methods without a major version bump. + /// \see http://stackoverflow.com/questions/14875052/pure-virtual-functions-and-binary-compatibility + class Builder { + StreamWriterBuilder* own_; + public: + Builder(StreamWriterBuilderFactory const*); + ~Builder(); // delete underlying StreamWriterBuilder -class JSON_API StreamWriterBuilderFactory { -public: - virtual ~StreamWriterBuilderFactory(); - virtual StreamWriterBuilder* newStreamWriterBuilder(); + void setCommentStyle(CommentStyle cs); /// default: All + + /// Do not take ownership of sout, but maintain a reference. + StreamWriter* newStreamWriter(std::ostream* sout); + }; }; /// \brief Write into stringstream, then return string, for convenience. diff --git a/src/lib_json/json_writer.cpp b/src/lib_json/json_writer.cpp index 3f53f94..15fcf64 100644 --- a/src/lib_json/json_writer.cpp +++ b/src/lib_json/json_writer.cpp @@ -696,9 +696,21 @@ int MyStreamWriter::write(Value const& root) const sout_ << root; return 0; } +class StreamWriterBuilder { + typedef StreamWriter::CommentStyle CommentStyle; + CommentStyle cs_; +public: + virtual ~StreamWriterBuilder(); + virtual void setCommentStyle(CommentStyle cs); + virtual StreamWriter* newStreamWriter(std::ostream* sout) const; +}; StreamWriterBuilder::~StreamWriterBuilder() { } +void StreamWriterBuilder::setCommentStyle(CommentStyle cs) +{ + cs_ = cs; +} StreamWriter* StreamWriterBuilder::newStreamWriter(std::ostream* stream) const { // return new StyledStreamWriter(stream); @@ -707,10 +719,26 @@ StreamWriter* StreamWriterBuilder::newStreamWriter(std::ostream* stream) const StreamWriterBuilderFactory::~StreamWriterBuilderFactory() { } -StreamWriterBuilder* StreamWriterBuilderFactory::newStreamWriterBuilder() +StreamWriterBuilder* StreamWriterBuilderFactory::newStreamWriterBuilder() const { return new StreamWriterBuilder; } + +StreamWriter::Builder::Builder(StreamWriterBuilderFactory const* f) + : own_(f->newStreamWriterBuilder()) +{ +} +StreamWriter::Builder::~Builder() +{ + delete own_; +} +void StreamWriter::Builder::setCommentStyle(CommentStyle cs) +{ + own_->setCommentStyle(cs); +} + +/// Do not take ownership of sout, but maintain a reference. +StreamWriter* newStreamWriter(std::ostream* sout); std::string writeString(Value const& root, StreamWriterBuilder const& builder) { std::ostringstream sout; std::unique_ptr const sw(builder.newStreamWriter(&sout));