make StreamWriterBuilder concrete

This commit is contained in:
Christopher Dunn 2015-01-26 11:01:15 -06:00
parent 28a20917b0
commit 6065a1c142
3 changed files with 36 additions and 108 deletions

View File

@ -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.

View File

@ -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(

View File

@ -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<StreamWriter> 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<StreamWriter> writer(builder.newStreamWriter(&sout));
writer->write(root);
return sout;