mirror of
https://github.com/open-source-parsers/jsoncpp.git
synced 2025-06-07 01:04:55 +02:00
Merge pull request #145 from cdunn2001/simplify-builder
Simplify builder
This commit is contained in:
commit
3b5f2b85ca
@ -81,8 +81,8 @@ root["indent"]["use_space"] = getCurrentIndentUseSpace();
|
|||||||
|
|
||||||
// To write into a steam with minimal memory overhead,
|
// To write into a steam with minimal memory overhead,
|
||||||
// create a Builder for a StreamWriter.
|
// create a Builder for a StreamWriter.
|
||||||
Json::StreamWriter::Builder builder;
|
Json::StreamWriterBuilder builder;
|
||||||
builder.withIndentation(" "); // or whatever you like
|
builder.indentation_ = " "; // or whatever you like
|
||||||
|
|
||||||
// Then build a StreamWriter.
|
// Then build a StreamWriter.
|
||||||
std::shared_ptr<Json::StreamWriter> writer(
|
std::shared_ptr<Json::StreamWriter> writer(
|
||||||
@ -94,6 +94,9 @@ writer->write( root );
|
|||||||
// If you like the defaults, you can insert directly into a stream.
|
// If you like the defaults, you can insert directly into a stream.
|
||||||
std::cout << root;
|
std::cout << root;
|
||||||
|
|
||||||
|
// If desired, remember to add a linefeed and flush.
|
||||||
|
std::cout << std::endl;
|
||||||
|
|
||||||
// Of course, you can write to `std::ostringstream` if you prefer. Or
|
// Of course, you can write to `std::ostringstream` if you prefer. Or
|
||||||
// use `writeString()` for convenience.
|
// use `writeString()` for convenience.
|
||||||
std::string document = Json::writeString( root, builder );
|
std::string document = Json::writeString( root, builder );
|
||||||
|
@ -11,6 +11,7 @@
|
|||||||
#endif // if !defined(JSON_IS_AMALGAMATION)
|
#endif // if !defined(JSON_IS_AMALGAMATION)
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <ostream>
|
||||||
|
|
||||||
// Disable warning C4251: <data member>: <type> needs to have dll-interface to
|
// Disable warning C4251: <data member>: <type> needs to have dll-interface to
|
||||||
// be used by...
|
// be used by...
|
||||||
@ -22,20 +23,18 @@
|
|||||||
namespace Json {
|
namespace Json {
|
||||||
|
|
||||||
class Value;
|
class Value;
|
||||||
class StreamWriterBuilder;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
||||||
Usage:
|
Usage:
|
||||||
\code
|
\code
|
||||||
using namespace Json;
|
using namespace Json;
|
||||||
Value value;
|
void writeToStdout(StreamWriter::Builder const& builder, Value const& value) {
|
||||||
StreamWriter::Builder builder;
|
std::unique_ptr<StreamWriter> const writer(
|
||||||
builder.withCommentStyle(StreamWriter::CommentStyle::None);
|
builder.newStreamWriter(&std::cout));
|
||||||
std::shared_ptr<StreamWriter> writer(
|
writer->write(value);
|
||||||
builder.newStreamWriter(&std::cout));
|
std::cout << std::endl; // add lf and flush
|
||||||
writer->write(value);
|
}
|
||||||
std::cout.flush();
|
|
||||||
\endcode
|
\endcode
|
||||||
*/
|
*/
|
||||||
class JSON_API StreamWriter {
|
class JSON_API StreamWriter {
|
||||||
@ -57,53 +56,103 @@ public:
|
|||||||
/// \throw std::exception possibly, depending on configuration
|
/// \throw std::exception possibly, depending on configuration
|
||||||
virtual int write(Value const& root) = 0;
|
virtual int write(Value const& root) = 0;
|
||||||
|
|
||||||
/// Because this Builder is non-virtual, we can safely add
|
/** \brief A simple abstract factory.
|
||||||
/// methods without a major version bump.
|
*/
|
||||||
/// \see http://stackoverflow.com/questions/14875052/pure-virtual-functions-and-binary-compatibility
|
class JSON_API Factory {
|
||||||
class Builder {
|
|
||||||
StreamWriterBuilder* own_;
|
|
||||||
Builder(Builder const&); // noncopyable
|
|
||||||
void operator=(Builder const&); // noncopyable
|
|
||||||
public:
|
public:
|
||||||
Builder();
|
virtual ~Factory();
|
||||||
~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);
|
|
||||||
/** \brief Drop the "null" string from the writer's output for nullValues.
|
|
||||||
* Strictly speaking, this is not valid JSON. But when the output is being
|
|
||||||
* fed to a browser's Javascript, it makes for smaller output and the
|
|
||||||
* browser can handle the output just fine.
|
|
||||||
*/
|
|
||||||
Builder& withDropNullPlaceholders(bool v);
|
|
||||||
/** \brief Do not add \n at end of document.
|
|
||||||
* Normally, we add an extra newline, just because.
|
|
||||||
*/
|
|
||||||
Builder& withOmitEndingLineFeed(bool v);
|
|
||||||
/** \brief Add a space after ':'.
|
|
||||||
* If indentation is non-empty, we surround colon with whitespace,
|
|
||||||
* e.g. " : "
|
|
||||||
* This will add back the trailing space when there is no indentation.
|
|
||||||
* This seems dubious when the entire document is on a single line,
|
|
||||||
* but we leave this here to repduce the behavior of the old `FastWriter`.
|
|
||||||
*/
|
|
||||||
Builder& withEnableYAMLCompatibility(bool v);
|
|
||||||
|
|
||||||
/// Do not take ownership of sout, but maintain a reference.
|
/// Do not take ownership of sout, but maintain a reference.
|
||||||
StreamWriter* newStreamWriter(std::ostream* sout) const;
|
virtual StreamWriter* newStreamWriter(std::ostream* sout) const = 0;
|
||||||
};
|
}; // Factory
|
||||||
};
|
}; // StreamWriter
|
||||||
|
|
||||||
/// \brief Write into stringstream, then return string, for convenience.
|
/// \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.
|
||||||
|
|
||||||
|
Usage:
|
||||||
|
\code
|
||||||
|
using namespace Json;
|
||||||
|
Value value = ...;
|
||||||
|
StreamWriter::Builder builder;
|
||||||
|
builder.cs_ = StreamWriter::CommentStyle::None;
|
||||||
|
std::shared_ptr<StreamWriter> writer(
|
||||||
|
builder.newStreamWriter(&std::cout));
|
||||||
|
writer->write(value);
|
||||||
|
std::cout << std::endl; // add lf and flush
|
||||||
|
\endcode
|
||||||
|
*/
|
||||||
|
class JSON_API StreamWriterBuilder : public StreamWriter::Factory {
|
||||||
|
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_;
|
||||||
|
/** \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_;
|
||||||
|
|
||||||
|
StreamWriterBuilder();
|
||||||
|
|
||||||
|
/// 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.
|
||||||
|
* In addition, there are some special settings to allow compatibility
|
||||||
|
* with the old FastWriter.
|
||||||
|
* Usage:
|
||||||
|
* \code
|
||||||
|
* OldCompressingStreamWriterBuilder b;
|
||||||
|
* b.dropNullPlaceHolders_ = true; // etc.
|
||||||
|
* StreamWriter* w = b.newStreamWriter(&std::cout);
|
||||||
|
* w.write(value);
|
||||||
|
* delete w;
|
||||||
|
* \endcode
|
||||||
|
*/
|
||||||
|
class JSON_API OldCompressingStreamWriterBuilder : public StreamWriter::Factory
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
// Note: We cannot add data-members to this class without a major version bump.
|
||||||
|
// So these might as well be completely exposed.
|
||||||
|
|
||||||
|
/** \brief Drop the "null" string from the writer's output for nullValues.
|
||||||
|
* Strictly speaking, this is not valid JSON. But when the output is being
|
||||||
|
* fed to a browser's Javascript, it makes for smaller output and the
|
||||||
|
* browser can handle the output just fine.
|
||||||
|
*/
|
||||||
|
bool dropNullPlaceholders_;
|
||||||
|
/** \brief Do not add \n at end of document.
|
||||||
|
* Normally, we add an extra newline, just because.
|
||||||
|
*/
|
||||||
|
bool omitEndingLineFeed_;
|
||||||
|
/** \brief Add a space after ':'.
|
||||||
|
* If indentation is non-empty, we surround colon with whitespace,
|
||||||
|
* e.g. " : "
|
||||||
|
* This will add back the trailing space when there is no indentation.
|
||||||
|
* This seems dubious when the entire document is on a single line,
|
||||||
|
* but we leave this here to repduce the behavior of the old `FastWriter`.
|
||||||
|
*/
|
||||||
|
bool enableYAMLCompatibility_;
|
||||||
|
|
||||||
|
OldCompressingStreamWriterBuilder()
|
||||||
|
: dropNullPlaceholders_(false)
|
||||||
|
, omitEndingLineFeed_(false)
|
||||||
|
, enableYAMLCompatibility_(false)
|
||||||
|
{}
|
||||||
|
virtual StreamWriter* newStreamWriter(std::ostream*) const;
|
||||||
|
};
|
||||||
|
|
||||||
/** \brief Abstract class for writers.
|
/** \brief Abstract class for writers.
|
||||||
* \deprecated Use StreamWriter::Builder.
|
* \deprecated Use StreamWriter::Builder.
|
||||||
*/
|
*/
|
||||||
|
@ -184,8 +184,7 @@ static std::string useStyledStreamWriter(
|
|||||||
static std::string useBuiltStyledStreamWriter(
|
static std::string useBuiltStyledStreamWriter(
|
||||||
Json::Value const& root)
|
Json::Value const& root)
|
||||||
{
|
{
|
||||||
Json::StreamWriter::Builder builder;
|
Json::StreamWriterBuilder builder;
|
||||||
builder.withCommentStyle(Json::StreamWriter::CommentStyle::All);
|
|
||||||
return writeString(root, builder);
|
return writeString(root, builder);
|
||||||
}
|
}
|
||||||
static int rewriteValueTree(
|
static int rewriteValueTree(
|
||||||
|
@ -959,78 +959,25 @@ int MyStreamWriter::write(Value const& root)
|
|||||||
sout_ << root;
|
sout_ << root;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
class StreamWriterBuilder {
|
StreamWriter::Factory::~Factory()
|
||||||
typedef StreamWriter::CommentStyle CommentStyle;
|
{}
|
||||||
CommentStyle cs_;
|
|
||||||
std::string indentation_;
|
|
||||||
bool dropNullPlaceholders_;
|
|
||||||
bool omitEndingLineFeed_;
|
|
||||||
bool enableYAMLCompatibility_;
|
|
||||||
public:
|
|
||||||
StreamWriterBuilder();
|
|
||||||
virtual ~StreamWriterBuilder();
|
|
||||||
virtual void setCommentStyle(CommentStyle cs);
|
|
||||||
virtual void setIndentation(std::string indentation);
|
|
||||||
virtual void setDropNullPlaceholders(bool v);
|
|
||||||
virtual void setOmitEndingLineFeed(bool v);
|
|
||||||
virtual void setEnableYAMLCompatibility(bool v);
|
|
||||||
virtual StreamWriter* newStreamWriter(std::ostream* sout) const;
|
|
||||||
};
|
|
||||||
StreamWriterBuilder::StreamWriterBuilder()
|
StreamWriterBuilder::StreamWriterBuilder()
|
||||||
: cs_(CommentStyle::All)
|
: cs_(StreamWriter::CommentStyle::All)
|
||||||
, indentation_("\t")
|
, indentation_("\t")
|
||||||
, dropNullPlaceholders_(false)
|
{}
|
||||||
, omitEndingLineFeed_(false)
|
|
||||||
, enableYAMLCompatibility_(false)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
StreamWriterBuilder::~StreamWriterBuilder()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
void StreamWriterBuilder::setCommentStyle(CommentStyle v)
|
|
||||||
{
|
|
||||||
cs_ = v;
|
|
||||||
}
|
|
||||||
void StreamWriterBuilder::setIndentation(std::string v)
|
|
||||||
{
|
|
||||||
indentation_ = v;
|
|
||||||
if (indentation_.empty()) cs_ = CommentStyle::None;
|
|
||||||
}
|
|
||||||
void StreamWriterBuilder::setDropNullPlaceholders(bool v)
|
|
||||||
{
|
|
||||||
dropNullPlaceholders_ = v;
|
|
||||||
}
|
|
||||||
void StreamWriterBuilder::setOmitEndingLineFeed(bool v)
|
|
||||||
{
|
|
||||||
omitEndingLineFeed_ = v;
|
|
||||||
}
|
|
||||||
void StreamWriterBuilder::setEnableYAMLCompatibility(bool v)
|
|
||||||
{
|
|
||||||
enableYAMLCompatibility_ = v;
|
|
||||||
}
|
|
||||||
StreamWriter* StreamWriterBuilder::newStreamWriter(std::ostream* stream) const
|
StreamWriter* StreamWriterBuilder::newStreamWriter(std::ostream* stream) const
|
||||||
{
|
{
|
||||||
std::string colonSymbol = " : ";
|
std::string colonSymbol = " : ";
|
||||||
if (indentation_.empty()) {
|
if (indentation_.empty()) {
|
||||||
if (enableYAMLCompatibility_) {
|
colonSymbol = ":";
|
||||||
colonSymbol = ": ";
|
|
||||||
} else {
|
|
||||||
colonSymbol = ":";
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
std::string nullSymbol = "null";
|
std::string nullSymbol = "null";
|
||||||
if (dropNullPlaceholders_) {
|
std::string endingLineFeedSymbol = "";
|
||||||
nullSymbol = "";
|
|
||||||
}
|
|
||||||
std::string endingLineFeedSymbol = "\n";
|
|
||||||
if (omitEndingLineFeed_) {
|
|
||||||
endingLineFeedSymbol = "";
|
|
||||||
}
|
|
||||||
return new BuiltStyledStreamWriter(stream,
|
return new BuiltStyledStreamWriter(stream,
|
||||||
indentation_, cs_,
|
indentation_, cs_,
|
||||||
colonSymbol, nullSymbol, endingLineFeedSymbol);
|
colonSymbol, nullSymbol, endingLineFeedSymbol);
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
// This might become public someday.
|
// This might become public someday.
|
||||||
class StreamWriterBuilderFactory {
|
class StreamWriterBuilderFactory {
|
||||||
public:
|
public:
|
||||||
@ -1044,51 +991,31 @@ StreamWriterBuilder* StreamWriterBuilderFactory::newStreamWriterBuilder() const
|
|||||||
{
|
{
|
||||||
return new StreamWriterBuilder;
|
return new StreamWriterBuilder;
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
StreamWriter::Builder::Builder()
|
StreamWriter* OldCompressingStreamWriterBuilder::newStreamWriter(
|
||||||
: own_(StreamWriterBuilderFactory().newStreamWriterBuilder())
|
std::ostream* stream) const
|
||||||
{
|
{
|
||||||
}
|
std::string colonSymbol = " : ";
|
||||||
StreamWriter::Builder::~Builder()
|
if (enableYAMLCompatibility_) {
|
||||||
{
|
colonSymbol = ": ";
|
||||||
delete own_;
|
} else {
|
||||||
}
|
colonSymbol = ":";
|
||||||
StreamWriter::Builder::Builder(Builder const&)
|
}
|
||||||
: own_(nullptr)
|
std::string nullSymbol = "null";
|
||||||
{abort();}
|
if (dropNullPlaceholders_) {
|
||||||
void StreamWriter::Builder::operator=(Builder const&)
|
nullSymbol = "";
|
||||||
{abort();}
|
}
|
||||||
StreamWriter::Builder& StreamWriter::Builder::withCommentStyle(CommentStyle v)
|
std::string endingLineFeedSymbol = "\n";
|
||||||
{
|
if (omitEndingLineFeed_) {
|
||||||
own_->setCommentStyle(v);
|
endingLineFeedSymbol = "";
|
||||||
return *this;
|
}
|
||||||
}
|
return new BuiltStyledStreamWriter(stream,
|
||||||
StreamWriter::Builder& StreamWriter::Builder::withIndentation(std::string v)
|
"", StreamWriter::CommentStyle::None,
|
||||||
{
|
colonSymbol, nullSymbol, endingLineFeedSymbol);
|
||||||
own_->setIndentation(v);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
StreamWriter::Builder& StreamWriter::Builder::withDropNullPlaceholders(bool v)
|
|
||||||
{
|
|
||||||
own_->setDropNullPlaceholders(v);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
StreamWriter::Builder& StreamWriter::Builder::withOmitEndingLineFeed(bool v)
|
|
||||||
{
|
|
||||||
own_->setOmitEndingLineFeed(v);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
StreamWriter::Builder& StreamWriter::Builder::withEnableYAMLCompatibility(bool v)
|
|
||||||
{
|
|
||||||
own_->setEnableYAMLCompatibility(v);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
StreamWriter* StreamWriter::Builder::newStreamWriter(std::ostream* sout) const
|
|
||||||
{
|
|
||||||
return own_->newStreamWriter(sout);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string writeString(Value const& root, StreamWriter::Builder const& builder) {
|
std::string writeString(Value const& root, StreamWriter::Factory const& builder) {
|
||||||
std::ostringstream sout;
|
std::ostringstream sout;
|
||||||
std::unique_ptr<StreamWriter> const sw(builder.newStreamWriter(&sout));
|
std::unique_ptr<StreamWriter> const sw(builder.newStreamWriter(&sout));
|
||||||
sw->write(root);
|
sw->write(root);
|
||||||
@ -1096,9 +1023,7 @@ std::string writeString(Value const& root, StreamWriter::Builder const& builder)
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::ostream& operator<<(std::ostream& sout, Value const& root) {
|
std::ostream& operator<<(std::ostream& sout, Value const& root) {
|
||||||
StreamWriter::Builder builder;
|
StreamWriterBuilder builder;
|
||||||
builder.withCommentStyle(StreamWriter::CommentStyle::All);
|
|
||||||
builder.withIndentation("\t");
|
|
||||||
std::shared_ptr<StreamWriter> writer(builder.newStreamWriter(&sout));
|
std::shared_ptr<StreamWriter> writer(builder.newStreamWriter(&sout));
|
||||||
writer->write(root);
|
writer->write(root);
|
||||||
return sout;
|
return sout;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user