blob: 75b6f5d3b1fd1b8f8d1dc5fe8d8ba4664f764df6 [file] [log] [blame]
José Fonseca589082d2011-03-30 09:10:40 +01001/**************************************************************************
2 *
3 * Copyright 2011 Jose Fonseca
4 * All Rights Reserved.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to deal
8 * in the Software without restriction, including without limitation the rights
9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 * copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 * THE SOFTWARE.
23 *
24 **************************************************************************/
25
26/*
José Fonseca17a45412012-11-28 09:44:01 +000027 * JSON writing functions.
José Fonseca589082d2011-03-30 09:10:40 +010028 */
29
30#ifndef _JSON_HPP_
31#define _JSON_HPP_
32
José Fonseca589082d2011-03-30 09:10:40 +010033#include <stddef.h>
José Fonseca702c1c62011-04-08 07:58:05 +010034#include <wchar.h>
José Fonseca589082d2011-03-30 09:10:40 +010035
Jose Fonsecafc740d72015-03-08 21:30:59 +000036#include <cmath> // for std::isinf, std::isnan; as C99 macros are unavailable in C++11
Carl Worth112e7472012-07-30 15:01:15 -070037
José Fonseca702c1c62011-04-08 07:58:05 +010038#include <iomanip>
José Fonseca5f2245e2012-05-14 20:20:44 +010039#include <limits>
José Fonsecaa15b7fe2011-07-16 21:08:16 -070040#include <ostream>
41#include <string>
José Fonseca589082d2011-03-30 09:10:40 +010042
43
José Fonseca6083cfc2012-11-28 09:58:09 +000044namespace image {
45 class Image;
46}
47
48
José Fonseca589082d2011-03-30 09:10:40 +010049class JSONWriter
50{
51private:
52 std::ostream &os;
53
54 int level;
55 bool value;
José Fonsecafc92b762011-04-08 09:44:26 +010056 char space;
José Fonseca589082d2011-03-30 09:10:40 +010057
José Fonseca17a45412012-11-28 09:44:01 +000058 void
59 newline(void);
José Fonseca589082d2011-03-30 09:10:40 +010060
José Fonseca17a45412012-11-28 09:44:01 +000061 void
62 separator(void);
José Fonseca23a17d62011-04-09 12:22:58 +010063
José Fonseca589082d2011-03-30 09:10:40 +010064public:
José Fonseca17a45412012-11-28 09:44:01 +000065 JSONWriter(std::ostream &_os);
José Fonseca589082d2011-03-30 09:10:40 +010066
José Fonseca17a45412012-11-28 09:44:01 +000067 ~JSONWriter();
José Fonseca589082d2011-03-30 09:10:40 +010068
José Fonseca17a45412012-11-28 09:44:01 +000069 void
70 beginObject();
José Fonseca589082d2011-03-30 09:10:40 +010071
José Fonseca17a45412012-11-28 09:44:01 +000072 void
73 endObject();
José Fonseca589082d2011-03-30 09:10:40 +010074
José Fonseca17a45412012-11-28 09:44:01 +000075 void
76 beginMember(const char * name);
José Fonseca589082d2011-03-30 09:10:40 +010077
José Fonseca17a45412012-11-28 09:44:01 +000078 inline void
79 beginMember(const std::string &name) {
José Fonsecaa15b7fe2011-07-16 21:08:16 -070080 beginMember(name.c_str());
81 }
82
José Fonseca17a45412012-11-28 09:44:01 +000083 void
84 endMember(void);
José Fonseca589082d2011-03-30 09:10:40 +010085
José Fonseca17a45412012-11-28 09:44:01 +000086 void
87 beginArray();
José Fonseca589082d2011-03-30 09:10:40 +010088
José Fonseca17a45412012-11-28 09:44:01 +000089 void
90 endArray(void);
José Fonseca589082d2011-03-30 09:10:40 +010091
José Fonseca17a45412012-11-28 09:44:01 +000092 void
93 writeString(const char *s);
José Fonseca02bf5b42011-10-11 19:33:02 +010094
José Fonseca17a45412012-11-28 09:44:01 +000095 inline void
96 writeString(const std::string &s) {
José Fonsecaa15b7fe2011-07-16 21:08:16 -070097 writeString(s.c_str());
98 }
99
José Fonseca17a45412012-11-28 09:44:01 +0000100 void
101 writeBase64(const void *bytes, size_t size);
José Fonseca23a17d62011-04-09 12:22:58 +0100102
José Fonseca17a45412012-11-28 09:44:01 +0000103 void
104 writeNull(void);
José Fonseca589082d2011-03-30 09:10:40 +0100105
José Fonseca17a45412012-11-28 09:44:01 +0000106 void
107 writeBool(bool b);
José Fonseca7ec90502012-04-16 20:09:42 +0100108
109 /**
110 * Special case for char to prevent it to be written as a literal
111 * character.
112 */
José Fonseca17a45412012-11-28 09:44:01 +0000113 inline void
114 writeInt(signed char n) {
José Fonseca7ec90502012-04-16 20:09:42 +0100115 separator();
116 os << std::dec << static_cast<int>(n);
117 value = true;
118 space = ' ';
119 }
120
José Fonseca17a45412012-11-28 09:44:01 +0000121 inline void
122 writeInt(unsigned char n) {
José Fonseca7ec90502012-04-16 20:09:42 +0100123 separator();
124 os << std::dec << static_cast<unsigned>(n);
125 value = true;
126 space = ' ';
127 }
128
José Fonseca589082d2011-03-30 09:10:40 +0100129 template<class T>
José Fonseca17a45412012-11-28 09:44:01 +0000130 inline void
131 writeInt(T n) {
José Fonseca8739fa62012-11-15 13:36:09 +0000132 separator();
133 os << std::dec << n;
134 value = true;
135 space = ' ';
136 }
José Fonseca17a45412012-11-28 09:44:01 +0000137
José Fonseca8739fa62012-11-15 13:36:09 +0000138 template<class T>
José Fonseca17a45412012-11-28 09:44:01 +0000139 void
140 writeFloat(T n) {
José Fonsecac3912652012-10-26 23:45:35 +0100141 separator();
Jose Fonsecafc740d72015-03-08 21:30:59 +0000142 if (std::isnan(n)) {
José Fonsecac3912652012-10-26 23:45:35 +0100143 // NaN is non-standard but widely supported
144 os << "NaN";
Jose Fonsecafc740d72015-03-08 21:30:59 +0000145 } else if (std::isinf(n)) {
José Fonsecac3912652012-10-26 23:45:35 +0100146 // Infinite is non-standard but widely supported
147 if (n < 0) {
148 os << '-';
149 }
150 os << "Infinity";
José Fonseca364a5a62011-05-06 20:49:45 +0100151 } else {
José Fonseca5f2245e2012-05-14 20:20:44 +0100152 os << std::dec << std::setprecision(std::numeric_limits<T>::digits10 + 1) << n;
José Fonseca364a5a62011-05-06 20:49:45 +0100153 }
José Fonsecac3912652012-10-26 23:45:35 +0100154 value = true;
155 space = ' ';
José Fonseca589082d2011-03-30 09:10:40 +0100156 }
José Fonseca23a17d62011-04-09 12:22:58 +0100157
José Fonseca17a45412012-11-28 09:44:01 +0000158 inline void
159 writeStringMember(const char *name, const char *s) {
José Fonseca23a17d62011-04-09 12:22:58 +0100160 beginMember(name);
161 writeString(s);
162 endMember();
163 }
164
José Fonseca17a45412012-11-28 09:44:01 +0000165 inline void
166 writeBoolMember(const char *name, bool b) {
José Fonseca23a17d62011-04-09 12:22:58 +0100167 beginMember(name);
168 writeBool(b);
169 endMember();
170 }
171
172 template<class T>
José Fonseca17a45412012-11-28 09:44:01 +0000173 inline void
Zack Rusin86bd4992015-03-03 21:50:43 -0500174 writeFloatMember(const char *name, T f) {
175 beginMember(name);
176 writeFloat(f);
177 endMember();
178 }
179
180 template<class T>
181 inline void
José Fonseca17a45412012-11-28 09:44:01 +0000182 writeIntMember(const char *name, T n) {
José Fonseca23a17d62011-04-09 12:22:58 +0100183 beginMember(name);
José Fonseca8739fa62012-11-15 13:36:09 +0000184 writeInt(n);
José Fonseca23a17d62011-04-09 12:22:58 +0100185 endMember();
186 }
José Fonseca6083cfc2012-11-28 09:58:09 +0000187
José Fonseca42551442014-12-29 18:10:08 +0000188 struct ImageDesc {
189 unsigned depth;
190 std::string format;
191
192 ImageDesc() :
193 depth(1),
194 format("UNKNOWN")
195 {}
196 };
197
José Fonseca6083cfc2012-11-28 09:58:09 +0000198 void
José Fonseca42551442014-12-29 18:10:08 +0000199 writeImage(image::Image *image, const ImageDesc & desc);
200
201 void
202 writeImage(image::Image *image) {
203 ImageDesc desc;
204 writeImage(image, desc);
205 }
206
José Fonseca589082d2011-03-30 09:10:40 +0100207};
208
209#endif /* _JSON_HPP_ */