cctools
json.h
1 
2 /* vim: set et ts=3 sw=3 ft=c:
3  *
4  * Copyright (C) 2012 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 
72 
73 #define json_relaxed_commas 1
74 
75 typedef enum
76 {
77  json_none,
78  json_object,
79  json_array,
80  json_integer,
81  json_double,
82  json_string,
83  json_boolean,
84  json_null
85 
86 } json_type;
87 
88 extern const struct _json_value json_value_none;
89 
90 typedef struct _json_value
91 {
92  struct _json_value * parent;
93 
94  json_type type;
95 
96  union
97  {
98  int boolean;
99  json_int_t integer;
100  double dbl;
101 
102  struct
103  {
104  unsigned int length;
105  json_char * ptr; /* null terminated */
106 
107  } string;
108 
109  struct
110  {
111  unsigned int length;
112 
113  struct
114  {
115  json_char * name;
116  struct _json_value * value;
117 
118  } * values;
119 
120  #if defined(__cplusplus) && __cplusplus >= 201103L
121  decltype(values) begin () const
122  { return values;
123  }
124  decltype(values) end () const
125  { return values + length;
126  }
127  #endif
128 
129  } object;
130 
131  struct
132  {
133  unsigned int length;
134  struct _json_value ** values;
135 
136  #if defined(__cplusplus) && __cplusplus >= 201103L
137  decltype(values) begin () const
138  { return values;
139  }
140  decltype(values) end () const
141  { return values + length;
142  }
143  #endif
144 
145  } array;
146 
147  } u;
148 
149  union
150  {
151  struct _json_value * next_alloc;
152  void * object_mem;
153 
154  } _reserved;
155 
156 
157  /* Some C++ operator sugar */
158 
159  #ifdef __cplusplus
160 
161  public:
162 
163  inline _json_value ()
164  { memset (this, 0, sizeof (_json_value));
165  }
166 
167  inline const struct _json_value &operator [] (int index) const
168  {
169  if (type != json_array || index < 0
170  || ((unsigned int) index) >= u.array.length)
171  {
172  return json_value_none;
173  }
174 
175  return *u.array.values [index];
176  }
177 
178  inline const struct _json_value &operator [] (const char * index) const
179  {
180  if (type != json_object)
181  return json_value_none;
182 
183  for (unsigned int i = 0; i < u.object.length; ++ i)
184  if (!strcmp (u.object.values [i].name, index))
185  return *u.object.values [i].value;
186 
187  return json_value_none;
188  }
189 
190  inline operator const char * () const
191  {
192  switch (type)
193  {
194  case json_string:
195  return u.string.ptr;
196 
197  default:
198  return "";
199  };
200  }
201 
202  inline operator json_int_t () const
203  {
204  switch (type)
205  {
206  case json_integer:
207  return u.integer;
208 
209  case json_double:
210  return (json_int_t) u.dbl;
211 
212  default:
213  return 0;
214  };
215  }
216 
217  inline operator bool () const
218  {
219  if (type != json_boolean)
220  return false;
221 
222  return u.boolean != 0;
223  }
224 
225  inline operator double () const
226  {
227  switch (type)
228  {
229  case json_integer:
230  return (double) u.integer;
231 
232  case json_double:
233  return u.dbl;
234 
235  default:
236  return 0;
237  };
238  }
239 
240  #endif
241 
242 } json_value;
243 
244 json_value * json_parse (const json_char * json,
245  size_t length);
246 
247 json_value * json_parse_ex (json_settings * settings,
248  const json_char * json,
249  size_t length,
250  char * error);
251 
252 void json_value_free (json_value *);
253 
254 
255 /* Not usually necessary, unless you used a custom mem_alloc and now want to
256  * use a custom mem_free.
257  */
258 void json_value_free_ex (json_settings * settings,
259  json_value *);
260 
261 
262 #ifdef __cplusplus
263  } /* extern "C" */
264 #endif
265 
266 #endif
267 
268 
Definition: json.h:90
Definition: json.h:58