GFXprim
2D bitmap graphics library with emphasis on speed and correctness
Loading...
Searching...
No Matches
Data Structures | Macros | Typedefs | Functions
gp_json_reader.h File Reference

A recursive descend JSON parser. More...

#include <stdio.h>
#include <core/gp_compiler.h>
#include <utils/gp_json_common.h>

Go to the source code of this file.

Data Structures

struct  gp_json_reader
 A JSON parser internal state. More...
 
struct  gp_json_val
 A parsed JSON key value pair. More...
 
struct  gp_json_obj_attr
 A JSON object attribute description i.e. key and type. More...
 
struct  gp_json_obj
 A JSON object description. More...
 
struct  gp_json_reader_state
 A JSON parser state. More...
 

Macros

#define GP_JSON_READER_INIT(buf, buf_len)
 A gp_json_reader initializer with default values.
 
#define GP_JSON_OBJ_FOREACH(self, res)    for (gp_json_obj_first(self, res); gp_json_val_valid(res); gp_json_obj_next(self, res))
 A loop over a JSON object.
 
#define GP_JSON_OBJ_ATTR(keyv, typev)    {.key = keyv, .type = typev}
 A gp_json_obj_attr initializer.
 
#define GP_JSON_OBJ_ATTR_IDX(key_idx, keyv, typev)    [key_idx] = {.key = keyv, .type = typev}
 gp_json_obj_attr intializer with an array index.
 
#define GP_JSON_OBJ_FOREACH_FILTER(self, res, obj, ign)
 A loop over a JSON object with a pre-defined list of expected attributes.
 
#define GP_JSON_ARR_FOREACH(self, res)    for (gp_json_arr_first(self, res); gp_json_val_valid(res); gp_json_arr_next(self, res))
 A loop over a JSON array.
 

Typedefs

typedef struct gp_json_obj_attr gp_json_obj_attr
 A JSON object attribute description i.e. key and type.
 
typedef struct gp_json_obj gp_json_obj
 A JSON object description.
 
typedef struct gp_json_reader_state gp_json_reader_state
 A JSON parser state.
 

Functions

gp_json_valgp_json_val_alloc (size_t buf_size)
 Allocates a JSON value.
 
void gp_json_val_free (gp_json_val *self)
 Frees a JSON value.
 
static int gp_json_val_valid (struct gp_json_val *res)
 Checks is result has valid type.
 
void gp_json_err (gp_json_reader *self, const char *fmt,...)
 Fills the reader error.
 
void gp_json_err_print (gp_json_reader *self)
 Prints error stored in the buffer.
 
void gp_json_warn (gp_json_reader *self, const char *fmt,...)
 Prints a warning.
 
static int gp_json_reader_err (gp_json_reader *self)
 Returns true if error was encountered.
 
enum gp_json_type gp_json_next_type (gp_json_reader *self)
 Returns the type of next element in buffer.
 
enum gp_json_type gp_json_reader_start (gp_json_reader *self)
 Returns if first element in JSON is object or array.
 
int gp_json_obj_first (gp_json_reader *self, struct gp_json_val *res)
 Starts parsing of a JSON object.
 
int gp_json_obj_next (gp_json_reader *self, struct gp_json_val *res)
 Parses next value from a JSON object.
 
size_t gp_json_lookup (const void *arr, size_t memb_size, size_t list_len, const char *key)
 Utility function for log(n) lookup in a sorted array.
 
int gp_json_obj_first_filter (gp_json_reader *self, struct gp_json_val *res, const struct gp_json_obj *obj, const struct gp_json_obj *ign)
 Starts parsing of a JSON object with attribute lists.
 
int gp_json_obj_next_filter (gp_json_reader *self, struct gp_json_val *res, const struct gp_json_obj *obj, const struct gp_json_obj *ign)
 Parses next value from a JSON object with attribute lists.
 
int gp_json_obj_skip (gp_json_reader *self)
 Skips parsing of a JSON object.
 
int gp_json_arr_first (gp_json_reader *self, struct gp_json_val *res)
 Starts parsing of a JSON array.
 
int gp_json_arr_next (gp_json_reader *self, struct gp_json_val *res)
 Parses next value from a JSON array.
 
int gp_json_arr_skip (gp_json_reader *self)
 Skips parsing of a JSON array.
 
static gp_json_reader_state gp_json_reader_state_save (gp_json_reader *self)
 Returns a parser state at the start of current object/array.
 
