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 6 #ifndef JSON_WRITER_H_INCLUDED 7 #define JSON_WRITER_H_INCLUDED 8 9 #if !defined(JSON_IS_AMALGAMATION) 10 #include "value.h" 11 #endif // if !defined(JSON_IS_AMALGAMATION) 12 #include <vector> 13 #include <string> 14 15 // Disable warning C4251: <data member>: <type> needs to have dll-interface to 16 // be used by... 17 #if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING) 18 #pragma warning(push) 19 #pragma warning(disable : 4251) 20 #endif // if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING) 21 22 namespace Json { 23 24 class Value; 25 26 /** \brief Abstract class for writers. 27 */ 28 class JSON_API Writer { 29 public: 30 virtual ~Writer(); 31 32 virtual std::string write(const Value& root) = 0; 33 }; 34 35 /** \brief Outputs a Value in <a HREF="http://www.json.org">JSON</a> format 36 *without formatting (not human friendly). 37 * 38 * The JSON document is written in a single line. It is not intended for 'human' 39 *consumption, 40 * but may be usefull to support feature such as RPC where bandwith is limited. 41 * \sa Reader, Value 42 */ 43 class JSON_API FastWriter : public Writer { 44 public: 45 FastWriter(); ~FastWriter()46 virtual ~FastWriter() {} 47 48 void enableYAMLCompatibility(); 49 50 /** \brief Drop the "null" string from the writer's output for nullValues. 51 * Strictly speaking, this is not valid JSON. But when the output is being 52 * fed to a browser's Javascript, it makes for smaller output and the 53 * browser can handle the output just fine. 54 */ 55 void dropNullPlaceholders(); 56 57 void omitEndingLineFeed(); 58 59 public: // overridden from Writer 60 virtual std::string write(const Value& root); 61 62 private: 63 void writeValue(const Value& value); 64 65 std::string document_; 66 bool yamlCompatiblityEnabled_; 67 bool dropNullPlaceholders_; 68 bool omitEndingLineFeed_; 69 }; 70 71 /** \brief Writes a Value in <a HREF="http://www.json.org">JSON</a> format in a 72 *human friendly way. 73 * 74 * The rules for line break and indent are as follow: 75 * - Object value: 76 * - if empty then print {} without indent and line break 77 * - if not empty the print '{', line break & indent, print one value per 78 *line 79 * and then unindent and line break and print '}'. 80 * - Array value: 81 * - if empty then print [] without indent and line break 82 * - if the array contains no object value, empty array or some other value 83 *types, 84 * and all the values fit on one lines, then print the array on a single 85 *line. 86 * - otherwise, it the values do not fit on one line, or the array contains 87 * object or non empty array, then print one value per line. 88 * 89 * If the Value have comments then they are outputed according to their 90 *#CommentPlacement. 91 * 92 * \sa Reader, Value, Value::setComment() 93 */ 94 class JSON_API StyledWriter : public Writer { 95 public: 96 StyledWriter(); ~StyledWriter()97 virtual ~StyledWriter() {} 98 99 public: // overridden from Writer 100 /** \brief Serialize a Value in <a HREF="http://www.json.org">JSON</a> format. 101 * \param root Value to serialize. 102 * \return String containing the JSON document that represents the root value. 103 */ 104 virtual std::string write(const Value& root); 105 106 private: 107 void writeValue(const Value& value); 108 void writeArrayValue(const Value& value); 109 bool isMultineArray(const Value& value); 110 void pushValue(const std::string& value); 111 void writeIndent(); 112 void writeWithIndent(const std::string& value); 113 void indent(); 114 void unindent(); 115 void writeCommentBeforeValue(const Value& root); 116 void writeCommentAfterValueOnSameLine(const Value& root); 117 bool hasCommentForValue(const Value& value); 118 static std::string normalizeEOL(const std::string& text); 119 120 typedef std::vector<std::string> ChildValues; 121 122 ChildValues childValues_; 123 std::string document_; 124 std::string indentString_; 125 int rightMargin_; 126 int indentSize_; 127 bool addChildValues_; 128 }; 129 130 /** \brief Writes a Value in <a HREF="http://www.json.org">JSON</a> format in a 131 human friendly way, 132 to a stream rather than to a string. 133 * 134 * The rules for line break and indent are as follow: 135 * - Object value: 136 * - if empty then print {} without indent and line break 137 * - if not empty the print '{', line break & indent, print one value per 138 line 139 * and then unindent and line break and print '}'. 140 * - Array value: 141 * - if empty then print [] without indent and line break 142 * - if the array contains no object value, empty array or some other value 143 types, 144 * and all the values fit on one lines, then print the array on a single 145 line. 146 * - otherwise, it the values do not fit on one line, or the array contains 147 * object or non empty array, then print one value per line. 148 * 149 * If the Value have comments then they are outputed according to their 150 #CommentPlacement. 151 * 152 * \param indentation Each level will be indented by this amount extra. 153 * \sa Reader, Value, Value::setComment() 154 */ 155 class JSON_API StyledStreamWriter { 156 public: 157 StyledStreamWriter(std::string indentation = "\t"); ~StyledStreamWriter()158 ~StyledStreamWriter() {} 159 160 public: 161 /** \brief Serialize a Value in <a HREF="http://www.json.org">JSON</a> format. 162 * \param out Stream to write to. (Can be ostringstream, e.g.) 163 * \param root Value to serialize. 164 * \note There is no point in deriving from Writer, since write() should not 165 * return a value. 166 */ 167 void write(std::ostream& out, const Value& root); 168 169 private: 170 void writeValue(const Value& value); 171 void writeArrayValue(const Value& value); 172 bool isMultineArray(const Value& value); 173 void pushValue(const std::string& value); 174 void writeIndent(); 175 void writeWithIndent(const std::string& value); 176 void indent(); 177 void unindent(); 178 void writeCommentBeforeValue(const Value& root); 179 void writeCommentAfterValueOnSameLine(const Value& root); 180 bool hasCommentForValue(const Value& value); 181 static std::string normalizeEOL(const std::string& text); 182 183 typedef std::vector<std::string> ChildValues; 184 185 ChildValues childValues_; 186 std::ostream* document_; 187 std::string indentString_; 188 int rightMargin_; 189 std::string indentation_; 190 bool addChildValues_; 191 }; 192 193 #if defined(JSON_HAS_INT64) 194 std::string JSON_API valueToString(Int value); 195 std::string JSON_API valueToString(UInt value); 196 #endif // if defined(JSON_HAS_INT64) 197 std::string JSON_API valueToString(LargestInt value); 198 std::string JSON_API valueToString(LargestUInt value); 199 std::string JSON_API valueToString(double value); 200 std::string JSON_API valueToString(bool value); 201 std::string JSON_API valueToQuotedString(const char* value); 202 203 /// \brief Output using the StyledStreamWriter. 204 /// \see Json::operator>>() 205 JSON_API std::ostream& operator<<(std::ostream&, const Value& root); 206 207 } // namespace Json 208 209 #if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING) 210 #pragma warning(pop) 211 #endif // if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING) 212 213 #endif // JSON_WRITER_H_INCLUDED 214