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