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