blob: e819b63220ac1e51b1e590516e900f99d8246f2f [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
Carl Worth112e7472012-07-30 15:01:15 -070036#ifdef _MSC_VER
37# include <float.h>
38# define isfinite _finite
José Fonsecac3912652012-10-26 23:45:35 +010039# define isnan _isnan
Carl Worth112e7472012-07-30 15:01:15 -070040#else
José Fonsecac3912652012-10-26 23:45:35 +010041# include <math.h> // isfinite, isnan
Carl Worth112e7472012-07-30 15:01:15 -070042#endif
43
José Fonseca702c1c62011-04-08 07:58:05 +010044#include <iomanip>
José Fonseca5f2245e2012-05-14 20:20:44 +010045#include <limits>
José Fonsecaa15b7fe2011-07-16 21:08:16 -070046#include <ostream>
47#include <string>
José Fonseca589082d2011-03-30 09:10:40 +010048
49
José Fonseca6083cfc2012-11-28 09:58:09 +000050namespace image {
51 class Image;
52}
53
54
José Fonseca589082d2011-03-30 09:10:40 +010055class JSONWriter
56{
57private:
58 std::ostream &os;
59
60 int level;
61 bool value;
José Fonsecafc92b762011-04-08 09:44:26 +010062 char space;
José Fonseca589082d2011-03-30 09:10:40 +010063
José Fonseca17a45412012-11-28 09:44:01 +000064 void
65 newline(void);
José Fonseca589082d2011-03-30 09:10:40 +010066
José Fonseca17a45412012-11-28 09:44:01 +000067 void
68 separator(void);
José Fonseca23a17d62011-04-09 12:22:58 +010069
José Fonseca589082d2011-03-30 09:10:40 +010070public:
José Fonseca17a45412012-11-28 09:44:01 +000071 JSONWriter(std::ostream &_os);
José Fonseca589082d2011-03-30 09:10:40 +010072
José Fonseca17a45412012-11-28 09:44:01 +000073 ~JSONWriter();
José Fonseca589082d2011-03-30 09:10:40 +010074
José Fonseca17a45412012-11-28 09:44:01 +000075 void
76 beginObject();
José Fonseca589082d2011-03-30 09:10:40 +010077
José Fonseca17a45412012-11-28 09:44:01 +000078 void
79 endObject();
José Fonseca589082d2011-03-30 09:10:40 +010080
José Fonseca17a45412012-11-28 09:44:01 +000081 void
82 beginMember(const char * name);
José Fonseca589082d2011-03-30 09:10:40 +010083
José Fonseca17a45412012-11-28 09:44:01 +000084 inline void
85 beginMember(const std::string &name) {
José Fonsecaa15b7fe2011-07-16 21:08:16 -070086 beginMember(name.c_str());
87 }
88
José Fonseca17a45412012-11-28 09:44:01 +000089 void
90 endMember(void);
José Fonseca589082d2011-03-30 09:10:40 +010091
José Fonseca17a45412012-11-28 09:44:01 +000092 void
93 beginArray();
José Fonseca589082d2011-03-30 09:10:40 +010094
José Fonseca17a45412012-11-28 09:44:01 +000095 void
96 endArray(void);
José Fonseca589082d2011-03-30 09:10:40 +010097
José Fonseca17a45412012-11-28 09:44:01 +000098 void
99 writeString(const char *s);
José Fonseca02bf5b42011-10-11 19:33:02 +0100100
José Fonseca17a45412012-11-28 09:44:01 +0000101 inline void
102 writeString(const std::string &s) {
José Fonsecaa15b7fe2011-07-16 21:08:16 -0700103 writeString(s.c_str());
104 }
105
José Fonseca17a45412012-11-28 09:44:01 +0000106 void
107 writeBase64(const void *bytes, size_t size);
José Fonseca23a17d62011-04-09 12:22:58 +0100108
José Fonseca17a45412012-11-28 09:44:01 +0000109 void
110 writeNull(void);
José Fonseca589082d2011-03-30 09:10:40 +0100111
José Fonseca17a45412012-11-28 09:44:01 +0000112 void
113 writeBool(bool b);
José Fonseca7ec90502012-04-16 20:09:42 +0100114
115 /**
116 * Special case for char to prevent it to be written as a literal
117 * character.
118 */
José Fonseca17a45412012-11-28 09:44:01 +0000119 inline void
120 writeInt(signed char n) {
José Fonseca7ec90502012-04-16 20:09:42 +0100121 separator();
122 os << std::dec << static_cast<int>(n);
123 value = true;
124 space = ' ';
125 }
126
José Fonseca17a45412012-11-28 09:44:01 +0000127 inline void
128 writeInt(unsigned char n) {
José Fonseca7ec90502012-04-16 20:09:42 +0100129 separator();
130 os << std::dec << static_cast<unsigned>(n);
131 value = true;
132 space = ' ';
133 }
134
José Fonseca589082d2011-03-30 09:10:40 +0100135 template<class T>
José Fonseca17a45412012-11-28 09:44:01 +0000136 inline void
137 writeInt(T n) {
José Fonseca8739fa62012-11-15 13:36:09 +0000138 separator();
139 os << std::dec << n;
140 value = true;
141 space = ' ';
142 }
José Fonseca17a45412012-11-28 09:44:01 +0000143
José Fonseca8739fa62012-11-15 13:36:09 +0000144 template<class T>
José Fonseca17a45412012-11-28 09:44:01 +0000145 void
146 writeFloat(T n) {
José Fonsecac3912652012-10-26 23:45:35 +0100147 separator();
148 if (isnan(n)) {
149 // NaN is non-standard but widely supported
150 os << "NaN";
151 } else if (!isfinite(n)) {
152 // Infinite is non-standard but widely supported
153 if (n < 0) {
154 os << '-';
155 }
156 os << "Infinity";
José Fonseca364a5a62011-05-06 20:49:45 +0100157 } else {
José Fonseca5f2245e2012-05-14 20:20:44 +0100158 os << std::dec << std::setprecision(std::numeric_limits<T>::digits10 + 1) << n;
José Fonseca364a5a62011-05-06 20:49:45 +0100159 }
José Fonsecac3912652012-10-26 23:45:35 +0100160 value = true;
161 space = ' ';
José Fonseca589082d2011-03-30 09:10:40 +0100162 }
José Fonseca23a17d62011-04-09 12:22:58 +0100163
José Fonseca17a45412012-11-28 09:44:01 +0000164 inline void
165 writeStringMember(const char *name, const char *s) {
José Fonseca23a17d62011-04-09 12:22:58 +0100166 beginMember(name);
167 writeString(s);
168 endMember();
169 }
170
José Fonseca17a45412012-11-28 09:44:01 +0000171 inline void
172 writeBoolMember(const char *name, bool b) {
José Fonseca23a17d62011-04-09 12:22:58 +0100173 beginMember(name);
174 writeBool(b);
175 endMember();
176 }
177
178 template<class T>
José Fonseca17a45412012-11-28 09:44:01 +0000179 inline void
180 writeIntMember(const char *name, T n) {
José Fonseca23a17d62011-04-09 12:22:58 +0100181 beginMember(name);
José Fonseca8739fa62012-11-15 13:36:09 +0000182 writeInt(n);
José Fonseca23a17d62011-04-09 12:22:58 +0100183 endMember();
184 }
José Fonseca6083cfc2012-11-28 09:58:09 +0000185
José Fonseca42551442014-12-29 18:10:08 +0000186 struct ImageDesc {
187 unsigned depth;
188 std::string format;
189
190 ImageDesc() :
191 depth(1),
192 format("UNKNOWN")
193 {}
194 };
195
José Fonseca6083cfc2012-11-28 09:58:09 +0000196 void
José Fonseca42551442014-12-29 18:10:08 +0000197 writeImage(image::Image *image, const ImageDesc & desc);
198
199 void
200 writeImage(image::Image *image) {
201 ImageDesc desc;
202 writeImage(image, desc);
203 }
204
José Fonseca589082d2011-03-30 09:10:40 +0100205};
206
207#endif /* _JSON_HPP_ */