1f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III// Copyright 2007-2010 Baptiste Lepilleur
2f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III// Distributed under MIT license, or public domain if desired and
3f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III// recognized in your jurisdiction.
4f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE
5f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III
6f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III#ifndef JSON_WRITER_H_INCLUDED
7f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III# define JSON_WRITER_H_INCLUDED
8f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III
9f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III#if !defined(JSON_IS_AMALGAMATION)
10f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III# include "value.h"
11f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III#endif // if !defined(JSON_IS_AMALGAMATION)
12f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III# include <vector>
13f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III# include <string>
14f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III
15f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins IIInamespace Json {
16f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III
17f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III   class Value;
18f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III
19f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III   /** \brief Abstract class for writers.
20f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III    */
21f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III   class JSON_API Writer
22f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III   {
23f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III   public:
24f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III      virtual ~Writer();
25f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III
26f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III      virtual std::string write( const Value &root ) = 0;
27f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III   };
28f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III
29f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III   /** \brief Outputs a Value in <a HREF="http://www.json.org">JSON</a> format without formatting (not human friendly).
30f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III    *
31f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III    * The JSON document is written in a single line. It is not intended for 'human' consumption,
32f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III    * but may be usefull to support feature such as RPC where bandwith is limited.
33f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III    * \sa Reader, Value
34f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III    */
35f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III   class JSON_API FastWriter : public Writer
36f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III   {
37f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III   public:
38f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III      FastWriter();
39f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III      virtual ~FastWriter(){}
40f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III
41f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III      void enableYAMLCompatibility();
42f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III
43f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III   public: // overridden from Writer
44f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III      virtual std::string write( const Value &root );
45f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III
46f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III   private:
47f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III      void writeValue( const Value &value );
48f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III
49f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III      std::string document_;
50f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III      bool yamlCompatiblityEnabled_;
51f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III   };
52f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III
53f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III   /** \brief Writes a Value in <a HREF="http://www.json.org">JSON</a> format in a human friendly way.
54f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III    *
55f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III    * The rules for line break and indent are as follow:
56f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III    * - Object value:
57f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III    *     - if empty then print {} without indent and line break
58f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III    *     - if not empty the print '{', line break & indent, print one value per line
59f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III    *       and then unindent and line break and print '}'.
60f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III    * - Array value:
61f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III    *     - if empty then print [] without indent and line break
62f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III    *     - if the array contains no object value, empty array or some other value types,
63f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III    *       and all the values fit on one lines, then print the array on a single line.
64f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III    *     - otherwise, it the values do not fit on one line, or the array contains
65f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III    *       object or non empty array, then print one value per line.
66f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III    *
67f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III    * If the Value have comments then they are outputed according to their #CommentPlacement.
68f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III    *
69f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III    * \sa Reader, Value, Value::setComment()
70f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III    */
71f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III   class JSON_API StyledWriter: public Writer
72f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III   {
73f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III   public:
74f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III      StyledWriter();
75f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III      virtual ~StyledWriter(){}
76f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III
77f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III   public: // overridden from Writer
78f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III      /** \brief Serialize a Value in <a HREF="http://www.json.org">JSON</a> format.
79f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III       * \param root Value to serialize.
80f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III       * \return String containing the JSON document that represents the root value.
81f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III       */
82f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III      virtual std::string write( const Value &root );
83f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III
84f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III   private:
85f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III      void writeValue( const Value &value );
86f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III      void writeArrayValue( const Value &value );
87f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III      bool isMultineArray( const Value &value );
88f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III      void pushValue( const std::string &value );
89f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III      void writeIndent();
90f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III      void writeWithIndent( const std::string &value );
91f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III      void indent();
92f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III      void unindent();
93f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III      void writeCommentBeforeValue( const Value &root );
94f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III      void writeCommentAfterValueOnSameLine( const Value &root );
95f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III      bool hasCommentForValue( const Value &value );
96f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III      static std::string normalizeEOL( const std::string &text );
97f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III
98f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III      typedef std::vector<std::string> ChildValues;
99f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III
100f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III      ChildValues childValues_;
101f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III      std::string document_;
102f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III      std::string indentString_;
103f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III      int rightMargin_;
104f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III      int indentSize_;
105f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III      bool addChildValues_;
106f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III   };
107f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III
108f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III   /** \brief Writes a Value in <a HREF="http://www.json.org">JSON</a> format in a human friendly way,
109f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III        to a stream rather than to a string.
110f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III    *
111f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III    * The rules for line break and indent are as follow:
112f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III    * - Object value:
113f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III    *     - if empty then print {} without indent and line break
114f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III    *     - if not empty the print '{', line break & indent, print one value per line
115f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III    *       and then unindent and line break and print '}'.
116f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III    * - Array value:
117f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III    *     - if empty then print [] without indent and line break
118f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III    *     - if the array contains no object value, empty array or some other value types,
119f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III    *       and all the values fit on one lines, then print the array on a single line.
120f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III    *     - otherwise, it the values do not fit on one line, or the array contains
121f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III    *       object or non empty array, then print one value per line.
122f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III    *
123f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III    * If the Value have comments then they are outputed according to their #CommentPlacement.
124f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III    *
125f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III    * \param indentation Each level will be indented by this amount extra.
126f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III    * \sa Reader, Value, Value::setComment()
127f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III    */
128f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III   class JSON_API StyledStreamWriter
129f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III   {
130f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III   public:
131f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III      StyledStreamWriter( std::string indentation="\t" );
132f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III      ~StyledStreamWriter(){}
133f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III
134f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III   public:
135f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III      /** \brief Serialize a Value in <a HREF="http://www.json.org">JSON</a> format.
136f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III       * \param out Stream to write to. (Can be ostringstream, e.g.)
137f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III       * \param root Value to serialize.
138f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III       * \note There is no point in deriving from Writer, since write() should not return a value.
139f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III       */
140f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III      void write( std::ostream &out, const Value &root );
141f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III
142f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III   private:
143f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III      void writeValue( const Value &value );
144f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III      void writeArrayValue( const Value &value );
145f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III      bool isMultineArray( const Value &value );
146f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III      void pushValue( const std::string &value );
147f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III      void writeIndent();
148f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III      void writeWithIndent( const std::string &value );
149f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III      void indent();
150f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III      void unindent();
151f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III      void writeCommentBeforeValue( const Value &root );
152f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III      void writeCommentAfterValueOnSameLine( const Value &root );
153f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III      bool hasCommentForValue( const Value &value );
154f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III      static std::string normalizeEOL( const std::string &text );
155f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III
156f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III      typedef std::vector<std::string> ChildValues;
157f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III
158f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III      ChildValues childValues_;
159f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III      std::ostream* document_;
160f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III      std::string indentString_;
161f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III      int rightMargin_;
162f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III      std::string indentation_;
163f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III      bool addChildValues_;
164f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III   };
165f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III
166f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III# if defined(JSON_HAS_INT64)
167f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III   std::string JSON_API valueToString( Int value );
168f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III   std::string JSON_API valueToString( UInt value );
169f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III# endif // if defined(JSON_HAS_INT64)
170f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III   std::string JSON_API valueToString( LargestInt value );
171f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III   std::string JSON_API valueToString( LargestUInt value );
172f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III   std::string JSON_API valueToString( double value );
173f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III   std::string JSON_API valueToString( bool value );
174f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III   std::string JSON_API valueToQuotedString( const char *value );
175f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III
176f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III   /// \brief Output using the StyledStreamWriter.
177f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III   /// \see Json::operator>>()
178f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III   std::ostream& operator<<( std::ostream&, const Value &root );
179f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III
180f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III} // namespace Json
181f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III
182f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III
183f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III
184f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III#endif // JSON_WRITER_H_INCLUDED
185