1 | |
2 | /* vim: set et ts=3 sw=3 sts=3 ft=c: |
3 | * |
4 | * Copyright (C) 2012, 2013, 2014 James McLaughlin et al. All rights reserved. |
5 | * https://github.com/udp/json-parser |
6 | * |
7 | * Redistribution and use in source and binary forms, with or without |
8 | * modification, are permitted provided that the following conditions |
9 | * are met: |
10 | * |
11 | * 1. Redistributions of source code must retain the above copyright |
12 | * notice, this list of conditions and the following disclaimer. |
13 | * |
14 | * 2. Redistributions in binary form must reproduce the above copyright |
15 | * notice, this list of conditions and the following disclaimer in the |
16 | * documentation and/or other materials provided with the distribution. |
17 | * |
18 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND |
19 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
20 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
21 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE |
22 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
23 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
24 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
25 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
26 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
27 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
28 | * SUCH DAMAGE. |
29 | */ |
30 | |
31 | #ifndef _JSON_H |
32 | #define _JSON_H |
33 | |
34 | #ifndef json_char |
35 | #define json_char char |
36 | #endif |
37 | |
38 | #ifndef json_int_t |
39 | #ifndef _MSC_VER |
40 | #include <inttypes.h> |
41 | #define json_int_t int64_t |
42 | #else |
43 | #define json_int_t __int64 |
44 | #endif |
45 | #endif |
46 | |
47 | #include <stdlib.h> |
48 | |
49 | #ifdef __cplusplus |
50 | |
51 | #include <string.h> |
52 | |
53 | extern "C" |
54 | { |
55 | |
56 | #endif |
57 | |
58 | typedef struct |
59 | { |
60 | unsigned long max_memory; |
61 | int settings; |
62 | |
63 | /* Custom allocator support (leave null to use malloc/free) |
64 | */ |
65 | |
66 | void * (* mem_alloc) (size_t, int zero, void * user_data); |
67 | void (* mem_free) (void *, void * user_data); |
68 | |
69 | void * user_data; /* will be passed to mem_alloc and mem_free */ |
70 | |
71 | size_t ; /* how much extra space to allocate for values? */ |
72 | |
73 | } json_settings; |
74 | |
75 | #define 0x01 |
76 | |
77 | typedef enum |
78 | { |
79 | json_none, |
80 | json_object, |
81 | json_array, |
82 | json_integer, |
83 | json_double, |
84 | json_string, |
85 | json_boolean, |
86 | json_null |
87 | |
88 | } json_type; |
89 | |
90 | extern const struct _json_value json_value_none; |
91 | |
92 | typedef struct _json_value |
93 | { |
94 | struct _json_value * parent; |
95 | |
96 | json_type type; |
97 | |
98 | union |
99 | { |
100 | int boolean; |
101 | json_int_t integer; |
102 | double dbl; |
103 | |
104 | struct |
105 | { |
106 | unsigned int length; |
107 | json_char * ptr; /* null terminated */ |
108 | |
109 | } string; |
110 | |
111 | struct |
112 | { |
113 | unsigned int length; |
114 | |
115 | struct |
116 | { |
117 | json_char * name; |
118 | unsigned int name_length; |
119 | |
120 | struct _json_value * value; |
121 | |
122 | } * values; |
123 | |
124 | #if defined(__cplusplus) && __cplusplus >= 201103L |
125 | decltype(values) begin () const |
126 | { return values; |
127 | } |
128 | decltype(values) end () const |
129 | { return values + length; |
130 | } |
131 | #endif |
132 | |
133 | } object; |
134 | |
135 | struct |
136 | { |
137 | unsigned int length; |
138 | struct _json_value ** values; |
139 | |
140 | #if defined(__cplusplus) && __cplusplus >= 201103L |
141 | decltype(values) begin () const |
142 | { return values; |
143 | } |
144 | decltype(values) end () const |
145 | { return values + length; |
146 | } |
147 | #endif |
148 | |
149 | } array; |
150 | |
151 | } u; |
152 | |
153 | union |
154 | { |
155 | struct _json_value * next_alloc; |
156 | void * object_mem; |
157 | |
158 | } _reserved; |
159 | |
160 | #ifdef JSON_TRACK_SOURCE |
161 | |
162 | /* Location of the value in the source JSON |
163 | */ |
164 | unsigned int line, col; |
165 | |
166 | #endif |
167 | |
168 | |
169 | /* Some C++ operator sugar */ |
170 | |
171 | #ifdef __cplusplus |
172 | |
173 | public: |
174 | |
175 | inline _json_value () |
176 | { memset (s: this, c: 0, n: sizeof (_json_value)); |
177 | } |
178 | |
179 | inline const struct _json_value &operator [] (int index) const |
180 | { |
181 | if (type != json_array || index < 0 |
182 | || ((unsigned int) index) >= u.array.length) |
183 | { |
184 | return json_value_none; |
185 | } |
186 | |
187 | return *u.array.values [index]; |
188 | } |
189 | |
190 | inline const struct _json_value &operator [] (const char * index) const |
191 | { |
192 | if (type != json_object) |
193 | return json_value_none; |
194 | |
195 | for (unsigned int i = 0; i < u.object.length; ++ i) |
196 | if (!strcmp (s1: u.object.values [i].name, s2: index)) |
197 | return *u.object.values [i].value; |
198 | |
199 | return json_value_none; |
200 | } |
201 | |
202 | inline operator const char * () const |
203 | { |
204 | switch (type) |
205 | { |
206 | case json_string: |
207 | return u.string.ptr; |
208 | |
209 | default: |
210 | return "" ; |
211 | }; |
212 | } |
213 | |
214 | inline operator json_int_t () const |
215 | { |
216 | switch (type) |
217 | { |
218 | case json_integer: |
219 | return u.integer; |
220 | |
221 | case json_double: |
222 | return (json_int_t) u.dbl; |
223 | |
224 | default: |
225 | return 0; |
226 | }; |
227 | } |
228 | |
229 | inline operator bool () const |
230 | { |
231 | if (type != json_boolean) |
232 | return false; |
233 | |
234 | return u.boolean != 0; |
235 | } |
236 | |
237 | inline operator double () const |
238 | { |
239 | switch (type) |
240 | { |
241 | case json_integer: |
242 | return (double) u.integer; |
243 | |
244 | case json_double: |
245 | return u.dbl; |
246 | |
247 | default: |
248 | return 0; |
249 | }; |
250 | } |
251 | |
252 | #endif |
253 | |
254 | } json_value; |
255 | |
256 | json_value * json_parse (const json_char * json, |
257 | size_t length); |
258 | |
259 | #define json_error_max 128 |
260 | json_value * json_parse_ex (json_settings * settings, |
261 | const json_char * json, |
262 | size_t length, |
263 | char * error); |
264 | |
265 | void json_value_free (json_value *); |
266 | |
267 | |
268 | /* Not usually necessary, unless you used a custom mem_alloc and now want to |
269 | * use a custom mem_free. |
270 | */ |
271 | void json_value_free_ex (json_settings * settings, |
272 | json_value *); |
273 | |
274 | #ifdef __cplusplus |
275 | } /* extern "C" */ |
276 | #endif |
277 | |
278 | #endif |
279 | |
280 | |
281 | |