Skip to content

Commit 54b8e69

Browse files
committed
Merge pull request open-source-parsers#132 from cdunn2001/builder
StreamWriter::Builder Deprecate old Writers, but include them in tests. This should still be binary-compatible with 1.3.0.
2 parents 948f290 + c7b39c2 commit 54b8e69

File tree

5 files changed

+561
-22
lines changed

5 files changed

+561
-22
lines changed

doc/jsoncpp.dox

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -73,24 +73,31 @@ for ( int index = 0; index < plugins.size(); ++index ) // Iterates over the seq
7373
setIndentLength( root["indent"].get("length", 3).asInt() );
7474
setIndentUseSpace( root["indent"].get("use_space", true).asBool() );
7575

76-
// ...
77-
// At application shutdown to make the new configuration document:
7876
// Since Json::Value has implicit constructor for all value types, it is not
7977
// necessary to explicitly construct the Json::Value object:
8078
root["encoding"] = getCurrentEncoding();
8179
root["indent"]["length"] = getCurrentIndentLength();
8280
root["indent"]["use_space"] = getCurrentIndentUseSpace();
8381

84-
Json::StyledWriter writer;
82+
// To write into a steam with minimal memory overhead,
83+
// create a Builder for a StreamWriter.
84+
Json::StreamWriter::Builder builder;
85+
builder.withIndentation(" "); // or whatever you like
86+
87+
// Then build a StreamWriter.
88+
// (Of course, you can write to std::ostringstream if you prefer.)
89+
std::shared_ptr<Json::StreamWriter> writer(
90+
builder.newStreamWriter( &std::cout );
91+
8592
// Make a new JSON document for the configuration. Preserve original comments.
86-
std::string outputConfig = writer.write( root );
93+
writer->write( root );
94+
95+
// If you like the defaults, you can insert directly into a stream.
96+
std::cout << root;
8797

88-
// You can also use streams. This will put the contents of any JSON
98+
// You can also read from a stream. This will put the contents of any JSON
8999
// stream at a particular sub-value, if you'd like.
90100
std::cin >> root["subtree"];
91-
92-
// And you can write to a stream, using the StyledWriter automatically.
93-
std::cout << root;
94101
\endcode
95102

96103
\section _pbuild Build instructions

include/json/writer.h

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,88 @@
2222
namespace Json {
2323

2424
class Value;
25+
class StreamWriterBuilder;
26+
27+
/**
28+
29+
Usage:
30+
31+
using namespace Json;
32+
Value value;
33+
StreamWriter::Builder builder;
34+
builder.withCommentStyle(StreamWriter::CommentStyle::None);
35+
std::shared_ptr<StreamWriter> writer(
36+
builder.newStreamWriter(&std::cout));
37+
writer->write(value);
38+
std::cout.flush();
39+
*/
40+
class JSON_API StreamWriter {
41+
protected:
42+
std::ostream& sout_; // not owned; will not delete
43+
public:
44+
/// `All`: Keep all comments.
45+
/// `None`: Drop all comments.
46+
/// Use `Most` to recover the odd behavior of previous versions.
47+
/// Only `All` is currently implemented.
48+
enum class CommentStyle {None, Most, All};
49+
50+
/// Keep a reference, but do not take ownership of `sout`.
51+
StreamWriter(std::ostream* sout);
52+
virtual ~StreamWriter();
53+
/// Write Value into document as configured in sub-class.
54+
/// \return zero on success
55+
/// \throw std::exception possibly, depending on configuration
56+
virtual int write(Value const& root) = 0;
57+
58+
/// Because this Builder is non-virtual, we can safely add
59+
/// methods without a major version bump.
60+
/// \see http://stackoverflow.com/questions/14875052/pure-virtual-functions-and-binary-compatibility
61+
class Builder {
62+
StreamWriterBuilder* own_;
63+
Builder(Builder const&); // noncopyable
64+
void operator=(Builder const&); // noncopyable
65+
public:
66+
Builder();
67+
~Builder(); // delete underlying StreamWriterBuilder
68+
69+
Builder& withCommentStyle(CommentStyle cs); /// default: All
70+
/** \brief Write in human-friendly style.
71+
72+
If "", then skip all indentation, newlines, and comments,
73+
which implies CommentStyle::None.
74+
Default: "\t"
75+
*/
76+
Builder& withIndentation(std::string indentation);
77+
/** \brief Drop the "null" string from the writer's output for nullValues.
78+
* Strictly speaking, this is not valid JSON. But when the output is being
79+
* fed to a browser's Javascript, it makes for smaller output and the
80+
* browser can handle the output just fine.
81+
*/
82+
Builder& withDropNullPlaceholders(bool v);
83+
/** \brief Do not add \n at end of document.
84+
* Normally, we add an extra newline, just because.
85+
*/
86+
Builder& withOmitEndingLineFeed(bool v);
87+
/** \brief Add a space after ':'.
88+
* If indentation is non-empty, we surround colon with whitespace,
89+
* e.g. " : "
90+
* This will add back the trailing space when there is no indentation.
91+
* This seems dubious when the entire document is on a single line,
92+
* but we leave this here to repduce the behavior of the old `FastWriter`.
93+
*/
94+
Builder& withEnableYAMLCompatibility(bool v);
95+
96+
/// Do not take ownership of sout, but maintain a reference.
97+
StreamWriter* newStreamWriter(std::ostream* sout) const;
98+
};
99+
};
100+
101+
/// \brief Write into stringstream, then return string, for convenience.
102+
std::string writeString(Value const& root, StreamWriter::Builder const& builder);
103+
25104

26105
/** \brief Abstract class for writers.
106+
* \deprecated Use StreamWriter::Builder.
27107
*/
28108
class JSON_API Writer {
29109
public:
@@ -39,6 +119,7 @@ class JSON_API Writer {
39119
*consumption,
40120
* but may be usefull to support feature such as RPC where bandwith is limited.
41121
* \sa Reader, Value
122+
* \deprecated Use StreamWriter::Builder.
42123
*/
43124
class JSON_API FastWriter : public Writer {
44125
public:
@@ -90,6 +171,7 @@ class JSON_API FastWriter : public Writer {
90171
*#CommentPlacement.
91172
*
92173
* \sa Reader, Value, Value::setComment()
174+
* \deprecated Use StreamWriter::Builder.
93175
*/
94176
class JSON_API StyledWriter : public Writer {
95177
public:
@@ -151,6 +233,7 @@ class JSON_API StyledWriter : public Writer {
151233
*
152234
* \param indentation Each level will be indented by this amount extra.
153235
* \sa Reader, Value, Value::setComment()
236+
* \deprecated Use StreamWriter::Builder.
154237
*/
155238
class JSON_API StyledStreamWriter {
156239
public:

src/jsontestrunner/main.cpp

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,6 @@ static int parseAndSaveValueTree(const std::string& input,
151151
reader.getFormattedErrorMessages().c_str());
152152
return 1;
153153
}
154-
155154
if (!parseOnly) {
156155
FILE* factual = fopen(actual.c_str(), "wt");
157156
if (!factual) {
@@ -182,6 +181,13 @@ static std::string useStyledStreamWriter(
182181
writer.write(sout, root);
183182
return sout.str();
184183
}
184+
static std::string useBuiltStyledStreamWriter(
185+
Json::Value const& root)
186+
{
187+
Json::StreamWriter::Builder builder;
188+
builder.withCommentStyle(Json::StreamWriter::CommentStyle::All);
189+
return writeString(root, builder);
190+
}
185191
static int rewriteValueTree(
186192
const std::string& rewritePath,
187193
const Json::Value& root,
@@ -248,6 +254,8 @@ static int parseCommandLine(
248254
opts->write = &useStyledWriter;
249255
} else if (writerName == "StyledStreamWriter") {
250256
opts->write = &useStyledStreamWriter;
257+
} else if (writerName == "BuiltStyledStreamWriter") {
258+
opts->write = &useBuiltStyledStreamWriter;
251259
} else {
252260
printf("Unknown '--json-writer %s'\n", writerName.c_str());
253261
return 4;

0 commit comments

Comments
 (0)