blob: fb0852a0ca83bab3a725bfbd8480c37e56a59c83 [file] [log] [blame]
Haibo Huangb0bee822021-02-24 15:40:15 -08001// Copyright 2007-2010 Baptiste Lepilleur and The JsonCpp Authors
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -04002// Distributed under MIT license, or public domain if desired and
3// recognized in your jurisdiction.
4// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE
5
6#ifndef JSON_WRITER_H_INCLUDED
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -05007#define JSON_WRITER_H_INCLUDED
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -04008
9#if !defined(JSON_IS_AMALGAMATION)
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -050010#include "value.h"
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -040011#endif // if !defined(JSON_IS_AMALGAMATION)
Haibo Huangb0bee822021-02-24 15:40:15 -080012#include <ostream>
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -050013#include <string>
Haibo Huangb0bee822021-02-24 15:40:15 -080014#include <vector>
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -050015
16// Disable warning C4251: <data member>: <type> needs to have dll-interface to
17// be used by...
Haibo Huangb0bee822021-02-24 15:40:15 -080018#if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING) && defined(_MSC_VER)
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -050019#pragma warning(push)
20#pragma warning(disable : 4251)
21#endif // if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -040022
Haibo Huangb0bee822021-02-24 15:40:15 -080023#pragma pack(push, 8)
24
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -040025namespace Json {
26
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -050027class Value;
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -040028
Haibo Huangb0bee822021-02-24 15:40:15 -080029/**
30 *
31 * Usage:
32 * \code
33 * using namespace Json;
34 * void writeToStdout(StreamWriter::Factory const& factory, Value const& value)
35 * { std::unique_ptr<StreamWriter> const writer( factory.newStreamWriter());
36 * writer->write(value, &std::cout);
37 * std::cout << std::endl; // add lf and flush
38 * }
39 * \endcode
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -050040 */
Haibo Huangb0bee822021-02-24 15:40:15 -080041class JSON_API StreamWriter {
42protected:
43 OStream* sout_; // not owned; will not delete
44public:
45 StreamWriter();
46 virtual ~StreamWriter();
47 /** Write Value into document as configured in sub-class.
48 * Do not take ownership of sout, but maintain a reference during function.
49 * \pre sout != NULL
50 * \return zero on success (For now, we always return zero, so check the
51 * stream instead.) \throw std::exception possibly, depending on
52 * configuration
53 */
54 virtual int write(Value const& root, OStream* sout) = 0;
55
56 /** \brief A simple abstract factory.
57 */
58 class JSON_API Factory {
59 public:
60 virtual ~Factory();
61 /** \brief Allocate a CharReader via operator new().
62 * \throw std::exception if something goes wrong (e.g. invalid settings)
63 */
64 virtual StreamWriter* newStreamWriter() const = 0;
65 }; // Factory
66}; // StreamWriter
67
68/** \brief Write into stringstream, then return string, for convenience.
69 * A StreamWriter will be created from the factory, used, and then deleted.
70 */
71String JSON_API writeString(StreamWriter::Factory const& factory,
72 Value const& root);
73
74/** \brief Build a StreamWriter implementation.
75
76* Usage:
77* \code
78* using namespace Json;
79* Value value = ...;
80* StreamWriterBuilder builder;
81* builder["commentStyle"] = "None";
82* builder["indentation"] = " "; // or whatever you like
83* std::unique_ptr<Json::StreamWriter> writer(
84* builder.newStreamWriter());
85* writer->write(value, &std::cout);
86* std::cout << std::endl; // add lf and flush
87* \endcode
88*/
89class JSON_API StreamWriterBuilder : public StreamWriter::Factory {
90public:
91 // Note: We use a Json::Value so that we can add data-members to this class
92 // without a major version bump.
93 /** Configuration of this builder.
94 * Available settings (case-sensitive):
95 * - "commentStyle": "None" or "All"
96 * - "indentation": "<anything>".
97 * - Setting this to an empty string also omits newline characters.
98 * - "enableYAMLCompatibility": false or true
99 * - slightly change the whitespace around colons
100 * - "dropNullPlaceholders": false or true
101 * - Drop the "null" string from the writer's output for nullValues.
102 * Strictly speaking, this is not valid JSON. But when the output is being
103 * fed to a browser's JavaScript, it makes for smaller output and the
104 * browser can handle the output just fine.
105 * - "useSpecialFloats": false or true
106 * - If true, outputs non-finite floating point values in the following way:
107 * NaN values as "NaN", positive infinity as "Infinity", and negative
108 * infinity as "-Infinity".
109 * - "precision": int
110 * - Number of precision digits for formatting of real values.
111 * - "precisionType": "significant"(default) or "decimal"
112 * - Type of precision for formatting of real values.
113
114 * You can examine 'settings_` yourself
115 * to see the defaults. You can also write and read them just like any
116 * JSON Value.
117 * \sa setDefaults()
118 */
119 Json::Value settings_;
120
121 StreamWriterBuilder();
122 ~StreamWriterBuilder() override;
123
124 /**
125 * \throw std::exception if something goes wrong (e.g. invalid settings)
126 */
127 StreamWriter* newStreamWriter() const override;
128
129 /** \return true if 'settings' are legal and consistent;
130 * otherwise, indicate bad settings via 'invalid'.
131 */
132 bool validate(Json::Value* invalid) const;
133 /** A simple way to update a specific setting.
134 */
135 Value& operator[](const String& key);
136
137 /** Called by ctor, but you can use this to reset settings_.
138 * \pre 'settings' != NULL (but Json::null is fine)
139 * \remark Defaults:
140 * \snippet src/lib_json/json_writer.cpp StreamWriterBuilderDefaults
141 */
142 static void setDefaults(Json::Value* settings);
143};
144
145/** \brief Abstract class for writers.
146 * \deprecated Use StreamWriter. (And really, this is an implementation detail.)
147 */
148class JSONCPP_DEPRECATED("Use StreamWriter instead") JSON_API Writer {
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -0500149public:
150 virtual ~Writer();
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -0400151
Haibo Huangb0bee822021-02-24 15:40:15 -0800152 virtual String write(const Value& root) = 0;
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -0500153};
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -0400154
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -0500155/** \brief Outputs a Value in <a HREF="http://www.json.org">JSON</a> format
156 *without formatting (not human friendly).
157 *
158 * The JSON document is written in a single line. It is not intended for 'human'
159 *consumption,
Haibo Huangb0bee822021-02-24 15:40:15 -0800160 * but may be useful to support feature such as RPC where bandwidth is limited.
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -0500161 * \sa Reader, Value
Haibo Huangb0bee822021-02-24 15:40:15 -0800162 * \deprecated Use StreamWriterBuilder.
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -0500163 */
Haibo Huangb0bee822021-02-24 15:40:15 -0800164#if defined(_MSC_VER)
165#pragma warning(push)
166#pragma warning(disable : 4996) // Deriving from deprecated class
167#endif
168class JSONCPP_DEPRECATED("Use StreamWriterBuilder instead") JSON_API FastWriter
169 : public Writer {
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -0500170public:
171 FastWriter();
Haibo Huangb0bee822021-02-24 15:40:15 -0800172 ~FastWriter() override = default;
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -0400173
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -0500174 void enableYAMLCompatibility();
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -0400175
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -0500176 /** \brief Drop the "null" string from the writer's output for nullValues.
177 * Strictly speaking, this is not valid JSON. But when the output is being
Haibo Huangb0bee822021-02-24 15:40:15 -0800178 * fed to a browser's JavaScript, it makes for smaller output and the
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -0500179 * browser can handle the output just fine.
180 */
181 void dropNullPlaceholders();
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -0400182
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -0500183 void omitEndingLineFeed();
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -0400184
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -0500185public: // overridden from Writer
Haibo Huangb0bee822021-02-24 15:40:15 -0800186 String write(const Value& root) override;
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -0400187
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -0500188private:
189 void writeValue(const Value& value);
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -0400190
Haibo Huangb0bee822021-02-24 15:40:15 -0800191 String document_;
192 bool yamlCompatibilityEnabled_{false};
193 bool dropNullPlaceholders_{false};
194 bool omitEndingLineFeed_{false};
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -0500195};
Haibo Huangb0bee822021-02-24 15:40:15 -0800196#if defined(_MSC_VER)
197#pragma warning(pop)
198#endif
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -0400199
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -0500200/** \brief Writes a Value in <a HREF="http://www.json.org">JSON</a> format in a
201 *human friendly way.
202 *
203 * The rules for line break and indent are as follow:
204 * - Object value:
205 * - if empty then print {} without indent and line break
206 * - if not empty the print '{', line break & indent, print one value per
207 *line
208 * and then unindent and line break and print '}'.
209 * - Array value:
210 * - if empty then print [] without indent and line break
211 * - if the array contains no object value, empty array or some other value
212 *types,
213 * and all the values fit on one lines, then print the array on a single
214 *line.
215 * - otherwise, it the values do not fit on one line, or the array contains
216 * object or non empty array, then print one value per line.
217 *
218 * If the Value have comments then they are outputed according to their
219 *#CommentPlacement.
220 *
221 * \sa Reader, Value, Value::setComment()
Haibo Huangb0bee822021-02-24 15:40:15 -0800222 * \deprecated Use StreamWriterBuilder.
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -0500223 */
Haibo Huangb0bee822021-02-24 15:40:15 -0800224#if defined(_MSC_VER)
225#pragma warning(push)
226#pragma warning(disable : 4996) // Deriving from deprecated class
227#endif
228class JSONCPP_DEPRECATED("Use StreamWriterBuilder instead") JSON_API
229 StyledWriter : public Writer {
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -0500230public:
231 StyledWriter();
Haibo Huangb0bee822021-02-24 15:40:15 -0800232 ~StyledWriter() override = default;
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -0400233
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -0500234public: // overridden from Writer
235 /** \brief Serialize a Value in <a HREF="http://www.json.org">JSON</a> format.
236 * \param root Value to serialize.
237 * \return String containing the JSON document that represents the root value.
238 */
Haibo Huangb0bee822021-02-24 15:40:15 -0800239 String write(const Value& root) override;
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -0400240
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -0500241private:
242 void writeValue(const Value& value);
243 void writeArrayValue(const Value& value);
Haibo Huangb0bee822021-02-24 15:40:15 -0800244 bool isMultilineArray(const Value& value);
245 void pushValue(const String& value);
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -0500246 void writeIndent();
Haibo Huangb0bee822021-02-24 15:40:15 -0800247 void writeWithIndent(const String& value);
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -0500248 void indent();
249 void unindent();
250 void writeCommentBeforeValue(const Value& root);
251 void writeCommentAfterValueOnSameLine(const Value& root);
Haibo Huangb0bee822021-02-24 15:40:15 -0800252 static bool hasCommentForValue(const Value& value);
253 static String normalizeEOL(const String& text);
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -0400254
Haibo Huangb0bee822021-02-24 15:40:15 -0800255 using ChildValues = std::vector<String>;
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -0400256
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -0500257 ChildValues childValues_;
Haibo Huangb0bee822021-02-24 15:40:15 -0800258 String document_;
259 String indentString_;
260 unsigned int rightMargin_{74};
261 unsigned int indentSize_{3};
262 bool addChildValues_{false};
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -0500263};
Haibo Huangb0bee822021-02-24 15:40:15 -0800264#if defined(_MSC_VER)
265#pragma warning(pop)
266#endif
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -0400267
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -0500268/** \brief Writes a Value in <a HREF="http://www.json.org">JSON</a> format in a
269 human friendly way,
270 to a stream rather than to a string.
271 *
272 * The rules for line break and indent are as follow:
273 * - Object value:
274 * - if empty then print {} without indent and line break
275 * - if not empty the print '{', line break & indent, print one value per
276 line
277 * and then unindent and line break and print '}'.
278 * - Array value:
279 * - if empty then print [] without indent and line break
280 * - if the array contains no object value, empty array or some other value
281 types,
282 * and all the values fit on one lines, then print the array on a single
283 line.
284 * - otherwise, it the values do not fit on one line, or the array contains
285 * object or non empty array, then print one value per line.
286 *
287 * If the Value have comments then they are outputed according to their
288 #CommentPlacement.
289 *
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -0500290 * \sa Reader, Value, Value::setComment()
Haibo Huangb0bee822021-02-24 15:40:15 -0800291 * \deprecated Use StreamWriterBuilder.
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -0500292 */
Haibo Huangb0bee822021-02-24 15:40:15 -0800293#if defined(_MSC_VER)
294#pragma warning(push)
295#pragma warning(disable : 4996) // Deriving from deprecated class
296#endif
297class JSONCPP_DEPRECATED("Use StreamWriterBuilder instead") JSON_API
298 StyledStreamWriter {
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -0500299public:
Haibo Huangb0bee822021-02-24 15:40:15 -0800300 /**
301 * \param indentation Each level will be indented by this amount extra.
302 */
303 StyledStreamWriter(String indentation = "\t");
304 ~StyledStreamWriter() = default;
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -0400305
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -0500306public:
307 /** \brief Serialize a Value in <a HREF="http://www.json.org">JSON</a> format.
308 * \param out Stream to write to. (Can be ostringstream, e.g.)
309 * \param root Value to serialize.
310 * \note There is no point in deriving from Writer, since write() should not
311 * return a value.
312 */
Haibo Huangb0bee822021-02-24 15:40:15 -0800313 void write(OStream& out, const Value& root);
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -0400314
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -0500315private:
316 void writeValue(const Value& value);
317 void writeArrayValue(const Value& value);
Haibo Huangb0bee822021-02-24 15:40:15 -0800318 bool isMultilineArray(const Value& value);
319 void pushValue(const String& value);
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -0500320 void writeIndent();
Haibo Huangb0bee822021-02-24 15:40:15 -0800321 void writeWithIndent(const String& value);
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -0500322 void indent();
323 void unindent();
324 void writeCommentBeforeValue(const Value& root);
325 void writeCommentAfterValueOnSameLine(const Value& root);
Haibo Huangb0bee822021-02-24 15:40:15 -0800326 static bool hasCommentForValue(const Value& value);
327 static String normalizeEOL(const String& text);
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -0400328
Haibo Huangb0bee822021-02-24 15:40:15 -0800329 using ChildValues = std::vector<String>;
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -0400330
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -0500331 ChildValues childValues_;
Haibo Huangb0bee822021-02-24 15:40:15 -0800332 OStream* document_;
333 String indentString_;
334 unsigned int rightMargin_{74};
335 String indentation_;
336 bool addChildValues_ : 1;
337 bool indented_ : 1;
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -0500338};
Haibo Huangb0bee822021-02-24 15:40:15 -0800339#if defined(_MSC_VER)
340#pragma warning(pop)
341#endif
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -0500342
343#if defined(JSON_HAS_INT64)
Haibo Huangb0bee822021-02-24 15:40:15 -0800344String JSON_API valueToString(Int value);
345String JSON_API valueToString(UInt value);
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -0500346#endif // if defined(JSON_HAS_INT64)
Haibo Huangb0bee822021-02-24 15:40:15 -0800347String JSON_API valueToString(LargestInt value);
348String JSON_API valueToString(LargestUInt value);
349String JSON_API valueToString(
350 double value, unsigned int precision = Value::defaultRealPrecision,
351 PrecisionType precisionType = PrecisionType::significantDigits);
352String JSON_API valueToString(bool value);
353String JSON_API valueToQuotedString(const char* value);
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -0500354
355/// \brief Output using the StyledStreamWriter.
356/// \see Json::operator>>()
Haibo Huangb0bee822021-02-24 15:40:15 -0800357JSON_API OStream& operator<<(OStream&, const Value& root);
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -0400358
359} // namespace Json
360
Haibo Huangb0bee822021-02-24 15:40:15 -0800361#pragma pack(pop)
362
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -0500363#if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)
364#pragma warning(pop)
365#endif // if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -0400366
367#endif // JSON_WRITER_H_INCLUDED