From 6065a1c1424fac66f9d6da25f2de58b19f2350b2 Mon Sep 17 00:00:00 2001 From: Christopher Dunn Date: Mon, 26 Jan 2015 11:01:15 -0600 Subject: [PATCH] make StreamWriterBuilder concrete --- include/json/writer.h | 73 ++++++++++++++---------------------- src/jsontestrunner/main.cpp | 3 +- src/lib_json/json_writer.cpp | 68 +++------------------------------ 3 files changed, 36 insertions(+), 108 deletions(-) diff --git a/include/json/writer.h b/include/json/writer.h index 176876e..db71cd7 100644 --- a/include/json/writer.h +++ b/include/json/writer.h @@ -58,58 +58,43 @@ public: /// \throw std::exception possibly, depending on configuration virtual int write(Value const& root) = 0; - /// 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 JSON_API Builder { - StreamWriterBuilder* own_; - Builder(Builder const&); // noncopyable - void operator=(Builder const&); // noncopyable - public: - Builder(); - ~Builder(); // delete underlying StreamWriterBuilder - - Builder& withCommentStyle(CommentStyle cs); /// default: All - /** \brief Write in human-friendly style. - - If "", then skip all indentation, newlines, and comments, - which implies CommentStyle::None. - Default: "\t" - */ - Builder& withIndentation(std::string indentation); - - /// Do not take ownership of sout, but maintain a reference. - StreamWriter* newStreamWriter(std::ostream* sout) const; - }; - /** \brief A simple abstract factory. */ class JSON_API Factory { public: virtual ~Factory(); - /* Because this is only a trivial API (the Factory pattern), we will - * never need to add virtual methods, so we do not need a concrete wrapper. - * This is better than the Builder above, but not everyone will agree. - */ - /// Do not take ownership of sout, but maintain a reference. virtual StreamWriter* newStreamWriter(std::ostream* sout) const = 0; - }; - - /** \brief Extensions of this are used to create a StreamWriter::Factory. - */ - class JSON_API FactoryFactory { - virtual ~FactoryFactory(); - virtual Factory* newFactory() const = 0; - /* This class will seem strange to some developers, but it actually - * simplifies our library maintenance. - */ - }; - -}; + }; // Factory +}; // StreamWriter /// \brief Write into stringstream, then return string, for convenience. -std::string writeString(Value const& root, StreamWriter::Builder const& builder); +std::string writeString(Value const& root, StreamWriter::Factory const& factory); + + +/** \brief Build a StreamWriter implementation. + */ +class JSON_API StreamWriterBuilder : public StreamWriter::Factory { + // typedef StreamWriter::CommentStyle CommentStyle; +public: + // Note: We cannot add data-members to this class without a major version bump. + // So these might as well be completely exposed. + + /** \brief How to write comments. + * Default: All + */ + StreamWriter::CommentStyle cs_ = StreamWriter::CommentStyle::All; + /** \brief Write in human-friendly style. + + If "", then skip all indentation and newlines. + In that case, you probably want CommentStyle::None also. + Default: "\t" + */ + std::string indentation_ = "\t"; + + /// Do not take ownership of sout, but maintain a reference. + StreamWriter* newStreamWriter(std::ostream* sout) const; +}; /** \brief Build a StreamWriter implementation. * Comments are not written, and most whitespace is omitted. @@ -124,7 +109,7 @@ std::string writeString(Value const& root, StreamWriter::Builder const& builder) * delete w; * \endcode */ -class JSON_API OldCompressingStreamWriterBuilder +class JSON_API OldCompressingStreamWriterBuilder : public StreamWriter::Factory { public: // Note: We cannot add data-members to this class without a major version bump. diff --git a/src/jsontestrunner/main.cpp b/src/jsontestrunner/main.cpp index 3a2229c..dba943b 100644 --- a/src/jsontestrunner/main.cpp +++ b/src/jsontestrunner/main.cpp @@ -184,8 +184,7 @@ static std::string useStyledStreamWriter( static std::string useBuiltStyledStreamWriter( Json::Value const& root) { - Json::StreamWriter::Builder builder; - builder.withCommentStyle(Json::StreamWriter::CommentStyle::All); + Json::StreamWriterBuilder builder; return writeString(root, builder); } static int rewriteValueTree( diff --git a/src/lib_json/json_writer.cpp b/src/lib_json/json_writer.cpp index 11c564b..b8d1ba8 100644 --- a/src/lib_json/json_writer.cpp +++ b/src/lib_json/json_writer.cpp @@ -959,34 +959,8 @@ int MyStreamWriter::write(Value const& root) sout_ << root; return 0; } -class StreamWriterBuilder { - typedef StreamWriter::CommentStyle CommentStyle; - CommentStyle cs_; - std::string indentation_; -public: - StreamWriterBuilder(); - virtual ~StreamWriterBuilder(); - virtual void setCommentStyle(CommentStyle cs); - virtual void setIndentation(std::string indentation); - virtual StreamWriter* newStreamWriter(std::ostream* sout) const; -}; -StreamWriterBuilder::StreamWriterBuilder() - : cs_(CommentStyle::All) - , indentation_("\t") -{ -} -StreamWriterBuilder::~StreamWriterBuilder() -{ -} -void StreamWriterBuilder::setCommentStyle(CommentStyle v) -{ - cs_ = v; -} -void StreamWriterBuilder::setIndentation(std::string v) -{ - indentation_ = v; - if (indentation_.empty()) cs_ = CommentStyle::None; -} +StreamWriter::Factory::~Factory() +{} StreamWriter* StreamWriterBuilder::newStreamWriter(std::ostream* stream) const { std::string colonSymbol = " : "; @@ -999,7 +973,7 @@ StreamWriter* StreamWriterBuilder::newStreamWriter(std::ostream* stream) const indentation_, cs_, colonSymbol, nullSymbol, endingLineFeedSymbol); } - +/* // This might become public someday. class StreamWriterBuilderFactory { public: @@ -1013,35 +987,7 @@ StreamWriterBuilder* StreamWriterBuilderFactory::newStreamWriterBuilder() const { return new StreamWriterBuilder; } - -StreamWriter::Builder::Builder() - : own_(StreamWriterBuilderFactory().newStreamWriterBuilder()) -{ -} -StreamWriter::Builder::~Builder() -{ - delete own_; -} -StreamWriter::Builder::Builder(Builder const&) - : own_(nullptr) -{abort();} -void StreamWriter::Builder::operator=(Builder const&) -{abort();} -StreamWriter::Builder& StreamWriter::Builder::withCommentStyle(CommentStyle v) -{ - own_->setCommentStyle(v); - return *this; -} -StreamWriter::Builder& StreamWriter::Builder::withIndentation(std::string v) -{ - own_->setIndentation(v); - return *this; -} -StreamWriter* StreamWriter::Builder::newStreamWriter( - std::ostream* sout) const -{ - return own_->newStreamWriter(sout); -} +*/ StreamWriter* OldCompressingStreamWriterBuilder::newStreamWriter( std::ostream* stream) const @@ -1065,7 +1011,7 @@ StreamWriter* OldCompressingStreamWriterBuilder::newStreamWriter( colonSymbol, nullSymbol, endingLineFeedSymbol); } -std::string writeString(Value const& root, StreamWriter::Builder const& builder) { +std::string writeString(Value const& root, StreamWriter::Factory const& builder) { std::ostringstream sout; std::unique_ptr const sw(builder.newStreamWriter(&sout)); sw->write(root); @@ -1073,9 +1019,7 @@ std::string writeString(Value const& root, StreamWriter::Builder const& builder) } std::ostream& operator<<(std::ostream& sout, Value const& root) { - StreamWriter::Builder builder; - builder.withCommentStyle(StreamWriter::CommentStyle::All); - builder.withIndentation("\t"); + StreamWriterBuilder builder; std::shared_ptr writer(builder.newStreamWriter(&sout)); writer->write(root); return sout;