static void gp_json_reader_state_load (gp_json_reader *self, gp_json_reader_state state)
 Returns the parser to a saved state.
 
static void gp_json_reader_reset (gp_json_reader *self)
 Resets the parser to a start.
 
gp_json_readergp_json_reader_load (const char *path)
 Loads a file into an gp_json_reader buffer.
 
void gp_json_reader_free (gp_json_reader *self)
 Frees an gp_json_reader buffer.
 
void gp_json_reader_finish (gp_json_reader *self)
 Prints errors and warnings at the end of parsing.
 
static int gp_json_reader_consumed (gp_json_reader *self)
 Returns non-zero if whole buffer has been consumed.
 

Detailed Description

A recursive descend JSON parser.

All the function that parse JSON return zero on success and non-zero on a failure. Once an error has happened all subsequent attempts to parse more return with non-zero exit status immediatelly. This is designed so that we can parse several values without checking each return value and only check if error has happened at the end of the sequence.

Definition in file gp_json_reader.h.

Macro Definition Documentation

◆ GP_JSON_ARR_FOREACH

#define GP_JSON_ARR_FOREACH (   self,
  res 
)     for (gp_json_arr_first(self, res); gp_json_val_valid(res); gp_json_arr_next(self, res))

A loop over a JSON array.

GP_JSON_ARR_FOREACH(reader, val) {
printf("Got value type '%s'", gp_json_type_name(val->type));
...
}
const char * gp_json_type_name(enum gp_json_type type)
Returns type name.
#define GP_JSON_ARR_FOREACH(self, res)
A loop over a JSON array.
Parameters
selfA gp_json_reader.
resA gp_json_val to store the next parsed value to.

Definition at line 398 of file gp_json_reader.h.

◆ GP_JSON_OBJ_FOREACH

#define GP_JSON_OBJ_FOREACH (   self,
  res 
)     for (gp_json_obj_first(self, res); gp_json_val_valid(res); gp_json_obj_next(self, res))

A loop over a JSON object.

GP_JSON_OBJ_FOREACH(reader, val) {
printf("Got value id '%s' type '%s'", val->id, gp_json_type_name(val->type));
...
}
#define GP_JSON_OBJ_FOREACH(self, res)
A loop over a JSON object.
Parameters
selfA gp_json_reader.
resA gp_json_val to store the parsed value to.

Definition at line 239 of file gp_json_reader.h.

◆ GP_JSON_OBJ_FOREACH_FILTER

#define GP_JSON_OBJ_FOREACH_FILTER (   self,
  res,
  obj,
  ign 
)
Value:
for (gp_json_obj_first_filter(self, res, obj, ign); \
gp_json_val_valid(res); \
gp_json_obj_next_filter(self, res, obj, ign))
int gp_json_obj_first_filter(gp_json_reader *self, struct gp_json_val *res, const struct gp_json_obj *obj, const struct gp_json_obj *ign)
Starts parsing of a JSON object with attribute lists.

A loop over a JSON object with a pre-defined list of expected attributes.

static struct gp_json_obj_attr attrs[] = {
};
static struct gp_json_obj obj = {
attrs = filter_attrs,
.attr_cnt = GP_JSON_ARRAY_SIZE(filter_attrs)
};
GP_JSON_OBJ_FOREACH_FILTER(reader, val, &obj, NULL) {
printf("Got value id '%s' type '%s'",
attrs[val->idx].id, gp_json_type_name(val->type));
...
}
@ GP_JSON_BOOL
A boolean.
@ GP_JSON_INT
An integer.
#define GP_JSON_OBJ_FOREACH_FILTER(self, res, obj, ign)
A loop over a JSON object with a pre-defined list of expected attributes.
#define GP_JSON_OBJ_ATTR(keyv, typev)
A gp_json_obj_attr initializer.
A JSON object attribute description i.e. key and type.
A JSON object description.
const gp_json_obj_attr * attrs
A list of object attributes.
Parameters
selfA gp_json_reader.
resA gp_json_val to store the next parsed value to.
objA gp_json_obj with a description of attributes to parse.
ignA gp_json_obj with a description of attributes to ignore.

Definition at line 348 of file gp_json_reader.h.

◆ GP_JSON_READER_INIT

