source: lib/json.h @ 885d294

Last change on this file since 885d294 was 7a80925, checked in by Wilmer van der Gaast <wilmer@…>, at 2014-02-13T08:48:37Z

Update json-parser code to git rev 11a80f389769d1f66ca7fbe64ad89c82d3ba4ba9.
Few BitlBee-specific diffs now. Annoyingly need to link to libm now for the
use of the function pow() since the lib now does its own number parsing...

  • Property mode set to 100644
File size: 6.0 KB
Line 
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
58typedef 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} json_settings;
72
73#define json_enable_comments  0x01
74
75typedef 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
88extern const struct _json_value json_value_none;
89
90typedef 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            unsigned int name_length;
117
118            struct _json_value * value;
119
120         } * values;
121
122         #if defined(__cplusplus) && __cplusplus >= 201103L
123         decltype(values) begin () const
124         {  return values;
125         }
126         decltype(values) end () const
127         {  return values + length;
128         }
129         #endif
130
131      } object;
132
133      struct
134      {
135         unsigned int length;
136         struct _json_value ** values;
137
138         #if defined(__cplusplus) && __cplusplus >= 201103L
139         decltype(values) begin () const
140         {  return values;
141         }
142         decltype(values) end () const
143         {  return values + length;
144         }
145         #endif
146
147      } array;
148
149   } u;
150
151   union
152   {
153      struct _json_value * next_alloc;
154      void * object_mem;
155
156   } _reserved;
157
158
159   /* Some C++ operator sugar */
160
161   #ifdef __cplusplus
162
163      public:
164
165         inline _json_value ()
166         {  memset (this, 0, sizeof (_json_value));
167         }
168
169         inline const struct _json_value &operator [] (int index) const
170         {
171            if (type != json_array || index < 0
172                     || ((unsigned int) index) >= u.array.length)
173            {
174               return json_value_none;
175            }
176
177            return *u.array.values [index];
178         }
179
180         inline const struct _json_value &operator [] (const char * index) const
181         { 
182            if (type != json_object)
183               return json_value_none;
184
185            for (unsigned int i = 0; i < u.object.length; ++ i)
186               if (!strcmp (u.object.values [i].name, index))
187                  return *u.object.values [i].value;
188
189            return json_value_none;
190         }
191
192         inline operator const char * () const
193         { 
194            switch (type)
195            {
196               case json_string:
197                  return u.string.ptr;
198
199               default:
200                  return "";
201            };
202         }
203
204         inline operator json_int_t () const
205         { 
206            switch (type)
207            {
208               case json_integer:
209                  return u.integer;
210
211               case json_double:
212                  return (json_int_t) u.dbl;
213
214               default:
215                  return 0;
216            };
217         }
218
219         inline operator bool () const
220         { 
221            if (type != json_boolean)
222               return false;
223
224            return u.boolean != 0;
225         }
226
227         inline operator double () const
228         { 
229            switch (type)
230            {
231               case json_integer:
232                  return (double) u.integer;
233
234               case json_double:
235                  return u.dbl;
236
237               default:
238                  return 0;
239            };
240         }
241
242   #endif
243
244} json_value;
245
246json_value * json_parse (const json_char * json,
247                         size_t length);
248
249#define json_error_max 128
250json_value * json_parse_ex (json_settings * settings,
251                            const json_char * json,
252                            size_t length,
253                            char * error);
254
255void json_value_free (json_value *);
256
257
258/* Not usually necessary, unless you used a custom mem_alloc and now want to
259 * use a custom mem_free.
260 */
261void json_value_free_ex (json_settings * settings,
262                         json_value *);
263
264
265#ifdef __cplusplus
266   } /* extern "C" */
267#endif
268
269#endif
270
271
Note: See TracBrowser for help on using the repository browser.