|
|
@ -1,7 +1,7 @@ |
|
|
|
|
|
|
|
/* vim: set et ts=3 sw=3 ft=c: |
|
|
|
/* vim: set et ts=3 sw=3 sts=3 ft=c: |
|
|
|
* |
|
|
|
* Copyright (C) 2012 James McLaughlin et al. All rights reserved. |
|
|
|
* Copyright (C) 2012, 2013, 2014 James McLaughlin et al. All rights reserved. |
|
|
|
* https://github.com/udp/json-parser |
|
|
|
* |
|
|
|
* Redistribution and use in source and binary forms, with or without |
|
|
@ -32,56 +32,56 @@ |
|
|
|
#define _JSON_H |
|
|
|
|
|
|
|
#ifndef json_char |
|
|
|
#define json_char char |
|
|
|
#define json_char char |
|
|
|
#endif |
|
|
|
|
|
|
|
#ifndef json_int_t |
|
|
|
#ifndef _MSC_VER |
|
|
|
#include <inttypes.h> |
|
|
|
#define json_int_t int64_t |
|
|
|
#else |
|
|
|
#define json_int_t __int64 |
|
|
|
#endif |
|
|
|
#ifndef _MSC_VER |
|
|
|
#include <inttypes.h> |
|
|
|
#define json_int_t int64_t |
|
|
|
#else |
|
|
|
#define json_int_t __int64 |
|
|
|
#endif |
|
|
|
#endif |
|
|
|
|
|
|
|
#include <stdlib.h> |
|
|
|
|
|
|
|
#ifdef __cplusplus |
|
|
|
|
|
|
|
#include <string.h> |
|
|
|
#include <string.h> |
|
|
|
|
|
|
|
extern "C" |
|
|
|
{ |
|
|
|
extern "C" |
|
|
|
{ |
|
|
|
|
|
|
|
#endif |
|
|
|
|
|
|
|
typedef struct |
|
|
|
{ |
|
|
|
unsigned long max_memory; |
|
|
|
int settings; |
|
|
|
unsigned long max_memory; |
|
|
|
int settings; |
|
|
|
|
|
|
|
/* Custom allocator support (leave null to use malloc/free) |
|
|
|
*/ |
|
|
|
/* Custom allocator support (leave null to use malloc/free) |
|
|
|
*/ |
|
|
|
|
|
|
|
void * (* mem_alloc) (size_t, int zero, void * user_data); |
|
|
|
void (* mem_free) (void *, void * user_data); |
|
|
|
void * (* mem_alloc) (size_t, int zero, void * user_data); |
|
|
|
void (* mem_free) (void *, void * user_data); |
|
|
|
|
|
|
|
void * user_data; /* will be passed to mem_alloc and mem_free */ |
|
|
|
void * user_data; /* will be passed to mem_alloc and mem_free */ |
|
|
|
|
|
|
|
} json_settings; |
|
|
|
|
|
|
|
#define json_relaxed_commas 1 |
|
|
|
#define json_enable_comments 0x01 |
|
|
|
|
|
|
|
typedef enum |
|
|
|
{ |
|
|
|
json_none, |
|
|
|
json_object, |
|
|
|
json_array, |
|
|
|
json_integer, |
|
|
|
json_double, |
|
|
|
json_string, |
|
|
|
json_boolean, |
|
|
|
json_null |
|
|
|
json_none, |
|
|
|
json_object, |
|
|
|
json_array, |
|
|
|
json_integer, |
|
|
|
json_double, |
|
|
|
json_string, |
|
|
|
json_boolean, |
|
|
|
json_null |
|
|
|
|
|
|
|
} json_type; |
|
|
|
|
|
|
@ -89,161 +89,181 @@ extern const struct _json_value json_value_none; |
|
|
|
|
|
|
|
typedef struct _json_value |
|
|
|
{ |
|
|
|
struct _json_value * parent; |
|
|
|
struct _json_value * parent; |
|
|
|
|
|
|
|
json_type type; |
|
|
|
json_type type; |
|
|
|
|
|
|
|
union |
|
|
|
{ |
|
|
|
int boolean; |
|
|
|
json_int_t integer; |
|
|
|
double dbl; |
|
|
|
union |
|
|
|
{ |
|
|
|
int boolean; |
|
|
|
json_int_t integer; |
|
|
|
double dbl; |
|
|
|
|
|
|
|
struct |
|
|
|
{ |
|
|
|
unsigned int length; |
|
|
|
json_char * ptr; /* null terminated */ |
|
|
|
struct |
|
|
|
{ |
|
|
|
unsigned int length; |
|
|
|
json_char * ptr; /* null terminated */ |
|
|
|
|
|
|
|
} string; |
|
|
|
} string; |
|
|
|
|
|
|
|
struct |
|
|
|
{ |
|
|
|
unsigned int length; |
|
|
|
struct |
|
|
|
{ |
|
|
|
unsigned int length; |
|
|
|
|
|
|
|
struct |
|
|
|
{ |
|
|
|
json_char * name; |
|
|
|
struct _json_value * value; |
|
|
|
struct |
|
|
|
{ |
|
|
|
json_char * name; |
|
|
|
unsigned int name_length; |
|
|
|
|
|
|
|
} * values; |
|
|
|
struct _json_value * value; |
|
|
|
|
|
|
|
} object; |
|
|
|
} * values; |
|
|
|
|
|
|
|
struct |
|
|
|
{ |
|
|
|
unsigned int length; |
|
|
|
struct _json_value ** values; |
|
|
|
#if defined(__cplusplus) && __cplusplus >= 201103L |
|
|
|
decltype(values) begin () const |
|
|
|
{ return values; |
|
|
|
} |
|
|
|
decltype(values) end () const |
|
|
|
{ return values + length; |
|
|
|
} |
|
|
|
#endif |
|
|
|
|
|
|
|
} array; |
|
|
|
} object; |
|
|
|
|
|
|
|
} u; |
|
|
|
struct |
|
|
|
{ |
|
|
|
unsigned int length; |
|
|
|
struct _json_value ** values; |
|
|
|
|
|
|
|
union |
|
|
|
{ |
|
|
|
struct _json_value * next_alloc; |
|
|
|
void * object_mem; |
|
|
|
#if defined(__cplusplus) && __cplusplus >= 201103L |
|
|
|
decltype(values) begin () const |
|
|
|
{ return values; |
|
|
|
} |
|
|
|
decltype(values) end () const |
|
|
|
{ return values + length; |
|
|
|
} |
|
|
|
#endif |
|
|
|
|
|
|
|
} _reserved; |
|
|
|
} array; |
|
|
|
|
|
|
|
} u; |
|
|
|
|
|
|
|
/* Some C++ operator sugar */ |
|
|
|
union |
|
|
|
{ |
|
|
|
struct _json_value * next_alloc; |
|
|
|
void * object_mem; |
|
|
|
|
|
|
|
} _reserved; |
|
|
|
|
|
|
|
#ifdef __cplusplus |
|
|
|
|
|
|
|
public: |
|
|
|
/* Some C++ operator sugar */ |
|
|
|
|
|
|
|
inline _json_value () |
|
|
|
{ |
|
|
|
memset (this, 0, sizeof (_json_value)); |
|
|
|
} |
|
|
|
#ifdef __cplusplus |
|
|
|
|
|
|
|
inline const struct _json_value &operator [] (int index) const |
|
|
|
{ |
|
|
|
public: |
|
|
|
|
|
|
|
inline _json_value () |
|
|
|
{ memset (this, 0, sizeof (_json_value)); |
|
|
|
} |
|
|
|
|
|
|
|
inline const struct _json_value &operator [] (int index) const |
|
|
|
{ |
|
|
|
if (type != json_array || index < 0 |
|
|
|
|| ((unsigned int) index) >= u.array.length) |
|
|
|
|| ((unsigned int) index) >= u.array.length) |
|
|
|
{ |
|
|
|
return json_value_none; |
|
|
|
return json_value_none; |
|
|
|
} |
|
|
|
|
|
|
|
return *u.array.values [index]; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
inline const struct _json_value &operator [] (const char * index) const |
|
|
|
{ |
|
|
|
inline const struct _json_value &operator [] (const char * index) const |
|
|
|
{ |
|
|
|
if (type != json_object) |
|
|
|
return json_value_none; |
|
|
|
return json_value_none; |
|
|
|
|
|
|
|
for (unsigned int i = 0; i < u.object.length; ++ i) |
|
|
|
if (!strcmp (u.object.values [i].name, index)) |
|
|
|
return *u.object.values [i].value; |
|
|
|
if (!strcmp (u.object.values [i].name, index)) |
|
|
|
return *u.object.values [i].value; |
|
|
|
|
|
|
|
return json_value_none; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
inline operator const char * () const |
|
|
|
{ |
|
|
|
inline operator const char * () const |
|
|
|
{ |
|
|
|
switch (type) |
|
|
|
{ |
|
|
|
case json_string: |
|
|
|
return u.string.ptr; |
|
|
|
case json_string: |
|
|
|
return u.string.ptr; |
|
|
|
|
|
|
|
default: |
|
|
|
return ""; |
|
|
|
default: |
|
|
|
return ""; |
|
|
|
}; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
inline operator json_int_t () const |
|
|
|
{ |
|
|
|
inline operator json_int_t () const |
|
|
|
{ |
|
|
|
switch (type) |
|
|
|
{ |
|
|
|
case json_integer: |
|
|
|
return u.integer; |
|
|
|
case json_integer: |
|
|
|
return u.integer; |
|
|
|
|
|
|
|
case json_double: |
|
|
|
return (json_int_t) u.dbl; |
|
|
|
case json_double: |
|
|
|
return (json_int_t) u.dbl; |
|
|
|
|
|
|
|
default: |
|
|
|
return 0; |
|
|
|
default: |
|
|
|
return 0; |
|
|
|
}; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
inline operator bool () const |
|
|
|
{ |
|
|
|
inline operator bool () const |
|
|
|
{ |
|
|
|
if (type != json_boolean) |
|
|
|
return false; |
|
|
|
return false; |
|
|
|
|
|
|
|
return u.boolean != 0; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
inline operator double () const |
|
|
|
{ |
|
|
|
inline operator double () const |
|
|
|
{ |
|
|
|
switch (type) |
|
|
|
{ |
|
|
|
case json_integer: |
|
|
|
return (double) u.integer; |
|
|
|
case json_integer: |
|
|
|
return (double) u.integer; |
|
|
|
|
|
|
|
case json_double: |
|
|
|
return u.dbl; |
|
|
|
case json_double: |
|
|
|
return u.dbl; |
|
|
|
|
|
|
|
default: |
|
|
|
return 0; |
|
|
|
default: |
|
|
|
return 0; |
|
|
|
}; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
#endif |
|
|
|
#endif |
|
|
|
|
|
|
|
} json_value; |
|
|
|
} json_value; |
|
|
|
|
|
|
|
json_value * json_parse (const json_char * json, |
|
|
|
size_t length); |
|
|
|
json_value * json_parse (const json_char * json, |
|
|
|
size_t length); |
|
|
|
|
|
|
|
json_value * json_parse_ex (json_settings * settings, |
|
|
|
const json_char * json, |
|
|
|
size_t length, |
|
|
|
char * error); |
|
|
|
#define json_error_max 128 |
|
|
|
json_value * json_parse_ex (json_settings * settings, |
|
|
|
const json_char * json, |
|
|
|
size_t length, |
|
|
|
char * error); |
|
|
|
|
|
|
|
void json_value_free (json_value *); |
|
|
|
void json_value_free (json_value *); |
|
|
|
|
|
|
|
|
|
|
|
/* Not usually necessary, unless you used a custom mem_alloc and now want to |
|
|
|
* use a custom mem_free. |
|
|
|
*/ |
|
|
|
void json_value_free_ex (json_settings * settings, |
|
|
|
json_value *); |
|
|
|
/* Not usually necessary, unless you used a custom mem_alloc and now want to |
|
|
|
* use a custom mem_free. |
|
|
|
*/ |
|
|
|
void json_value_free_ex (json_settings * settings, |
|
|
|
json_value *); |
|
|
|
|
|
|
|
|
|
|
|
#ifdef __cplusplus |
|
|
|
} /* extern "C" */ |
|
|
|
} /* extern "C" */ |
|
|
|
#endif |
|
|
|
|
|
|
|
#endif |
|
|
|