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