implement strange setting from FastWriter
diff --git a/include/json/writer.h b/include/json/writer.h
index e4d665e..763a949 100644
--- a/include/json/writer.h
+++ b/include/json/writer.h
@@ -74,6 +74,24 @@
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;
diff --git a/src/lib_json/json_writer.cpp b/src/lib_json/json_writer.cpp
index 43166ac..bf103d2 100644
--- a/src/lib_json/json_writer.cpp
+++ b/src/lib_json/json_writer.cpp
@@ -673,7 +673,10 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
{
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::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;