#define GP_JSON_READER_INIT (   buf,
  buf_len 
)
Value:
{ \
.max_depth = GP_JSON_RECURSION_MAX, \
.err_print = GP_JSON_ERR_PRINT, \
.err_print_priv = GP_JSON_ERR_PRINT_PRIV, \
.json = buf, \
.len = buf_len, \
}
#define GP_JSON_RECURSION_MAX
Maximal recursion depth allowed.

A gp_json_reader initializer with default values.

Parameters
bufA pointer to a buffer with JSON data.
buf_lenA JSON data buffer lenght.
Returns
A gp_json_reader initialized with default values.

Definition at line 32 of file gp_json_reader.h.

Function Documentation

◆ gp_json_arr_first()

int gp_json_arr_first ( gp_json_reader self,
struct gp_json_val res 
)

Starts parsing of a JSON array.

Parameters
selfA gp_json_reader.
resA gp_json_val to store the parsed value to.
Returns
Zero on success, non-zero otherwise.

◆ gp_json_arr_next()

int gp_json_arr_next ( gp_json_reader self,
struct gp_json_val res 
)

Parses next value from a JSON array.

If the res->type is GP_JSON_OBJ or GP_JSON_ARR it has to be parsed or skipped before next call to this function.

Parameters
selfA gp_json_reader.
resA gp_json_val to store the parsed value to.
Returns
Zero on success, non-zero otherwise.

◆ gp_json_arr_skip()

int gp_json_arr_skip ( gp_json_reader self)

Skips parsing of a JSON array.

Parameters
selfA gp_json_reader.
Returns
Zero on success, non-zero otherwise.

◆ gp_json_err()

void gp_json_err ( gp_json_reader self,
const char *  fmt,
  ... 
)

Fills the reader error.

Once buffer error is set all parsing functions return immediatelly with type set to GP_JSON_VOID.

Parameters
selfA gp_json_reader
fmtA printf like format string
...A printf like parameters

◆ gp_json_err_print()

void gp_json_err_print ( gp_json_reader self)

Prints error stored in the buffer.

The error takes into consideration the current offset in the buffer and prints a few preceding lines along with the exact position of the error.

The error is passed to the err_print() handler.

Parameters
selfA gp_json_reader

◆ gp_json_lookup()

size_t gp_json_lookup ( const void *  arr,
size_t  memb_size,
size_t  list_len,
const char *  key 
)

Utility function for log(n) lookup in a sorted array.

Parameters
listAnalphabetically sorted array.
list_lenArray length.
Returns
An array index or (size_t)-1 if key wasn't found.

◆ gp_json_next_type()

enum gp_json_type gp_json_next_type ( gp_json_reader self)

Returns the type of next element in buffer.

Parameters
selfA gp_json_reader
Returns
A type of next element in the buffer.

◆ gp_json_obj_first()

int gp_json_obj_first ( gp_json_reader self,
struct gp_json_val res 
)

Starts parsing of a JSON object.

Parameters
selfA gp_json_reader.
resA gp_json_val to store the parsed value to.
Returns
Zero on success, non-zero otherwise.

◆ gp_json_obj_first_filter()

int gp_json_obj_first_filter ( gp_json_reader self,
struct gp_json_val res,
const struct gp_json_obj obj,
const struct gp_json_obj ign 
)

Starts parsing of a JSON object with attribute lists.

Parameters
selfA gp_json_reader.
resA gp_json_val to store the parsed value to.
objA gp_json_obj object description.
ignA list of keys to ignore.
Returns
Zero on success, non-zero otherwise.

◆ gp_json_obj_next()

int gp_json_obj_next ( gp_json_reader self,
struct gp_json_val res 
)

Parses next value from a JSON object.

If the res->type is GP_JSON_OBJ or GP_JSON_ARR it has to be parsed or skipped before next call to this function.

Parameters
selfA gp_json_reader.
resA gp_json_val to store the parsed value to.
Returns
Zero on success, non-zero otherwise.

◆ gp_json_obj_next_filter()

int gp_json_obj_next_filter ( gp_json_reader self,
struct gp_json_val res,
const struct gp_json_obj obj,
const struct gp_json_obj ign 
)

Parses next value from a JSON object with attribute lists.

If the res->type is GP_JSON_OBJ or GP_JSON_ARR it has to be parsed or skipped before next call to this function.

Parameters
selfA gp_json_reader.
resA gp_json_val to store the parsed value to.
objA gp_json_obj object description.
ignA list of keys to ignore.
Returns
Zero on success, non-zero otherwise.

◆ gp_json_obj_skip()

