writer.h 11 KB

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