1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197
|
/* Structures for JSON parsing using only fixed-extent memory
*
* This file is Copyright by the GPSD project
* SPDX-License-Identifier: BSD-2-clause
*/
#include <ctype.h>
#include <stdbool.h>
#include <sys/time.h> // for struct timespec
/* the json_type is the type of the C variable the JSON
* value gets placed in. It is NOT the JSON type as used
* in the JSON standard. But it does partly specify how
* the JSON value is decoded.
*
* For example a t_character must be in quotes, but a t_byte
* is a bare number. */
typedef enum {t_array,
t_boolean,
t_byte,
t_character,
t_check,
t_ignore,
t_integer,
t_longint,
t_object,
t_real,
t_short,
t_string,
t_structobject,
t_time,
t_timespec,
t_ubyte,
t_uinteger,
t_ulongint,
t_ushort}
json_type;
struct json_enum_t {
char *name;
int value;
};
struct json_array_t {
json_type element_type;
union {
struct {
const struct json_attr_t *subtype;
char *base;
size_t stride;
} objects;
struct {
char **ptrs;
char *store;
int storelen;
} strings;
struct {
int *store;
} bytes;
struct {
unsigned int *store;
} ubytes;
struct {
int *store;
} integers;
struct {
unsigned int *store;
} uintegers;
struct {
long *store;
} longint;
struct {
unsigned long *store;
} ulongint;
struct {
short *store;
} shorts;
struct {
unsigned short *store;
} ushorts;
struct {
double *store;
} reals;
struct {
bool *store;
} booleans;
struct {
struct timespec *store;
} timespecs;
} arr;
int *count, maxlen;
};
struct json_attr_t {
char *attribute;
json_type type;
union {
bool *boolean;
char *byte;
char *character;
char *string;
double *real;
int *integer;
long *longint;
short *shortint;
size_t offset;
struct json_array_t array;
unsigned char *ubyte;
unsigned int *uinteger;
unsigned long *ulongint;
unsigned short *ushortint;
struct timespec *ts;
} addr;
union {
bool boolean;
char byte;
char character;
char *check;
double real;
int integer;
long longint;
short shortint;
unsigned char ubyte;
unsigned int uinteger;
unsigned long ulongint;
unsigned short ushortint;
struct timespec ts;
} dflt;
size_t len;
const struct json_enum_t *map;
bool nodefault;
};
#define JSON_ATTR_MAX 31 // max chars in JSON attribute name
#define JSON_VAL_MAX 512 // max chars in JSON value part
#ifdef __cplusplus
extern "C" {
#endif
int json_read_object(const char *, const struct json_attr_t *,
const char **);
int json_read_array(const char *, const struct json_array_t *,
const char **);
const char *json_error_string(int);
void json_enable_debug(int, FILE *);
char *json_quote(const char *, char *, size_t, size_t);
#ifdef __cplusplus
}
#endif
#define JSON_ERR_OBSTART 1 // non-WS when expecting object start
#define JSON_ERR_ATTRSTART 2 // non-WS when expecting attrib start
#define JSON_ERR_BADATTR 3 // unknown attribute name
#define JSON_ERR_ATTRLEN 4 // attribute name too long
#define JSON_ERR_NOARRAY 5 // saw [ when not expecting array
#define JSON_ERR_NOBRAK 6 // array element specified, but no [
#define JSON_ERR_STRLONG 7 // string value too long
#define JSON_ERR_TOKLONG 8 // token value too long
#define JSON_ERR_BADTRAIL 9 // garbage expecting comma or } or ]
#define JSON_ERR_ARRAYSTART 10 // didn't find expected array start
#define JSON_ERR_OBJARR 11 // error while parsing object array
#define JSON_ERR_SUBTOOLONG 12 // too many array elements
#define JSON_ERR_BADSUBTRAIL 13 // garbage while expecting array comma
#define JSON_ERR_SUBTYPE 14 // unsupported array element type
#define JSON_ERR_BADSTRING 15 // error while string parsing
#define JSON_ERR_CHECKFAIL 16 // check attribute not matched
#define JSON_ERR_NOPARSTR 17 // no strings in parallel arrays
#define JSON_ERR_BADENUM 18 // invalid enumerated value
#define JSON_ERR_QNONSTRING 19 // quoted value when expecting nonstring
#define JSON_ERR_NONQSTRING 20 // no quoted value when expecting string
#define JSON_ERR_MISC 21 // other data conversion error
#define JSON_ERR_BADNUM 22 // error parsing a numerical argument
#define JSON_ERR_NULLPTR 23 // unexpected null value or attribute
#define JSON_ERR_NOCURLY 24 // object element specified, but no {
#define JSON_ERR_EMPTY 25 // input was empty or white-space only
/*
* Use the following macros to declare template initializers for structobject
* arrays. Writing the equivalents out by hand is error-prone.
*
* STRUCTOBJECT takes a structure name s, and a fieldname f in s.
*
* STRUCTARRAY takes the name of a structure array, a pointer to a an
* initializer defining the subobject type, and the address of an integer to
* store the length in.
*/
#define STRUCTOBJECT(s, f) .addr.offset = offsetof(s, f)
#define STRUCTARRAY(a, e, n) \
.addr.array.element_type = t_structobject, \
.addr.array.arr.objects.subtype = e, \
.addr.array.arr.objects.base = (char*)a, \
.addr.array.arr.objects.stride = sizeof(a[0]), \
.addr.array.count = n, \
.addr.array.maxlen = NITEMS(a)
// vim: set expandtab shiftwidth=4
|