Skip to content

Commit

Permalink
Merge branch 'develop'
Browse files Browse the repository at this point in the history
  • Loading branch information
MaJerle committed Dec 15, 2020
2 parents e49f6d9 + 7b109e2 commit 40dc4de
Show file tree
Hide file tree
Showing 11 changed files with 161 additions and 52 deletions.
2 changes: 1 addition & 1 deletion dev/VisualStudio/lwjson_opts.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
* This file is part of LwJSON - Lightweight JSON format parser.
*
* Author: Tilen MAJERLE <tilen@majerle.eu>
* Version: v1.1.0
* Version: v1.2.0
*/
#ifndef LWJSON_HDR_OPTS_H
#define LWJSON_HDR_OPTS_H
Expand Down
4 changes: 2 additions & 2 deletions docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
author = 'Tilen MAJERLE'

# The full version, including alpha/beta/rc tags
version = 'v1.1.0'
version = 'v1.2.0'

# Try to get branch at which this is running
# and try to determine which version to display in sphinx
Expand Down Expand Up @@ -112,7 +112,7 @@
'css/custom.css',
]
html_js_files = [
'https://kit.fontawesome.com/3102794088.js'
'https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.1/css/all.min.css'
]

master_doc = 'index'
Expand Down
2 changes: 1 addition & 1 deletion docs/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ Features
^^^^^^^^

* Written in ANSI C99, compatible with ``size_t`` for size data types
* RFC 4627 compliant
* RFC 4627 and RFC 8259 compliant
* Based on static token allocation with optional application dynamic pre-allocation
* No recursion during parse operation
* Re-entrant functions
Expand Down
3 changes: 3 additions & 0 deletions examples/example_minimal.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,5 +17,8 @@ example_minimal_run(void) {
if ((t = lwjson_find(&lwjson, "mykey")) != NULL) {
printf("Key found with data type: %d\r\n", (int)t->type);
}

/* Call this when not used anymore */
lwjson_free(&lwjson);
}
}
6 changes: 6 additions & 0 deletions examples/example_traverse.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,10 @@ static lwjson_t lwjson;
/* Parse JSON */
void
example_traverse_run(void) {
/* Initialize and pass statically allocated tokens */
lwjson_init(&lwjson, tokens, LWJSON_ARRAYSIZE(tokens));

/* Try to parse input string */
if (lwjson_parse(&lwjson, "{\"mykey\":\"myvalue\",\"num\":1,\"obj\":{},\"arr\":[1,2,3,4]}") == lwjsonOK) {
lwjson_token_t* t;
printf("JSON parsed..\r\n");
Expand All @@ -33,5 +36,8 @@ example_traverse_run(void) {
}
printf("\n");
}

/* Call this when not used anymore */
lwjson_free(&lwjson);
}
}
44 changes: 26 additions & 18 deletions lwjson/src/include/lwjson/lwjson.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
* This file is part of LwJSON - Lightweight JSON format parser.
*
* Author: Tilen MAJERLE <tilen@majerle.eu>
* Version: v1.1.0
* Version: v1.2.0
*/
#ifndef LWJSON_HDR_H
#define LWJSON_HDR_H
Expand Down Expand Up @@ -90,12 +90,12 @@ typedef struct lwjson_token {
size_t token_name_len; /*!< Length of token name (this is needed to support const input strings to parse) */
union {
struct {
const char* token_value; /*!< Value if type is not \ref LWJSON_TYPE_OBJECT or \ref LWJSON_TYPE_ARRAY */
const char* token_value; /*!< Pointer to the beginning of the string */
size_t token_value_len; /*!< Length of token value (this is needed to support const input strings to parse) */
} str; /*!< String data */
lwjson_real_t num_real; /*!< Real number format */
lwjson_int_t num_int; /*!< Int number format */
struct lwjson_token* first_child; /*!< First children object */
struct lwjson_token* first_child; /*!< First children object for object or array type */
} u; /*!< Union with different data types */
} lwjson_token_t;

Expand All @@ -122,14 +122,14 @@ typedef struct {
} flags; /*!< List of flags */
} lwjson_t;

lwjsonr_t lwjson_init(lwjson_t* lw, lwjson_token_t* tokens, size_t tokens_len);
lwjsonr_t lwjson_parse(lwjson_t* lw, const char* json_str);
lwjsonr_t lwjson_reset(lwjson_t* lw);
const lwjson_token_t* lwjson_find(lwjson_t* lw, const char* path);
lwjsonr_t lwjson_free(lwjson_t* lw);
lwjsonr_t lwjson_init(lwjson_t* lw, lwjson_token_t* tokens, size_t tokens_len);
lwjsonr_t lwjson_parse(lwjson_t* lw, const char* json_str);
const lwjson_token_t* lwjson_find(lwjson_t* lw, const char* path);
const lwjson_token_t* lwjson_find_ex(lwjson_t* lw, const lwjson_token_t* token, const char* path);
lwjsonr_t lwjson_free(lwjson_t* lw);

