writer.h 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338
  1. // Copyright 2007-2010 Baptiste Lepilleur and The JsonCpp Authors
  2. // 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. #ifndef JSON_WRITER_H_INCLUDED
  6. #define JSON_WRITER_H_INCLUDED
  7. #if !defined(JSON_IS_AMALGAMATION)
  8. #include "value.h"
  9. #endif // if !defined(JSON_IS_AMALGAMATION)
  10. #include <iosfwd>
  11. #include <vector>
  12. #include <string>
  13. #include <ostream>
  14. // Disable warning C4251: <data member>: <type> needs to have dll-interface to
  15. // be used by...
  16. #if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)
  17. #pragma warning(push)
  18. #pragma warning(disable : 4251)
  19. #endif // if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)
  20. #pragma pack(push, 8)
  21. namespace Json {
  22. class Value;
  23. /**
  24. Usage:
  25. \code
  26. using namespace Json;
  27. void writeToStdout(StreamWriter::Factory const& factory, Value const& value) {
  28. std::unique_ptr<StreamWriter> const writer(
  29. factory.newStreamWriter());
  30. writer->write(value, &std::cout);
  31. std::cout << std::endl; // add lf and flush
  32. }
  33. \endcode
  34. */
  35. class JSON_API StreamWriter {
  36. protected:
  37. JSONCPP_OSTREAM* sout_; // not owned; will not delete
  38. public:
  39. StreamWriter();
  40. virtual ~StreamWriter();
  41. /** Write Value into document as configured in sub-class.
  42. Do not take ownership of sout, but maintain a reference during function.
  43. \pre sout != NULL
  44. \return zero on success (For now, we always return zero, so check the stream instead.)
  45. \throw std::exception possibly, depending on configuration
  46. */
  47. virtual int write(Value const& root, JSONCPP_OSTREAM* sout) = 0;
  48. /** \brief A simple abstract factory.
  49. */
  50. class JSON_API Factory {
  51. public:
  52. virtual ~Factory();
  53. /** \brief Allocate a CharReader via operator new().
  54. * \throw std::exception if something goes wrong (e.g. invalid settings)
  55. */
  56. virtual StreamWriter* newStreamWriter() const = 0;
  57. }; // Factory
  58. }; // StreamWriter
  59. /** \brief Write into stringstream, then return string, for convenience.
  60. * A StreamWriter will be created from the factory, used, and then deleted.
  61. */
  62. JSONCPP_STRING JSON_API writeString(StreamWriter::Factory const& factory, Value const& root);
  63. /** \brief Build a StreamWriter implementation.
  64. Usage:
  65. \code
  66. using namespace Json;
  67. Value value = ...;
  68. StreamWriterBuilder builder;
  69. builder["commentStyle"] = "None";
  70. builder["indentation"] = " "; // or whatever you like
  71. std::unique_ptr<Json::StreamWriter> writer(
  72. builder.newStreamWriter());
  73. writer->write(value, &std::cout);
  74. std::cout << std::endl; // add lf and flush
  75. \endcode
  76. */
  77. class JSON_API StreamWriterBuilder : public StreamWriter::Factory {
  78. public:
  79. // Note: We use a Json::Value so that we can add data-members to this class
  80. // without a major version bump.
  81. /** Configuration of this builder.
  82. Available settings (case-sensitive):
  83. - "commentStyle": "None" or "All"
  84. - "indentation": "<anything>"
  85. - "enableYAMLCompatibility": false or true
  86. - slightly change the whitespace around colons
  87. - "dropNullPlaceholders": false or true
  88. - Drop the "null" string from the writer's output for nullValues.
  89. Strictly speaking, this is not valid JSON. But when the output is being
  90. fed to a browser's Javascript, it makes for smaller output and the
  91. browser can handle the output just fine.
  92. - "useSpecialFloats": false or true
  93. - If true, outputs non-finite floating point values in the following way:
  94. NaN values as "NaN", positive infinity as "Infinity", and negative infinity
  95. as "-Infinity".
  96. You can examine 'settings_` yourself
  97. to see the defaults. You can also write and read them just like any
  98. JSON Value.
  99. \sa setDefaults()
  100. */
  101. Json::Value settings_;
  102. StreamWriterBuilder();
  103. ~StreamWriterBuilder() JSONCPP_OVERRIDE;
  104. /**
  105. * \throw std::exception if something goes wrong (e.g. invalid settings)
  106. */
  107. StreamWriter* newStreamWriter() const JSONCPP_OVERRIDE;
  108. /** \return true if 'settings' are legal and consistent;
  109. * otherwise, indicate bad settings via 'invalid'.
  110. */
  111. bool validate(Json::Value* invalid) const;
  112. /** A simple way to update a specific setting.
  113. */
  114. Value& operator[](JSONCPP_STRING key);
  115. /** Called by ctor, but you can use this to reset settings_.
  116. * \pre 'settings' != NULL (but Json::null is fine)
  117. * \remark Defaults:
  118. * \snippet src/lib_json/json_writer.cpp StreamWriterBuilderDefaults
  119. */
  120. static void setDefaults(Json::Value* settings);
  121. };
  122. /** \brief Abstract class for writers.
  123. * deprecated Use StreamWriter. (And really, this is an implementation detail.)
  124. */
  125. class JSONCPP_DEPRECATED("Use StreamWriter instead") JSON_API Writer {
  126. public:
  127. virtual ~Writer();
  128. virtual JSONCPP_STRING write(const Value& root) = 0;
  129. };
  130. /** \brief Outputs a Value in <a HREF="http://www.json.org">JSON</a> format
  131. *without formatting (not human friendly).
  132. *
  133. * The JSON document is written in a single line. It is not intended for 'human'
  134. *consumption,
  135. * but may be usefull to support feature such as RPC where bandwith is limited.
  136. * \sa Reader, Value
  137. * deprecated Use StreamWriterBuilder.
  138. */
  139. class JSONCPP_DEPRECATED("Use StreamWriterBuilder instead") JSON_API FastWriter : public Writer {
  140. public:
  141. FastWriter();
  142. ~FastWriter() JSONCPP_OVERRIDE {}
  143. void enableYAMLCompatibility();
  144. /** \brief Drop the "null" string from the writer's output for nullValues.
  145. * Strictly speaking, this is not valid JSON. But when the output is being
  146. * fed to a browser's Javascript, it makes for smaller output and the
  147. * browser can handle the output just fine.
  148. */
  149. void dropNullPlaceholders();
  150. void omitEndingLineFeed();
  151. public: // overridden from Writer
  152. JSONCPP_STRING write(const Value& root) JSONCPP_OVERRIDE;
  153. private:
  154. void writeValue(const Value& value);
  155. JSONCPP_STRING document_;
  156. bool yamlCompatiblityEnabled_;
  157. bool dropNullPlaceholders_;
  158. bool omitEndingLineFeed_;
  159. };
  160. /** \brief Writes a Value in <a HREF="http://www.json.org">JSON</a> format in a
  161. *human friendly way.
  162. *
  163. * The rules for line break and indent are as follow:
  164. * - Object value:
  165. * - if empty then print {} without indent and line break
  166. * - if not empty the print '{', line break & indent, print one value per
  167. *line
  168. * and then unindent and line break and print '}'.
  169. * - Array value:
  170. * - if empty then print [] without indent and line break
  171. * - if the array contains no object value, empty array or some other value
  172. *types,
  173. * and all the values fit on one lines, then print the array on a single
  174. *line.
  175. * - otherwise, it the values do not fit on one line, or the array contains
  176. * object or non empty array, then print one value per line.
  177. *
  178. * If the Value have comments then they are outputed according to their
  179. *#CommentPlacement.
  180. *
  181. * \sa Reader, Value, Value::setComment()
  182. * deprecated Use StreamWriterBuilder.
  183. */
  184. class JSONCPP_DEPRECATED("Use StreamWriterBuilder instead") JSON_API StyledWriter : public Writer {
  185. public:
  186. StyledWriter();
  187. ~StyledWriter() JSONCPP_OVERRIDE {}
  188. public: // overridden from Writer
  189. /** \brief Serialize a Value in <a HREF="http://www.json.org">JSON</a> format.
  190. * \param root Value to serialize.
  191. * \return String containing the JSON document that represents the root value.
  192. */
  193. JSONCPP_STRING write(const Value& root) JSONCPP_OVERRIDE;
  194. private:
  195. void writeValue(const Value& value);
  196. void writeArrayValue(const Value& value);
  197. bool isMultineArray(const Value& value);
  198. void pushValue(const JSONCPP_STRING& value);
  199. void writeIndent();
  200. void writeWithIndent(const JSONCPP_STRING& value);
  201. void indent();
  202. void unindent();
  203. void writeCommentBeforeValue(const Value& root);
  204. void writeCommentAfterValueOnSameLine(const Value& root);
  205. bool hasCommentForValue(const Value& value);
  206. static JSONCPP_STRING normalizeEOL(const JSONCPP_STRING& text);
  207. typedef std::vector<JSONCPP_STRING> ChildValues;
  208. ChildValues childValues_;
  209. JSONCPP_STRING document_;
  210. JSONCPP_STRING indentString_;
  211. unsigned int rightMargin_;
  212. unsigned int indentSize_;
  213. bool addChildValues_;
  214. };
  215. /** \brief Writes a Value in <a HREF="http://www.json.org">JSON</a> format in a
  216. human friendly way,
  217. to a stream rather than to a string.
  218. *
  219. * The rules for line break and indent are as follow:
  220. * - Object value:
  221. * - if empty then print {} without indent and line break
  222. * - if not empty the print '{', line break & indent, print one value per
  223. line
  224. * and then unindent and line break and print '}'.
  225. * - Array value:
  226. * - if empty then print [] without indent and line break
  227. * - if the array contains no object value, empty array or some other value
  228. types,
  229. * and all the values fit on one lines, then print the array on a single
  230. line.
  231. * - otherwise, it the values do not fit on one line, or the array contains
  232. * object or non empty array, then print one value per line.
  233. *
  234. * If the Value have comments then they are outputed according to their
  235. #CommentPlacement.
  236. *
  237. * \sa Reader, Value, Value::setComment()
  238. * deprecated Use StreamWriterBuilder.
  239. */
  240. class JSONCPP_DEPRECATED("Use StreamWriterBuilder instead") JSON_API StyledStreamWriter {
  241. public:
  242. /**
  243. * \param indentation Each level will be indented by this amount extra.
  244. */
  245. StyledStreamWriter(JSONCPP_STRING indentation = "\t");
  246. ~StyledStreamWriter() {}
  247. public:
  248. /** \brief Serialize a Value in <a HREF="http://www.json.org">JSON</a> format.
  249. * \param out Stream to write to. (Can be ostringstream, e.g.)
  250. * \param root Value to serialize.
  251. * \note There is no point in deriving from Writer, since write() should not
  252. * return a value.
  253. */
  254. void write(JSONCPP_OSTREAM& out, const Value& root);
  255. private:
  256. void writeValue(const Value& value);
  257. void writeArrayValue(const Value& value);
  258. bool isMultineArray(const Value& value);
  259. void pushValue(const JSONCPP_STRING& value);
  260. void writeIndent();
  261. void writeWithIndent(const JSONCPP_STRING& value);
  262. void indent();
  263. void unindent();
  264. void writeCommentBeforeValue(const Value& root);
  265. void writeCommentAfterValueOnSameLine(const Value& root);
  266. bool hasCommentForValue(const Value& value);
  267. static JSONCPP_STRING normalizeEOL(const JSONCPP_STRING& text);
  268. typedef std::vector<JSONCPP_STRING> ChildValues;
  269. ChildValues childValues_;
  270. JSONCPP_OSTREAM* document_;
  271. JSONCPP_STRING indentString_;
  272. unsigned int rightMargin_;
  273. JSONCPP_STRING indentation_;
  274. bool addChildValues_ : 1;
  275. bool indented_ : 1;
  276. };
  277. #if defined(JSON_HAS_INT64)
  278. JSONCPP_STRING JSON_API valueToString(Int value);
  279. JSONCPP_STRING JSON_API valueToString(UInt value);
  280. #endif // if defined(JSON_HAS_INT64)
  281. JSONCPP_STRING JSON_API valueToString(LargestInt value);
  282. JSONCPP_STRING JSON_API valueToString(LargestUInt value);
  283. JSONCPP_STRING JSON_API valueToString(double value);
  284. JSONCPP_STRING JSON_API valueToString(bool value);
  285. JSONCPP_STRING JSON_API valueToQuotedString(const char* value);
  286. /// \brief Output using the StyledStreamWriter.
  287. /// \see Json::operator>>()
  288. JSON_API JSONCPP_OSTREAM& operator<<(JSONCPP_OSTREAM&, const Value& root);
  289. } // namespace Json
  290. #pragma pack(pop)
  291. #if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)
  292. #pragma warning(pop)
  293. #endif // if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)
  294. #endif // JSON_WRITER_H_INCLUDED