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