void lwjson_print_token(const lwjson_token_t* token);
void lwjson_print_json(const lwjson_t* lw);
void lwjson_print_token(const lwjson_token_t* token);
void lwjson_print_json(const lwjson_t* lw);

/**
* \brief Get number of tokens used to parse JSON
Expand All @@ -139,7 +139,7 @@ void lwjson_print_json(const lwjson_t* lw);
#define lwjson_get_tokens_used(lw) (((lw) != NULL) ? ((lw)->next_free_token_pos + 1) : 0)

/**
* \brief Get top token on a list
* \brief Get very first token of LwJSON instance
* \param[in] lw: Pointer to LwJSON instance
* \return Pointer to first token
*/
Expand All @@ -150,30 +150,31 @@ void lwjson_print_json(const lwjson_t* lw);
* \param[in] token: token with integer type
* \return Int number if type is integer, `0` otherwise
*/
#define lwjson_get_val_int(token) (((token) != NULL && (token)->type == LWJSON_TYPE_NUM_INT) ? (token)->u.num_int : 0)
#define lwjson_get_val_int(token) ((lwjson_int_t)(((token) != NULL && (token)->type == LWJSON_TYPE_NUM_INT) ? (token)->u.num_int : 0))

/**
* \brief Get token value for \ref LWJSON_TYPE_NUM_REAL type
* \param[in] token: token with real type
* \return Real numbeer if type is real, `0` otherwise
*/
#define lwjson_get_val_real(token) (((token) != NULL && (token)->type == LWJSON_TYPE_NUM_REAL) ? (token)->u.num_real : 0)
#define lwjson_get_val_real(token) ((lwjson_real_t)(((token) != NULL && (token)->type == LWJSON_TYPE_NUM_REAL) ? (token)->u.num_real : 0))

/**
* \brief Get for child token for \ref LWJSON_TYPE_OBJECT or \ref LWJSON_TYPE_ARRAY types
* \brief Get first child token for \ref LWJSON_TYPE_OBJECT or \ref LWJSON_TYPE_ARRAY types
* \param[in] token: token with integer type
* \return Pointer to first child
* \return Pointer to first child or `NULL` if parent token is not object or array
*/
#define lwjson_get_first_child(token) (const void *)(((token) != NULL && ((token)->type == LWJSON_TYPE_OBJECT || (token)->type == LWJSON_TYPE_ARRAY)) ? (token)->u.first_child : NULL)

