set output stream in write(), not in builder
authorChristopher Dunn <cdunn2001@gmail.com>
Tue, 10 Feb 2015 00:44:53 +0000 (18:44 -0600)
committerChristopher Dunn <cdunn2001@gmail.com>
Tue, 10 Feb 2015 00:44:53 +0000 (18:44 -0600)
include/json/writer.h
src/lib_json/json_writer.cpp

index 7dad7f6..c62d080 100644 (file)
@@ -31,15 +31,15 @@ Usage:
   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 {
@@ -51,13 +51,15 @@ public:
     };
   };
 
-  /// 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.
    */
@@ -65,10 +67,9 @@ public:
   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
 
@@ -88,8 +89,8 @@ Usage:
   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
 */
@@ -112,10 +113,10 @@ public:
   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'.
@@ -137,8 +138,8 @@ public:
  * \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
  *
@@ -174,7 +175,7 @@ public:
     , omitEndingLineFeed_(false)
     , enableYAMLCompatibility_(false)
   {}
-  virtual StreamWriter* newStreamWriter(std::ostream*) const;
+  virtual StreamWriter* newStreamWriter() const;
 };
 
 /** \brief Abstract class for writers.
index 2b73d79..d00f501 100644 (file)
@@ -679,13 +679,12 @@ bool StyledStreamWriter::hasCommentForValue(const Value& value) {
 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);
@@ -713,14 +712,12 @@ private:
   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)
@@ -730,8 +727,9 @@ BuiltStyledStreamWriter::BuiltStyledStreamWriter(
   , indented_(false)
 {
 }
-int BuiltStyledStreamWriter::write(Value const& root)
+int BuiltStyledStreamWriter::write(Value const& root, std::ostream* sout)
 {
+  sout_ = sout;
   addChildValues_ = false;
   indented_ = true;
   indentString_ = "";
@@ -740,7 +738,8 @@ int BuiltStyledStreamWriter::write(Value const& root)
   indented_ = true;
   writeValue(root);
   writeCommentAfterValueOnSameLine(root);
-  sout_ << endingLineFeedSymbol_;
+  *sout_ << endingLineFeedSymbol_;
+  sout_ = NULL;
   return 0;
 }
 void BuiltStyledStreamWriter::writeValue(Value const& value) {
@@ -779,13 +778,13 @@ 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();
@@ -821,7 +820,7 @@ void BuiltStyledStreamWriter::writeArrayValue(Value const& value) {
           writeCommentAfterValueOnSameLine(childValue);
           break;
         }
-        sout_ << ",";
+        *sout_ << ",";
         writeCommentAfterValueOnSameLine(childValue);
       }
       unindent();
@@ -829,15 +828,15 @@ void BuiltStyledStreamWriter::writeArrayValue(Value const& value) {
     } 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_ << "]";
     }
   }
 }
@@ -874,7 +873,7 @@ void BuiltStyledStreamWriter::pushValue(std::string const& value) {
   if (addChildValues_)
     childValues_.push_back(value);
   else
-    sout_ << value;
+    *sout_ << value;
 }
 
 void BuiltStyledStreamWriter::writeIndent() {
@@ -885,13 +884,13 @@ 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;
 }
 
@@ -911,11 +910,11 @@ void BuiltStyledStreamWriter::writeCommentBeforeValue(Value const& root) {
   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;
@@ -924,11 +923,11 @@ void BuiltStyledStreamWriter::writeCommentBeforeValue(Value const& root) {
 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);
   }
 }
 
@@ -942,8 +941,8 @@ bool BuiltStyledStreamWriter::hasCommentForValue(const Value& value) {
 ///////////////
 // StreamWriter
 
-StreamWriter::StreamWriter(std::ostream* sout)
-    : sout_(*sout)
+StreamWriter::StreamWriter()
+    : sout_(NULL)
 {
 }
 StreamWriter::~StreamWriter()
@@ -957,7 +956,7 @@ StreamWriterBuilder::StreamWriterBuilder()
 }
 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.
@@ -978,7 +977,7 @@ StreamWriter* StreamWriterBuilder::newStreamWriter(std::ostream* stream) const
   }
   std::string nullSymbol = "null";
   std::string endingLineFeedSymbol = "";
-  return new BuiltStyledStreamWriter(stream,
+  return new BuiltStyledStreamWriter(
       indentation, cs,
       colonSymbol, nullSymbol, endingLineFeedSymbol);
 }
@@ -1015,24 +1014,7 @@ void StreamWriterBuilder::setDefaults(Json::Value* settings)
   //! [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_) {
@@ -1048,22 +1030,22 @@ StreamWriter* OldCompressingStreamWriterBuilder::newStreamWriter(
   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;
 }