int gp_json_obj_skip ( gp_json_reader self)

Skips parsing of a JSON object.

Parameters
selfA gp_json_reader.
Returns
Zero on success, non-zero otherwise.

◆ gp_json_reader_consumed()

static int gp_json_reader_consumed ( gp_json_reader self)
inlinestatic

Returns non-zero if whole buffer has been consumed.

Parameters
selfA gp_json_reader.
Returns
Non-zero if whole buffer was consumed.

Definition at line 502 of file gp_json_reader.h.

References gp_json_reader::len, and gp_json_reader::off.

◆ gp_json_reader_err()

static int gp_json_reader_err ( gp_json_reader self)
inlinestatic

Returns true if error was encountered.

Parameters
selfA gp_json_reader
Returns
True if error was encountered false otherwise.

Definition at line 182 of file gp_json_reader.h.

◆ gp_json_reader_finish()

void gp_json_reader_finish ( gp_json_reader self)

Prints errors and warnings at the end of parsing.

Checks if self->err is set and prints the error with gp_json_reader_err()

Checks if there is any text left after the parser has finished with gp_json_reader_consumed() and prints a warning if there were any non-whitespace characters left.

Parameters
selfA gp_json_reader

◆ gp_json_reader_free()

void gp_json_reader_free ( gp_json_reader self)

Frees an gp_json_reader buffer.

Parameters
selfA gp_json_reader allocated by gp_json_reader_load() function.

◆ gp_json_reader_load()

gp_json_reader * gp_json_reader_load ( const char *  path)

Loads a file into an gp_json_reader buffer.

The reader has to be later freed by gp_json_reader_free().

Parameters
pathA path to a file.
Returns
A gp_json_reader or NULL in a case of a failure.

◆ gp_json_reader_reset()

static void gp_json_reader_reset ( gp_json_reader self)
inlinestatic

Resets the parser to a start.

Parameters
selfA gp_json_reader

Definition at line 458 of file gp_json_reader.h.

References gp_json_reader::depth, gp_json_reader::off, and gp_json_reader::sub_off.

◆ gp_json_reader_start()

enum gp_json_type gp_json_reader_start ( gp_json_reader self)

Returns if first element in JSON is object or array.

Parameters
selfA gp_json_reader
Returns
On success returns GP_JSON_OBJ or GP_JSON_ARR. On failure GP_JSON_VOID.

◆ gp_json_reader_state_load()

static void gp_json_reader_state_load ( gp_json_reader self,
gp_json_reader_state  state 
)
inlinestatic

Returns the parser to a saved state.

This function could be used for the parser to return to the start of object or array saved by t the gp_json_reader_state_get() function.

Parameters
selfA gp_json_reader
stateAn parser state as returned by the gp_json_reader_state_get().

Definition at line 446 of file gp_json_reader.h.

References gp_json_reader::depth, gp_json_reader::off, and gp_json_reader::sub_off.

◆ gp_json_reader_state_save()

static gp_json_reader_state gp_json_reader_state_save ( gp_json_reader self)
inlinestatic

Returns a parser state at the start of current object/array.

This function could be used for the parser to return to the start of the currently parsed object or array.

Parameters
selfA gp_json_reader
Returns
A state that points to a start of the last object or array.

Definition at line 427 of file gp_json_reader.h.

References gp_json_reader::depth, and gp_json_reader::sub_off.

◆ gp_json_val_alloc()

gp_json_val * gp_json_val_alloc ( size_t  buf_size)

Allocates a JSON value.

Parameters
buf_sizeA maximal buffer size for a string value, pass 0 for default.
Returns
A newly allocated JSON value.

◆ gp_json_val_free()

void gp_json_val_free ( gp_json_val self)

Frees a JSON value.

Parameters
selfA JSON value previously allocated by gp_json_val_alloc().

◆ gp_json_val_valid()

static int gp_json_val_valid ( struct gp_json_val res)
inlinestatic

Checks is result has valid type.

Parameters
resA gp_json value.
Returns
Zero if result is not valid, non-zero otherwise.

Definition at line 133 of file gp_json_reader.h.

References gp_json_val::type.

◆ gp_json_warn()

void gp_json_warn ( gp_json_reader self,
const char *  fmt,
  ... 
)

Prints a warning.

Uses the print handler in the buffer to print a warning along with a few lines of context from the JSON at the current position.

Parameters
selfA gp_json_reader
fmtA printf-like error string.
...A printf-like parameters.