/**
* \brief Get string value from JSON token
* \param[in] token: Token with string type
* \param[out] str_len: Pointer to variable holding length of string
* \return Pointer to string
* \param[out] str_len: Pointer to variable holding length of string.
* Set to `NULL` if not used
* \return Pointer to string or `NULL` if invalid token type
*/
static inline const char*
lwjson_get_val_string(lwjson_token_t* token, size_t* str_len) {
lwjson_get_val_string(const lwjson_token_t* token, size_t* str_len) {
if (token != NULL && token->type == LWJSON_TYPE_STRING) {
if (str_len != NULL) {
*str_len = token->u.str.token_value_len;
Expand All @@ -183,6 +184,13 @@ lwjson_get_val_string(lwjson_token_t* token, size_t* str_len) {
return NULL;
}

/**
* \brief Get length of string for \ref LWJSON_TOKEN_STRING token type
* \param[in] token: token with string type
* \return Length of string in units of bytes
*/
#define lwjson_get_val_string_length(token) ((size_t)(((token) != NULL && (token)->type == LWJSON_TYPE_STRING) ? (token)->u.str.token_value_len : 0))

/**
* \}
*/
Expand Down
2 changes: 1 addition & 1 deletion lwjson/src/include/lwjson/lwjson_opt.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
* This file is part of LwJSON - Lightweight JSON format parser.
*
* Author: Tilen MAJERLE <tilen@majerle.eu>
* Version: v1.1.0
* Version: v1.2.0
*/
#ifndef LWJSON_HDR_OPT_H
#define LWJSON_HDR_OPT_H
Expand Down
2 changes: 1 addition & 1 deletion lwjson/src/include/lwjson/lwjson_opts_template.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
* This file is part of LwJSON - Lightweight JSON format parser.
*
* Author: Tilen MAJERLE <tilen@majerle.eu>
* Version: v1.1.0
* Version: v1.2.0
*/
#ifndef LWJSON_HDR_OPTS_H
#define LWJSON_HDR_OPTS_H
Expand Down
36 changes: 31 additions & 5 deletions lwjson/src/lwjson/lwjson.c
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
* This file is part of LwJSON - Lightweight JSON format parser.
*
* Author: Tilen MAJERLE <tilen@majerle.eu>
* Version: v1.1.0
* Version: v1.2.0
*/
#include <string.h>
#include "lwjson/lwjson.h"
Expand Down Expand Up @@ -596,7 +596,7 @@ lwjson_parse(lwjson_t* lw, const char* json_str) {
* Check what are values after the token value
*
* As per RFC4627, every token value may have one or more
* blank characters, followed by one of below options:
* blank characters, followed by one of below options:
* - Comma separator for next token
* - End of array indication
* - End of object indication
Expand All @@ -617,7 +617,7 @@ lwjson_parse(lwjson_t* lw, const char* json_str) {
to = NULL;
}
if (to != NULL) {
if (to->type != LWJSON_TYPE_ARRAY || to->type != LWJSON_TYPE_OBJECT) {
if (to->type != LWJSON_TYPE_ARRAY && to->type != LWJSON_TYPE_OBJECT) {
res = lwjsonERRJSON;
}
to->token_name = NULL;
Expand All @@ -631,13 +631,14 @@ lwjson_parse(lwjson_t* lw, const char* json_str) {
}

/**
* \brief Reset token instances and prepare for new parsing
* \brief Free token instances (specially used in case of dynamic memory allocation)
* \param[in,out] lw: LwJSON instance
* \return \ref lwjsonOK on success, member of \ref lwjsonr_t otherwise
*/
lwjsonr_t
lwjson_reset(lwjson_t* lw) {
lwjson_free(lwjson_t* lw) {
memset(lw->tokens, 0x00, sizeof(*lw->tokens) * lw->tokens_len);
lw->flags.parsed = 0;
return lwjsonOK;
}

Expand All @@ -655,3 +656,28 @@ lwjson_find(lwjson_t* lw, const char* path) {
}
return prv_find(lwjson_get_first_token(lw), path);
}

/**
* \brief Find first match in the given path for JSON path
* JSON must be valid and parsed with \ref lwjson_parse function
*
* \param[in] lw: JSON instance with parsed JSON string
* \param[in] token: Root token to start search at.
* Token must be type \ref LWJSON_TYPE_OBJECT or \ref LWJSON_TYPE_ARRAY.
* Set to `NULL` to use root token of LwJSON object
* \param[in] path: path with dot-separated entries to search for JSON key
* \return Pointer to found token on success, `NULL` if token cannot be found
*/
const lwjson_token_t*
lwjson_find_ex(lwjson_t* lw, const lwjson_token_t* token, const char* path) {
if (lw == NULL || !lw->flags.parsed || path == NULL) {
return NULL;
}
if (token == NULL) {
token = lwjson_get_first_token(lw);
}
if (token == NULL || (token->type != LWJSON_TYPE_ARRAY && token->type != LWJSON_TYPE_OBJECT)) {
return NULL;
}
return prv_find(token, path);
}
19 changes: 11 additions & 8 deletions lwjson/src/lwjson/lwjson_debug.c
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
* This file is part of LwJSON - Lightweight JSON format parser.
*
* Author: Tilen MAJERLE <tilen@majerle.eu>
* Version: v1.1.0
* Version: v1.2.0
*/
#include <string.h>
#include <stdio.h>
Expand All @@ -51,11 +51,14 @@ static void
prv_print_token(lwjson_token_print_t* p, const lwjson_token_t* token) {
#define print_indent() printf("%.*s", (int)((p->indent)), "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t");

if (token == NULL) {
return;
}

/* Check if token has a name */
print_indent();
if (token->token_name != NULL) {
print_indent(); printf("\"%.*s\":", (int)token->token_name_len, token->token_name);
} else {
print_indent();
printf("\"%.*s\":", (int)token->token_name_len, token->token_name);
}

/* Print different types */
Expand All @@ -66,7 +69,7 @@ prv_print_token(lwjson_token_print_t* p, const lwjson_token_t* token) {
if (token->u.first_child != NULL) {
printf("\n");
++p->indent;
for (lwjson_token_t* t = token->u.first_child; t != NULL; t = t->next) {
for (const lwjson_token_t* t = lwjson_get_first_child(token); t != NULL; t = t->next) {
prv_print_token(p, t);
}
--p->indent;
Expand All @@ -76,15 +79,15 @@ prv_print_token(lwjson_token_print_t* p, const lwjson_token_t* token) {
break;
}
case LWJSON_TYPE_STRING: {
printf("\"%.*s\"", (int)token->u.str.token_value_len, token->u.str.token_value);
printf("\"%.*s\"", (int)lwjson_get_val_string_length(token), lwjson_get_val_string(token, NULL));
break;
}
case LWJSON_TYPE_NUM_INT: {
printf("%lld", (long long)token->u.num_int);
printf("%lld", (long long)lwjson_get_val_int(token));
break;
}
case LWJSON_TYPE_NUM_REAL: {
printf("%f", (float)token->u.num_real);
printf("%f", (double)lwjson_get_val_real(token));
break;
}
case LWJSON_TYPE_TRUE: {
Expand Down

0 comments on commit 40dc4de

Please sign in to comment.