Skip to content

Commit c41609b

Browse files
committed
set output stream in write(), not in builder
1 parent b56381a commit c41609b

File tree

2 files changed

+51
-68
lines changed

2 files changed

+51
-68
lines changed

include/json/writer.h

Lines changed: 19 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -31,15 +31,15 @@ class Value;
3131
using namespace Json;
3232
void writeToStdout(StreamWriter::Factory const& factory, Value const& value) {
3333
std::unique_ptr<StreamWriter> const writer(
34-
factory.newStreamWriter(&std::cout));
35-
writer->write(value);
34+
factory.newStreamWriter());
35+
writer->write(value, &std::cout);
3636
std::cout << std::endl; // add lf and flush
3737
}
3838
\endcode
3939
*/
4040
class JSON_API StreamWriter {
4141
protected:
42-
std::ostream& sout_; // not owned; will not delete
42+
std::ostream* sout_; // not owned; will not delete
4343
public:
4444
/// Scoped enums are not available until C++11.
4545
struct CommentStyle {
@@ -51,24 +51,25 @@ class JSON_API StreamWriter {
5151
};
5252
};
5353

54-
/// Keep a reference, but do not take ownership of `sout`.
55-
StreamWriter(std::ostream* sout);
54+
StreamWriter();
5655
virtual ~StreamWriter();
57-
/// Write Value into document as configured in sub-class.
58-
/// \return zero on success
59-
/// \throw std::exception possibly, depending on configuration
60-
virtual int write(Value const& root) = 0;
56+
/** Write Value into document as configured in sub-class.
57+
Do not take ownership of sout, but maintain a reference during function.
58+
\pre sout != NULL
59+
\return zero on success
60+
\throw std::exception possibly, depending on configuration
61+
*/
62+
virtual int write(Value const& root, std::ostream* sout) = 0;
6163

6264
/** \brief A simple abstract factory.
6365
*/
6466
class JSON_API Factory {
6567
public:
6668
virtual ~Factory();
6769
/** \brief Allocate a CharReader via operator new().
68-
* Do not take ownership of sout, but maintain a reference.
6970
* \throw std::exception if something goes wrong (e.g. invalid settings)
7071
*/
71-
virtual StreamWriter* newStreamWriter(std::ostream* sout) const = 0;
72+
virtual StreamWriter* newStreamWriter() const = 0;
7273
}; // Factory
7374
}; // StreamWriter
7475

