blob: 0ff7819f87c38bfe92d8c1a65f2a06f16fea94cf [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
#ifndef _JSON_H_
#define _JSON_H_
#include <stdbool.h>
#include <stdint.h>
#include <ctype.h>
#include <stdio.h>
#include <sys/types.h>
#ifdef __cplusplus
extern "C" {
#endif
#define JSON_VALUE_TYPE_BOOL (0)
#define JSON_VALUE_TYPE_UINT64 (1)
#define JSON_VALUE_TYPE_INT64 (2)
#define JSON_VALUE_TYPE_STRING (3)
#define JSON_VALUE_TYPE_ARRAY (4)
#define JSON_VALUE_TYPE_OBJECT (5)
struct json_value {
uint8_t jv_pad1;
uint8_t jv_type;
uint16_t jv_len;
union {
uint64_t u;
float fl;
char *str;
struct {
char **keys;
struct json_value **values;
} composite;
} jv_val;
};
#define JSON_VALUE_STRING(__jv, __str) \
(__jv)->jv_type = JSON_VALUE_TYPE_STRING; \
(__jv)->jv_len = strlen(__str); \
(__jv)->jv_val.str = (__str);
#define JSON_VALUE_STRINGN(__jv, __str, __len) \
(__jv)->jv_type = JSON_VALUE_TYPE_STRING; \
(__jv)->jv_len = (uint16_t) (__len); \
(__jv)->jv_val.str = (__str);
#define JSON_VALUE_BOOL(__jv, __v) \
(__jv)->jv_type = JSON_VALUE_TYPE_BOOL; \
(__jv)->jv_val.u = (__v);
#define JSON_VALUE_INT(__jv, __v) \
(__jv)->jv_type = JSON_VALUE_TYPE_INT64; \
(__jv)->jv_val.u = (uint64_t) __v;
#define JSON_VALUE_UINT(__jv, __v) \
(__jv)->jv_type = JSON_VALUE_TYPE_UINT64; \
(__jv)->jv_val.u = (uint64_t) __v;
/* Encoding functions */
typedef int (*json_write_func_t)(void *buf, char *data,
int len);
struct json_encoder {
json_write_func_t je_write;
void *je_arg;
int je_wr_commas:1;
char je_encode_buf[64];
};
#define JSON_NITEMS(x) (int)(sizeof(x)/sizeof(x[0]))
int json_encode_object_start(struct json_encoder *);
int json_encode_object_key(struct json_encoder *encoder, char *key);
int json_encode_object_entry(struct json_encoder *, char *,
struct json_value *);
int json_encode_object_finish(struct json_encoder *);
int json_encode_array_name(struct json_encoder *encoder, char *name);
int json_encode_array_start(struct json_encoder *encoder);
int json_encode_array_value(struct json_encoder *encoder, struct json_value *val);
int json_encode_array_finish(struct json_encoder *encoder);
/* Json parser definitions */
typedef enum {
t_integer,
t_uinteger,
t_real,
t_string,
t_boolean,
t_character,
t_object,
t_structobject,
t_array,
t_check,
t_ignore
} json_type;
struct json_enum_t {
char *name;
long long 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 {
long long int *store;
} integers;
struct {
long long unsigned int *store;
} uintegers;
struct {
double *store;
} reals;
struct {
bool *store;
} booleans;
} arr;
int *count;
int maxlen;
};
struct json_attr_t {
char *attribute;
json_type type;
union {
long long int *integer;
long long unsigned int *uinteger;
double *real;
char *string;
bool *boolean;
char *character;
struct json_array_t array;
size_t offset;
} addr;
union {
long long int integer;
long long unsigned int uinteger;
double real;
bool boolean;
char character;
char *check;
} dflt;
size_t len;
const struct json_enum_t *map;
bool nodefault;
};
struct json_buffer;
/* when you implement a json buffer, you must implement these functions */
/* returns the next character in the buffer or '\0'*/
typedef char (*json_buffer_read_next_byte_t)(struct json_buffer *);
/* returns the previous character in the buffer or '\0' */
typedef char (*json_buffer_read_prev_byte_t)(struct json_buffer *);
/* returns the number of characters read or zero */
typedef int (*json_buffer_readn_t)(struct json_buffer *, char *buf, int n);
struct json_buffer {
json_buffer_readn_t jb_readn;
json_buffer_read_next_byte_t jb_read_next;
json_buffer_read_prev_byte_t jb_read_prev;
};
#define JSON_ATTR_MAX 31 /* max chars in JSON attribute name */
#define JSON_VAL_MAX 512 /* max chars in JSON value part */
int json_read_object(struct json_buffer *, const struct json_attr_t *);
int json_read_array(struct json_buffer *, const struct json_array_t *);
#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 while 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 /* can't support strings in parallel arrays */
#define JSON_ERR_BADENUM 18 /* invalid enumerated value */
#define JSON_ERR_QNONSTRING 19 /* saw quoted value when expecting nonstring */
#define JSON_ERR_NONQSTRING 19 /* didn't see quoted value when expecting string */
#define JSON_ERR_MISC 20 /* other data conversion error */
#define JSON_ERR_BADNUM 21 /* error while parsing a numerical argument */
#define JSON_ERR_NULLPTR 22 /* unexpected null value or attribute pointer */
/*
* Use the following macros to declare template initializers for structobject
* arrays. Writing the equivalents out by hand is error-prone.
*
* JSON_STRUCT_OBJECT takes a structure name s, and a fieldname f in s.
*
* JSON_STRUCT_ARRAY 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 JSON_STRUCT_OBJECT(s, f) .addr.offset = offsetof(s, f)
#define JSON_STRUCT_ARRAY(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 = (int)(sizeof(a)/sizeof(a[0]))
#ifdef __cplusplus
}
#endif
#endif /* _JSON_H_ */
/**
* @} OSEncoding
* @} OSJSON
*/