implement strange setting from FastWriter
authorChristopher Dunn <cdunn2001@gmail.com>
Mon, 26 Jan 2015 00:15:54 +0000 (18:15 -0600)
committerChristopher Dunn <cdunn2001@gmail.com>
Mon, 26 Jan 2015 00:15:54 +0000 (18:15 -0600)
include/json/writer.h
src/lib_json/json_writer.cpp

index e4d665e..763a949 100644 (file)
@@ -74,6 +74,24 @@ public:
         Default: "\t"
     */
     void setIndentation(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.
+    */
+    void setDropNullPlaceholders(bool v);
+    /** \brief Do not add \n at end of document.
+     * Normally, we add an extra newline, just because.
+     */
+    void setOmitEndingLineFeed(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`.
+     */
+    void setEnableYAMLCompatibility(bool v);
 
     /// Do not take ownership of sout, but maintain a reference.
     StreamWriter* newStreamWriter(std::ostream* sout) const;
index 43166ac..bf103d2 100644 (file)
@@ -673,7 +673,10 @@ struct BuiltStyledStreamWriter : public StreamWriter
   BuiltStyledStreamWriter(
       std::ostream* sout,
       std::string const& indentation,
-      StreamWriter::CommentStyle cs);
+      StreamWriter::CommentStyle cs,
+      std::string const& colonSymbol,
+      std::string const& nullSymbol,
+      std::string const& endingLineFeedSymbol);
   virtual int write(Value const& root);
 private:
   void writeValue(Value const& value);
@@ -695,17 +698,26 @@ private:
   int rightMargin_;
   std::string indentation_;
   CommentStyle cs_;
+  std::string colonSymbol_;
+  std::string nullSymbol_;
+  std::string endingLineFeedSymbol_;
   bool addChildValues_ : 1;
   bool indented_ : 1;
 };
 BuiltStyledStreamWriter::BuiltStyledStreamWriter(
       std::ostream* sout,
       std::string const& indentation,
-      StreamWriter::CommentStyle cs)
+      StreamWriter::CommentStyle cs,
+      std::string const& colonSymbol,
+      std::string const& nullSymbol,
+      std::string const& endingLineFeedSymbol)
   : StreamWriter(sout)
   , rightMargin_(74)
   , indentation_(indentation)
   , cs_(cs)
+  , colonSymbol_(colonSymbol)
+  , nullSymbol_(nullSymbol)
+  , endingLineFeedSymbol_(endingLineFeedSymbol)
   , addChildValues_(false)
   , indented_(false)
 {
@@ -720,15 +732,13 @@ int BuiltStyledStreamWriter::write(Value const& root)
   indented_ = true;
   writeValue(root);
   writeCommentAfterValueOnSameLine(root);
-  if (!indentation_.empty()) {
-    sout_ << "\n";
-  }
+  sout_ << endingLineFeedSymbol_;
   return 0;
 }
 void BuiltStyledStreamWriter::writeValue(Value const& value) {
   switch (value.type()) {
   case nullValue:
-    pushValue("null");
+    pushValue(nullSymbol_);
     break;
   case intValue:
     pushValue(valueToString(value.asLargestInt()));
@@ -761,9 +771,7 @@ void BuiltStyledStreamWriter::writeValue(Value const& value) {
         Value const& childValue = value[name];
         writeCommentBeforeValue(childValue);
         writeWithIndent(valueToQuotedString(name.c_str()));
-        if (!indentation_.empty()) sout_ << " ";
-        sout_ << ":";
-        if (!indentation_.empty()) sout_ << " ";
+        sout_ << colonSymbol_;
         writeValue(childValue);
         if (++it == members.end()) {
           writeCommentAfterValueOnSameLine(childValue);
@@ -955,16 +963,25 @@ class StreamWriterBuilder {
   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()
   : cs_(CommentStyle::All)
   , indentation_("\t")
+  , dropNullPlaceholders_(false)
+  , omitEndingLineFeed_(false)
+  , enableYAMLCompatibility_(false)
 {
 }
 StreamWriterBuilder::~StreamWriterBuilder()
@@ -979,9 +996,39 @@ 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
 {
-  return new BuiltStyledStreamWriter(stream, indentation_, cs_);
+  std::string colonSymbol = " : ";
+  if (indentation_.empty()) {
+    if (enableYAMLCompatibility_) {
+      colonSymbol = ": ";
+    } else {
+      colonSymbol = ":";
+    }
+  }
+  std::string nullSymbol = "null";
+  if (dropNullPlaceholders_) {
+    nullSymbol = "";
+  }
+  std::string endingLineFeedSymbol = "\n";
+  if (omitEndingLineFeed_) {
+    endingLineFeedSymbol = "";
+  }
+  return new BuiltStyledStreamWriter(stream,
+      indentation_, cs_,
+      colonSymbol, nullSymbol, endingLineFeedSymbol);
 }
 
 // This might become public someday.
@@ -1019,13 +1066,23 @@ void StreamWriter::Builder::setIndentation(std::string v)
 {
   own_->setIndentation(v);
 }
+void StreamWriter::Builder::setDropNullPlaceholders(bool v)
+{
+  own_->setDropNullPlaceholders(v);
+}
+void StreamWriter::Builder::setOmitEndingLineFeed(bool v)
+{
+  own_->setOmitEndingLineFeed(v);
+}
+void StreamWriter::Builder::setEnableYAMLCompatibility(bool v)
+{
+  own_->setEnableYAMLCompatibility(v);
+}
 StreamWriter* StreamWriter::Builder::newStreamWriter(std::ostream* sout) const
 {
   return own_->newStreamWriter(sout);
 }
 
-/// Do not take ownership of sout, but maintain a reference.
-StreamWriter* newStreamWriter(std::ostream* sout);
 std::string writeString(Value const& root, StreamWriter::Builder const& builder) {
   std::ostringstream sout;
   std::unique_ptr<StreamWriter> const sw(builder.newStreamWriter(&sout));
@@ -1036,6 +1093,7 @@ std::string writeString(Value const& root, StreamWriter::Builder const& builder)
 std::ostream& operator<<(std::ostream& sout, Value const& root) {
   StreamWriter::Builder builder;
   builder.setCommentStyle(StreamWriter::CommentStyle::All);
+  builder.setIndentation("\t");
   std::shared_ptr<StreamWriter> writer(builder.newStreamWriter(&sout));
   writer->write(root);
   return sout;