44 return atoi(&j[tok->
start]);
57 return atol(&j[tok->
start]);
71 return &j[tok->
start];
97 int size = (*tok)->size;
98 log(LOG_JSMN_PARSING,
"Ignoring list of size %d", size);
99 for (
int i=0; i<size; i++){
107 int size = (*tok)->size;
108 log(LOG_JSMN_PARSING,
"Ignoring object of size %d", size);
109 for (
int i=0; i<size; i++) {
121 switch ( (*tok)->type ) {
139 FILE *file = fopen(filename,
"r");
147 fseek(file, 0, SEEK_END);
148 long fsize = ftell(file);
152 char *contents = malloc(fsize + 1);
153 size_t rtn = fread(contents, fsize, 1, file);
158 contents[fsize] =
'\0';
168 #define MAX_RETRIES 1024
177 int n_tokens =
jsmn_parse(&parser, contents, strlen(contents), NULL, 16384);
178 log(LOG_JSMN_PARSING,
"Allocating %d tokens", n_tokens);
183 n_tokens =
jsmn_parse(&parser, contents, strlen(contents), tokens, n_tokens);
184 log(LOG_JSMN_PARSING,
"Allocated %d tokens", n_tokens);
198 int rtn =
parse_jsmn_obj(&tokens, contents, &init_state, &saved_state);
205 log(LOG_JSMN_PARSING,
"Parsed %d top-level objects", rtn);
210 while (saved_state != NULL){
211 log(LOG_JSMN_PARSING,
"Retrying saved states");
214 log_error(
"Failed to re-interpret saved JSMN tokens");
219 if (n_retries > 100) {
220 log_error(
"Something is wrong. Retried too many times");
238 km->
parse != 0; km++){
239 if (strncasecmp(key, km->key, strlen(km->key)) == 0 &&
240 km->parent_type == parent_type){
263 while (saved != NULL){
266 log(LOG_JSMN_PARSING,
"Retrying key: %s", key);
270 int rtn = parser(&tok, j, saved, saved_states);
275 }
else if (rtn == 0){
276 log(LOG_JSMN_PARSING,
"Successfully parsed retried key '%s'", key);
278 if (*saved_states == saved)
279 *saved_states = saved->
next;
286 }
else if (rtn == 1){
287 log(LOG_JSMN_PARSING,
"Will try again on the next pass...");
291 log_error(
"Unknown return code: %d", rtn);
295 log_error(
"Retried too many times. Something is wrong");
300 if (success == -1 && key != NULL) {
301 log_error(
"Failed while reprocessing key '%s' for missing dependencies", key);
302 log_error(
"Value for improper key %s", key + (strlen(key) + 1));
321 int size = (*tok)->size;
325 for (
int i=0; i<size; i++){
326 log(LOG_JSMN_PARSING,
"Parsing list item %d", i);
333 new_state.
next = NULL;
362 int size = (*tok)->size;
368 for (
int i=0; i<size; i++){
375 log_error(
"No matching key %s for type %d",
381 void *pre_data = state->
data;
382 state->
tok = ++(*tok);
383 int rtn = parse(tok, j, state, saved);
389 log(LOG_JSMN_PARSING,
"Deferring parsing of %s", key);
390 struct json_state *to_save = malloc(
sizeof(*to_save));
391 to_save->
data = pre_data;
393 to_save->
next = *saved;
394 to_save->
tok = pre_tok;
397 log(LOG_JSMN_PARSING,
"Successfully parsed %s", key);
jsmn_parsing_fn parse
The function to be called when this string is seen at the appropriate place in the input JSON...
char * tok_to_str(jsmntok_t *tok, char *j)
Destructively extracts a c-string from a jsmn token.
int jsmn_ignore(jsmntok_t **tok, char *j, struct json_state *in, struct json_state **saved)
Ignores a JSMN value.
static struct key_mapping * jsmn_key_map
Global key mapping, giving which function should be called for each JSMN key.
long tok_to_long(jsmntok_t *tok, char *j)
Destructively extracts an int from a jsmn token.
int jsmn_ignore_list(jsmntok_t **tok, char *j, struct json_state *in, struct json_state **saved)
#define log_perror(fmt,...)
Logging of status messages to the terminal.
Structure to hold state while parsing JSON.
int parent_type
The type of object that is being create.
int(* jsmn_parsing_fn)(jsmntok_t **tok, char *j, struct json_state *state, struct json_state **saved)
Typedef for a jsmn parsing function.
Structure to map a key + state to a function.
int tok_to_int(jsmntok_t *tok, char *j)
Destructively extracts an int from a jsmn token.
#define log_error(fmt,...)
struct json_state(* jsmn_initializer)(struct json_state *state, int index)
Typedef for a json_state initializer, used when iterating over lists of objects.
static jsmn_parsing_fn get_parse_fn(char *key, int parent_type)
Returns the function to parse a given key.
int parse_jsmn_obj(jsmntok_t **tok, char *j, struct json_state *state, struct json_state **saved)
Parses a single JSMN object utilizing the provided (global) key map.
int parse_jsmn_obj_list(jsmntok_t **tok, char *j, struct json_state *state, struct json_state **saved, jsmn_initializer init)
Parses an array of JSMN objects.
#define ASSERT_JSMN_TYPE(tok, toktype, j)
Asserts that the type of the current token is the provided type, and logs an error if that is not the...
General-purpose function to interact with JSMN library, and create objects (potentially with circular...
void * get_root_jsmn_obj()
Returns the initial object passed into the JSON parser.
#define MAX_RETRIES
The maximum number of times that a PARSE_FN can return 1 before an error is raised.
void jsmn_init(jsmn_parser *parser)
Create JSON parser over an array of tokens.
int parse_file_into_obj(const char *filename, void *obj, struct key_mapping *km)
Using the provided functions, parses the JSON present in 'filename' and stores the resulting object i...
void * data
The object currently under construction.
int jsmn_parse(jsmn_parser *parser, const char *js, size_t len, jsmntok_t *tokens, unsigned int num_tokens)
Run JSON parser.
static int retry_saved(struct json_state **saved, char *j)
Retries tokens which have been deferred.
int parse_str_into_obj(char *contents, void *obj, struct key_mapping *km)
Using the provided functions, parses the JSON present in in the provided string and stores the result...
#define log(level, fmt,...)
Log at a custom level.
static void * global_obj
The object which is pased into the JSON parser to be filled.
int jsmn_ignore_obj(jsmntok_t **tok, char *j, struct json_state *in, struct json_state **saved)
jsmntok_t * tok
When saving state, provides a linked-list.
static const char tokens[256]