using namespace Json;
void writeToStdout(StreamWriter::Factory const& factory, Value const& value) {
std::unique_ptr<StreamWriter> const writer(
- factory.newStreamWriter(&std::cout));
- writer->write(value);
+ factory.newStreamWriter());
+ writer->write(value, &std::cout);
std::cout << std::endl; // add lf and flush
}
\endcode
*/
class JSON_API StreamWriter {
protected:
- std::ostream& sout_; // not owned; will not delete
+ std::ostream* sout_; // not owned; will not delete
public:
/// Scoped enums are not available until C++11.
struct CommentStyle {
};
};
- /// Keep a reference, but do not take ownership of `sout`.
- StreamWriter(std::ostream* sout);
+ StreamWriter();
virtual ~StreamWriter();
- /// Write Value into document as configured in sub-class.
- /// \return zero on success
- /// \throw std::exception possibly, depending on configuration
- virtual int write(Value const& root) = 0;
+ /** Write Value into document as configured in sub-class.
+ Do not take ownership of sout, but maintain a reference during function.
+ \pre sout != NULL
+ \return zero on success
+ \throw std::exception possibly, depending on configuration
+ */
+ virtual int write(Value const& root, std::ostream* sout) = 0;
/** \brief A simple abstract factory.
*/
public:
virtual ~Factory();
/** \brief Allocate a CharReader via operator new().
- * Do not take ownership of sout, but maintain a reference.
* \throw std::exception if something goes wrong (e.g. invalid settings)
*/
- virtual StreamWriter* newStreamWriter(std::ostream* sout) const = 0;
+ virtual StreamWriter* newStreamWriter() const = 0;
}; // Factory
}; // StreamWriter
builder.settings_["commentStyle"] = "None";
builder.settings_["indentation"] = " "; // or whatever you like
std::unique_ptr<Json::StreamWriter> writer(
- builder.newStreamWriter(&std::cout));
- writer->write(value);
+ builder.newStreamWriter());
+ writer->write(value, &std::cout);
std::cout << std::endl; // add lf and flush
\endcode
*/
StreamWriterBuilder();
virtual ~StreamWriterBuilder();
- /** Do not take ownership of sout, but maintain a reference.
+ /**
* \throw std::exception if something goes wrong (e.g. invalid settings)
*/
- virtual StreamWriter* newStreamWriter(std::ostream* sout) const;
+ virtual StreamWriter* newStreamWriter() const;
/** \return true if 'settings' are legal and consistent;
* otherwise, indicate bad settings via 'invalid'.
* \code
* OldCompressingStreamWriterBuilder b;
* b.dropNullPlaceHolders_ = true; // etc.
- * StreamWriter* w = b.newStreamWriter(&std::cout);
- * w->write(value);
+ * StreamWriter* w = b.newStreamWriter();
+ * w->write(value, &std::cout);
* delete w;
* \endcode
*
, omitEndingLineFeed_(false)
, enableYAMLCompatibility_(false)
{}
- virtual StreamWriter* newStreamWriter(std::ostream*) const;
+ virtual StreamWriter* newStreamWriter() const;
};
/** \brief Abstract class for writers.
struct BuiltStyledStreamWriter : public StreamWriter
{
BuiltStyledStreamWriter(
- std::ostream* sout,
std::string const& indentation,
StreamWriter::CommentStyle::Enum cs,
std::string const& colonSymbol,
std::string const& nullSymbol,
std::string const& endingLineFeedSymbol);
- virtual int write(Value const& root);
+ virtual int write(Value const& root, std::ostream* sout);
private:
void writeValue(Value const& value);
void writeArrayValue(Value const& value);
bool indented_ : 1;
};
BuiltStyledStreamWriter::BuiltStyledStreamWriter(
- std::ostream* sout,
std::string const& indentation,
StreamWriter::CommentStyle::Enum cs,
std::string const& colonSymbol,
std::string const& nullSymbol,
std::string const& endingLineFeedSymbol)
- : StreamWriter(sout)
- , rightMargin_(74)
+ : rightMargin_(74)
, indentation_(indentation)
, cs_(cs)
, colonSymbol_(colonSymbol)
, indented_(false)
{
}
-int BuiltStyledStreamWriter::write(Value const& root)
+int BuiltStyledStreamWriter::write(Value const& root, std::ostream* sout)
{
+ sout_ = sout;
addChildValues_ = false;
indented_ = true;
indentString_ = "";
indented_ = true;
writeValue(root);
writeCommentAfterValueOnSameLine(root);
- sout_ << endingLineFeedSymbol_;
+ *sout_ << endingLineFeedSymbol_;
+ sout_ = NULL;
return 0;
}
void BuiltStyledStreamWriter::writeValue(Value const& value) {
Value const& childValue = value[name];
writeCommentBeforeValue(childValue);
writeWithIndent(valueToQuotedString(name.c_str()));
- sout_ << colonSymbol_;
+ *sout_ << colonSymbol_;
writeValue(childValue);
if (++it == members.end()) {
writeCommentAfterValueOnSameLine(childValue);
break;
}
- sout_ << ",";
+ *sout_ << ",";
writeCommentAfterValueOnSameLine(childValue);
}
unindent();
writeCommentAfterValueOnSameLine(childValue);
break;
}
- sout_ << ",";
+ *sout_ << ",";
writeCommentAfterValueOnSameLine(childValue);
}
unindent();
} else // output on a single line
{
assert(childValues_.size() == size);
- sout_ << "[";
- if (!indentation_.empty()) sout_ << " ";
+ *sout_ << "[";
+ if (!indentation_.empty()) *sout_ << " ";
for (unsigned index = 0; index < size; ++index) {
if (index > 0)
- sout_ << ", ";
- sout_ << childValues_[index];
+ *sout_ << ", ";
+ *sout_ << childValues_[index];
}
- if (!indentation_.empty()) sout_ << " ";
- sout_ << "]";
+ if (!indentation_.empty()) *sout_ << " ";
+ *sout_ << "]";
}
}
}
if (addChildValues_)
childValues_.push_back(value);
else
- sout_ << value;
+ *sout_ << value;
}
void BuiltStyledStreamWriter::writeIndent() {
if (!indentation_.empty()) {
// In this case, drop newlines too.
- sout_ << '\n' << indentString_;
+ *sout_ << '\n' << indentString_;
}
}
void BuiltStyledStreamWriter::writeWithIndent(std::string const& value) {
if (!indented_) writeIndent();
- sout_ << value;
+ *sout_ << value;
indented_ = false;
}
const std::string& comment = root.getComment(commentBefore);
std::string::const_iterator iter = comment.begin();
while (iter != comment.end()) {
- sout_ << *iter;
+ *sout_ << *iter;
if (*iter == '\n' &&
(iter != comment.end() && *(iter + 1) == '/'))
// writeIndent(); // would write extra newline
- sout_ << indentString_;
+ *sout_ << indentString_;
++iter;
}
indented_ = false;
void BuiltStyledStreamWriter::writeCommentAfterValueOnSameLine(Value const& root) {
if (cs_ == CommentStyle::None) return;
if (root.hasComment(commentAfterOnSameLine))
- sout_ << " " + root.getComment(commentAfterOnSameLine);
+ *sout_ << " " + root.getComment(commentAfterOnSameLine);
if (root.hasComment(commentAfter)) {
writeIndent();
- sout_ << root.getComment(commentAfter);
+ *sout_ << root.getComment(commentAfter);
}
}
///////////////
// StreamWriter
-StreamWriter::StreamWriter(std::ostream* sout)
- : sout_(*sout)
+StreamWriter::StreamWriter()
+ : sout_(NULL)
{
}
StreamWriter::~StreamWriter()
}
StreamWriterBuilder::~StreamWriterBuilder()
{}
-StreamWriter* StreamWriterBuilder::newStreamWriter(std::ostream* stream) const
+StreamWriter* StreamWriterBuilder::newStreamWriter() const
{
if (!validate(NULL)) throw std::runtime_error("invalid settings");
// TODO: Maybe serialize the invalid settings into the exception.
}
std::string nullSymbol = "null";
std::string endingLineFeedSymbol = "";
- return new BuiltStyledStreamWriter(stream,
+ return new BuiltStyledStreamWriter(
indentation, cs,
colonSymbol, nullSymbol, endingLineFeedSymbol);
}
//! [StreamWriterBuilderDefaults]
}
-/*
-// This might become public someday.
-class StreamWriterBuilderFactory {
-public:
- virtual ~StreamWriterBuilderFactory();
- virtual StreamWriterBuilder* newStreamWriterBuilder() const;
-};
-StreamWriterBuilderFactory::~StreamWriterBuilderFactory()
-{
-}
-StreamWriterBuilder* StreamWriterBuilderFactory::newStreamWriterBuilder() const
-{
- return new StreamWriterBuilder;
-}
-*/
-
-StreamWriter* OldCompressingStreamWriterBuilder::newStreamWriter(
- std::ostream* stream) const
+StreamWriter* OldCompressingStreamWriterBuilder::newStreamWriter() const
{
std::string colonSymbol = " : ";
if (enableYAMLCompatibility_) {
if (omitEndingLineFeed_) {
endingLineFeedSymbol = "";
}
- return new BuiltStyledStreamWriter(stream,
+ return new BuiltStyledStreamWriter(
"", StreamWriter::CommentStyle::None,
colonSymbol, nullSymbol, endingLineFeedSymbol);
}
std::string writeString(StreamWriter::Factory const& builder, Value const& root) {
std::ostringstream sout;
- StreamWriterPtr const writer(builder.newStreamWriter(&sout));
- writer->write(root);
+ StreamWriterPtr const writer(builder.newStreamWriter());
+ writer->write(root, &sout);
return sout.str();
}
std::ostream& operator<<(std::ostream& sout, Value const& root) {
StreamWriterBuilder builder;
- StreamWriterPtr const writer(builder.newStreamWriter(&sout));
- writer->write(root);
+ StreamWriterPtr const writer(builder.newStreamWriter());
+ writer->write(root, &sout);
return sout;
}