writer.h 11 KB

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