@@ -88,8 +89,8 @@ std::string writeString(StreamWriter::Factory const& factory, Value const& root)
8889
builder.settings_["commentStyle"] = "None";
8990
builder.settings_["indentation"] = " "; // or whatever you like
9091
std::unique_ptr<Json::StreamWriter> writer(
91-
builder.newStreamWriter(&std::cout));
92-
writer->write(value);
92+
builder.newStreamWriter());
93+
writer->write(value, &std::cout);
9394
std::cout << std::endl; // add lf and flush
9495
\endcode
9596
*/
@@ -112,10 +113,10 @@ class JSON_API StreamWriterBuilder : public StreamWriter::Factory {
112113
StreamWriterBuilder();
113114
virtual ~StreamWriterBuilder();
114115

115-
/** Do not take ownership of sout, but maintain a reference.
116+
/**
116117
* \throw std::exception if something goes wrong (e.g. invalid settings)
117118
*/
118-
virtual StreamWriter* newStreamWriter(std::ostream* sout) const;
119+
virtual StreamWriter* newStreamWriter() const;
119120

120121
/** \return true if 'settings' are legal and consistent;
121122
* otherwise, indicate bad settings via 'invalid'.
@@ -137,8 +138,8 @@ class JSON_API StreamWriterBuilder : public StreamWriter::Factory {
137138
* \code
138139
* OldCompressingStreamWriterBuilder b;
139140
* b.dropNullPlaceHolders_ = true; // etc.
140-
* StreamWriter* w = b.newStreamWriter(&std::cout);
141-
* w->write(value);
141+
* StreamWriter* w = b.newStreamWriter();
142+
* w->write(value, &std::cout);
142143
* delete w;
143144
* \endcode
144145
*
@@ -174,7 +175,7 @@ class JSON_API OldCompressingStreamWriterBuilder : public StreamWriter::Factory
174175
, omitEndingLineFeed_(false)
175176
, enableYAMLCompatibility_(false)
176177
{}
177-
virtual StreamWriter* newStreamWriter(std::ostream*) const;
178+
virtual StreamWriter* newStreamWriter() const;
178179
};
179180

180181
/** \brief Abstract class for writers.

src/lib_json/json_writer.cpp

Lines changed: 32 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -679,13 +679,12 @@ bool StyledStreamWriter::hasCommentForValue(const Value& value) {
679679
struct BuiltStyledStreamWriter : public StreamWriter
680680
{
681681
BuiltStyledStreamWriter(
682-
std::ostream* sout,
683682
std::string const& indentation,
684683
StreamWriter::CommentStyle::Enum cs,
685684
std::string const& colonSymbol,
686685
std::string const& nullSymbol,
687686
std::string const& endingLineFeedSymbol);
688-
virtual int write(Value const& root);
687+
virtual int write(Value const& root, std::ostream* sout);
689688
private:
690689
void writeValue(Value const& value);
691690
void writeArrayValue(Value const& value);
@@ -713,14 +712,12 @@ struct BuiltStyledStreamWriter : public StreamWriter
713712
bool indented_ : 1;
714713
};
715714
BuiltStyledStreamWriter::BuiltStyledStreamWriter(
716-
std::ostream* sout,
717715
std::string const& indentation,
718716
StreamWriter::CommentStyle::Enum cs,
719717
std::string const& colonSymbol,
720718
std::string const& nullSymbol,
721719
std::string const& endingLineFeedSymbol)
722-
: StreamWriter(sout)
723-
, rightMargin_(74)
720+
: rightMargin_(74)
724721
, indentation_(indentation)
725722
, cs_(cs)
726723
, colonSymbol_(colonSymbol)
@@ -730,8 +727,9 @@ BuiltStyledStreamWriter::BuiltStyledStreamWriter(
730727
, indented_(false)
731728
{
732729
}
733-
int BuiltStyledStreamWriter::write(Value const& root)
730+
int BuiltStyledStreamWriter::write(Value const& root, std::ostream* sout)
734731
{
732+
sout_ = sout;
735733
addChildValues_ = false;
736734
indented_ = true;
737735
indentString_ = "";
@@ -740,7 +738,8 @@ int BuiltStyledStreamWriter::write(Value const& root)
740738
indented_ = true;
741739
writeValue(root);
742740
writeCommentAfterValueOnSameLine(root);
743-
sout_ << endingLineFeedSymbol_;
741+
*sout_ << endingLineFeedSymbol_;
742+
sout_ = NULL;
744743
return 0;
745744
}
746745
void BuiltStyledStreamWriter::writeValue(Value const& value) {
@@ -779,13 +778,13 @@ void BuiltStyledStreamWriter::writeValue(Value const& value) {
779778
Value const& childValue = value[name];
780779
writeCommentBeforeValue(childValue);
781780
writeWithIndent(valueToQuotedString(name.c_str()));
782-
sout_ << colonSymbol_;
781+
*sout_ << colonSymbol_;
783782
writeValue(childValue);
784783
if (++it == members.end()) {
785784
writeCommentAfterValueOnSameLine(childValue);
786785
break;
787786
}
788-
sout_ << ",";
787+
*sout_ << ",";
789788
writeCommentAfterValueOnSameLine(childValue);
790789
}
791790
unindent();
@@ -821,23 +820,23 @@ void BuiltStyledStreamWriter::writeArrayValue(Value const& value) {
821820
writeCommentAfterValueOnSameLine(childValue);
822821
break;
823822
}
824-
sout_ << ",";
823+
*sout_ << ",";
825824
writeCommentAfterValueOnSameLine(childValue);
826825
}
827826
unindent();
828827
writeWithIndent("]");
829828
} else // output on a single line
830829
{
831830
assert(childValues_.size() == size);
832-
sout_ << "[";
833-
if (!indentation_.empty()) sout_ << " ";
831+
*sout_ << "[";
832+
if (!indentation_.empty()) *sout_ << " ";
834833
for (unsigned index = 0; index < size; ++index) {
835834
if (index > 0)
836-
sout_ << ", ";
837-
sout_ << childValues_[index];
835+
*sout_ << ", ";
836+
*sout_ << childValues_[index];
838837
}
839-
if (!indentation_.empty()) sout_ << " ";
840-
sout_ << "]";
838+
if (!indentation_.empty()) *sout_ << " ";
839+
*sout_ << "]";
841840
}
842841
}
843842
}
@@ -874,7 +873,7 @@ void BuiltStyledStreamWriter::pushValue(std::string const& value) {
874873
if (addChildValues_)
875874
childValues_.push_back(value);
876875
else
877-
sout_ << value;
876+
*sout_ << value;
878877
}
879878

880879
void BuiltStyledStreamWriter::writeIndent() {
@@ -885,13 +884,13 @@ void BuiltStyledStreamWriter::writeIndent() {
885884

886885
if (!indentation_.empty()) {
887886
// In this case, drop newlines too.
888-
sout_ << '\n' << indentString_;
887+
*sout_ << '\n' << indentString_;
889888
}
890889
}
891890

892891
void BuiltStyledStreamWriter::writeWithIndent(std::string const& value) {
893892
if (!indented_) writeIndent();
894-
sout_ << value;
893+
*sout_ << value;
895894
indented_ = false;
896895
}
897896

@@ -911,11 +910,11 @@ void BuiltStyledStreamWriter::writeCommentBeforeValue(Value const& root) {
911910
const std::string& comment = root.getComment(commentBefore);
912911
std::string::const_iterator iter = comment.begin();
913912
while (iter != comment.end()) {
914-
sout_ << *iter;
913+
*sout_ << *iter;
915914
if (*iter == '\n' &&
916915
(iter != comment.end() && *(iter + 1) == '/'))
917916
// writeIndent(); // would write extra newline
918-
sout_ << indentString_;
917+
*sout_ << indentString_;
919918
++iter;
920919
}
921920
indented_ = false;
@@ -924,11 +923,11 @@ void BuiltStyledStreamWriter::writeCommentBeforeValue(Value const& root) {
924923
void BuiltStyledStreamWriter::writeCommentAfterValueOnSameLine(Value const& root) {
925924
if (cs_ == CommentStyle::None) return;
926925
if (root.hasComment(commentAfterOnSameLine))
927-
sout_ << " " + root.getComment(commentAfterOnSameLine);
926+
*sout_ << " " + root.getComment(commentAfterOnSameLine);
928927

929928
if (root.hasComment(commentAfter)) {
930929
writeIndent();
931-
sout_ << root.getComment(commentAfter);
930+
*sout_ << root.getComment(commentAfter);
932931
}
933932
}
934933

@@ -942,8 +941,8 @@ bool BuiltStyledStreamWriter::hasCommentForValue(const Value& value) {
942941
///////////////
943942
// StreamWriter
944943

945-
StreamWriter::StreamWriter(std::ostream* sout)
946-
: sout_(*sout)
944+
StreamWriter::StreamWriter()
945+
: sout_(NULL)
947946
{
948947
}
949948
StreamWriter::~StreamWriter()
@@ -957,7 +956,7 @@ StreamWriterBuilder::StreamWriterBuilder()
957956
}
958957
StreamWriterBuilder::~StreamWriterBuilder()
959958
{}
960-
StreamWriter* StreamWriterBuilder::newStreamWriter(std::ostream* stream) const
959+
StreamWriter* StreamWriterBuilder::newStreamWriter() const
961960
{
962961
if (!validate(NULL)) throw std::runtime_error("invalid settings");
963962
// TODO: Maybe serialize the invalid settings into the exception.
@@ -978,7 +977,7 @@ StreamWriter* StreamWriterBuilder::newStreamWriter(std::ostream* stream) const
978977
}
979978
std::string nullSymbol = "null";
980979
std::string endingLineFeedSymbol = "";
981-
return new BuiltStyledStreamWriter(stream,
980+
return new BuiltStyledStreamWriter(
982981
indentation, cs,
983982
colonSymbol, nullSymbol, endingLineFeedSymbol);
984983
}
@@ -1015,24 +1014,7 @@ void StreamWriterBuilder::setDefaults(Json::Value* settings)
10151014
//! [StreamWriterBuilderDefaults]
10161015
}
10171016

1018-
/*
1019-
// This might become public someday.
1020-
class StreamWriterBuilderFactory {
1021-
public:
1022-
virtual ~StreamWriterBuilderFactory();
1023-
virtual StreamWriterBuilder* newStreamWriterBuilder() const;
1024-
};
1025-
StreamWriterBuilderFactory::~StreamWriterBuilderFactory()
1026-
{
1027-
}
1028-
StreamWriterBuilder* StreamWriterBuilderFactory::newStreamWriterBuilder() const
1029-
{
1030-
return new StreamWriterBuilder;
1031-
}
1032-
*/
1033-
1034-
StreamWriter* OldCompressingStreamWriterBuilder::newStreamWriter(
1035-
std::ostream* stream) const
1017+
StreamWriter* OldCompressingStreamWriterBuilder::newStreamWriter() const
10361018
{
10371019
std::string colonSymbol = " : ";
10381020
if (enableYAMLCompatibility_) {
@@ -1048,22 +1030,22 @@ StreamWriter* OldCompressingStreamWriterBuilder::newStreamWriter(
10481030
if (omitEndingLineFeed_) {
10491031
endingLineFeedSymbol = "";
10501032
}
1051-
return new BuiltStyledStreamWriter(stream,
1033+
return new BuiltStyledStreamWriter(
10521034
"", StreamWriter::CommentStyle::None,
10531035
colonSymbol, nullSymbol, endingLineFeedSymbol);
10541036
}
10551037

10561038
std::string writeString(StreamWriter::Factory const& builder, Value const& root) {
10571039
std::ostringstream sout;
1058-
StreamWriterPtr const writer(builder.newStreamWriter(&sout));
1059-
writer->write(root);
1040+
StreamWriterPtr const writer(builder.newStreamWriter());
1041+
writer->write(root, &sout);
10601042
return sout.str();
10611043
}
10621044

10631045
std::ostream& operator<<(std::ostream& sout, Value const& root) {
10641046
StreamWriterBuilder builder;
1065-
StreamWriterPtr const writer(builder.newStreamWriter(&sout));
1066-
writer->write(root);
1047+
StreamWriterPtr const writer(builder.newStreamWriter());
1048+
writer->write(root, &sout);
10671049
return sout;
10681050
}
10691051

0 commit comments

Comments
 (0)