LwJSON v1.6.0 documentation
Welcome to the documentation for version v1.6.0.
LwJSON is a generic JSON parser library optimized for embedded systems.
Download library Getting started Open Github Donate
Features
Written in ANSI C99, compatible with
size_t
for size data typesRFC 4627 and RFC 8259 compliant
Based on static token allocation with optional application dynamic pre-allocation
No recursion during parse operation
Re-entrant functions
Zero-copy, no
malloc
orfree
functions usedSupports streaming parsing as secondary option
Optional support for inline comments with /* comment… */ syntax between any blank region of input string
Advanced find algorithm for tokens
Tests coverage is available
User friendly MIT license
Requirements
C compiler
Few kB of ROM memory
Contribute
Fresh contributions are always welcome. Simple instructions to proceed:
Fork Github repository
Respect C style & coding rules used by the library
Create a pull request to
develop
branch with new features or bug fixes
Alternatively you may:
Report a bug
Ask for a feature request
Example code
1#include <stdio.h>
2#include "lwjson/lwjson.h"
3
4/* LwJSON instance and tokens */
5static lwjson_token_t tokens[128];
6static lwjson_t lwjson;
7
8/* Parse JSON */
9void
10example_minimal_run(void) {
11 lwjson_init(&lwjson, tokens, LWJSON_ARRAYSIZE(tokens));
12 if (lwjson_parse(&lwjson, "{\"mykey\":\"myvalue\"}") == lwjsonOK) {
13 const lwjson_token_t* t;
14 printf("JSON parsed..\r\n");
15
16 /* Find custom key in JSON */
17 if ((t = lwjson_find(&lwjson, "mykey")) != NULL) {
18 printf("Key found with data type: %d\r\n", (int)t->type);
19 }
20
21 /* Call this when not used anymore */
22 lwjson_free(&lwjson);
23 }
24}
License
MIT License
Copyright (c) 2022 Tilen MAJERLE
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
Table of contents
Getting started
Getting started may be the most challenging part of every new library. This guide is describing how to start with the library quickly and effectively
Download library
Library is primarly hosted on Github.
You can get it by:
Downloading latest release from releases area on Github
Cloning
main
branch for latest stable versionCloning
develop
branch for latest development
Download from releases
All releases are available on Github releases area.
Clone from Github
First-time clone
This is used when you do not have yet local copy on your machine.
Make sure
git
is installed.Open console and navigate to path in the system to clone repository to. Use command
cd your_path
Clone repository with one of available options below
Run
git clone --recurse-submodules https://github.com/MaJerle/lwjson
command to clone entire repository, including submodulesRun
git clone --recurse-submodules --branch develop https://github.com/MaJerle/lwjson
to clone development branch, including submodulesRun
git clone --recurse-submodules --branch main https://github.com/MaJerle/lwjson
to clone latest stable branch, including submodules
Navigate to
examples
directory and run favourite example
Update cloned to latest version
Open console and navigate to path in the system where your repository is located. Use command
cd your_path
Run
git pull origin main
command to get latest changes onmain
branchRun
git pull origin develop
command to get latest changes ondevelop
branchRun
git submodule update --init --remote
to update submodules to latest version
Note
This is preferred option to use when you want to evaluate library and run prepared examples. Repository consists of multiple submodules which can be automatically downloaded when cloning and pulling changes from root repository.
Add library to project
At this point it is assumed that you have successfully download library, either cloned it or from releases page. Next step is to add the library to the project, by means of source files to compiler inputs and header files in search path
Copy
lwjson
folder to your project, it contains library filesAdd
lwjson/src/include
folder to include path of your toolchain. This is where C/C++ compiler can find the files during compilation process. Usually using-I
flagAdd source files from
lwjson/src/
folder to toolchain build. These files are built by C/C++ compilerCopy
lwjson/src/include/lwjson/lwjson_opts_template.h
to project folder and rename it tolwjson_opts.h
Build the project
Configuration file
Configuration file is used to overwrite default settings defined for the essential use case.
Library comes with template config file, which can be modified according to needs.
and it should be copied (or simply renamed in-place) and named lwjson_opts.h
Note
Default configuration template file location: lwjson/src/include/lwjson/lwjson_opts_template.h
.
File must be renamed to lwjson_opts.h
first and then copied to the project directory where compiler
include paths have access to it by using #include "lwjson_opts.h"
.
List of configuration options are available in the Configuration section. If any option is about to be modified, it should be done in configuration file
1/**
2 * \file lwjson_opts_template.h
3 * \brief Template config file
4 */
5
6/*
7 * Copyright (c) 2022 Tilen MAJERLE
8 *
9 * Permission is hereby granted, free of charge, to any person
10 * obtaining a copy of this software and associated documentation
11 * files (the "Software"), to deal in the Software without restriction,
12 * including without limitation the rights to use, copy, modify, merge,
13 * publish, distribute, sublicense, and/or sell copies of the Software,
14 * and to permit persons to whom the Software is furnished to do so,
15 * subject to the following conditions:
16 *
17 * The above copyright notice and this permission notice shall be
18 * included in all copies or substantial portions of the Software.
19 *
20 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
22 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
23 * AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
24 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
25 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
26 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
27 * OTHER DEALINGS IN THE SOFTWARE.
28 *
29 * This file is part of LwJSON - Lightweight JSON format parser.
30 *
31 * Author: Tilen MAJERLE <tilen@majerle.eu>
32 * Version: v1.6.0
33 */
34#ifndef LWJSON_HDR_OPTS_H
35#define LWJSON_HDR_OPTS_H
36
37/* Rename this file to "lwjson_opts.h" for your application */
38
39/*
40 * Open "include/lwjson/lwjson_opt.h" and
41 * copy & replace here settings you want to change values
42 */
43
44#endif /* LWJSON_HDR_OPTS_H */
Note
If you prefer to avoid using configuration file, application must define
a global symbol LWJSON_IGNORE_USER_OPTS
, visible across entire application.
This can be achieved with -D
compiler option.
Minimal example code
To verify proper library setup, minimal example has been prepared. Run it in your main application file to verify its proper execution
1#include <stdio.h>
2#include "lwjson/lwjson.h"
3
4/* LwJSON instance and tokens */
5static lwjson_token_t tokens[128];
6static lwjson_t lwjson;
7
8/* Parse JSON */
9void
10example_minimal_run(void) {
11 lwjson_init(&lwjson, tokens, LWJSON_ARRAYSIZE(tokens));
12 if (lwjson_parse(&lwjson, "{\"mykey\":\"myvalue\"}") == lwjsonOK) {
13 const lwjson_token_t* t;
14 printf("JSON parsed..\r\n");
15
16 /* Find custom key in JSON */
17 if ((t = lwjson_find(&lwjson, "mykey")) != NULL) {
18 printf("Key found with data type: %d\r\n", (int)t->type);
19 }
20
21 /* Call this when not used anymore */
22 lwjson_free(&lwjson);
23 }
24}
User manual
How it works
LwJSON fully complies with RFC 4627 memo and supports 2
types of parsing:
Parsing with full data available as single linear memory (primary option)
Stream parsing with partial available bytes at any given point of time - advanced state machine
When full data are available, standard parsing is used with tokens, that contain references to start/stop indexes of the strings and other primitives and provide full device tree - sort of custom hash-map value.
When JSON is successfully parsed, there are several tokens used, one for each JSON data type. Each token consists of:
Token type
Token parameter name (key) and its length
Token value or pointer to first child (in case of object or array types)
As an example, JSON text {"mykey":"myvalue"}
will be parsed into 2
tokens:
First token is the opening bracket and has type object as it holds children tokens
Second token has name
mykey
, its type is string with value set asmyvalue
Warning
When JSON input string is parsed, create tokens use input string as a reference. This means that until JSON parsed tokens are being used, original text must stay as-is. Any modification of source JSON input may destroy references from the token tree and hence generate wrong output for the user
Tip
See Stream parser for implementation of streaming parser where full data do not need to be available at any given time.
Token design
Every element of LwJSON is a token. There are different set of token types:
Object: Type that has nested key-value pairs, eg
{"key":{"sub-key":"value"}}
Array: Type that holds nested values, eg
{"key":[1,2,3,4,5]}
String: Regular string, quoted sequence of characters, eg
{"key":"my_string"}
Number: Integer or real number, eg
{"intnum":123,"realnum":4.3}
Boolean true: Boolean type true, eg
{"key":true}
Boolean false: Boolean type false, eg
{"key":false}
Null: Null indicator, eg
{"key":null}
When parsed, input string is not copied to token, every token uses input string as a reference and points to the beginning of strings/values. This is valid for all string data types and for parameter names.
Note
Input string is not modified therefore all strings contain additional parameter with string length.
Access to data
Once application successfully parses input JSON string, LwJSON creates set of tokens in hierarchical order with tree for children tokens.
To simplify data extraction and to quickly find/access-to given object and token, LwJSON implements simple find algorithm based on path formatting.
Traverse object
Valid JSON input starts with object ({
) or array ([
). Anything else is invalid JSON object.
When lwjson_parse()
successfully processes input data, application may access JSON tokens
with simple loop. Every token is part of linked list and has tree organization for children objects.
Note
Children objects are only available for object and array types
To traverse through all elements, application must first get top object. It can then loop through all in linked list until it reaches zero.
If the token type is object or array, application must check children nodes for more token data.
1#include <stdio.h>
2#include "lwjson/lwjson.h"
3
4/* LwJSON instance and tokens */
5static lwjson_token_t tokens[128];
6static lwjson_t lwjson;
7
8/* Parse JSON */
9void
10example_traverse_run(void) {
11 /* Initialize and pass statically allocated tokens */
12 lwjson_init(&lwjson, tokens, LWJSON_ARRAYSIZE(tokens));
13
14 /* Try to parse input string */
15 if (lwjson_parse(&lwjson, "{\"mykey\":\"myvalue\",\"num\":1,\"obj\":{},\"arr\":[1,2,3,4]}") == lwjsonOK) {
16 lwjson_token_t* t;
17 printf("JSON parsed..\r\n");
18
19 /* Get very first token as top object */
20 t = lwjson_get_first_token(&lwjson);
21 if (t->type == LWJSON_TYPE_ARRAY) {
22 printf("JSON starts with array..\r\n");
23 } else if (t->type == LWJSON_TYPE_OBJECT) {
24 printf("JSON starts with object..\r\n");
25 } else {
26 printf("This should never happen..\r\n");
27 }
28
29 /* Now print all keys in the object */
30 for (const lwjson_token_t* tkn = lwjson_get_first_child(t); tkn != NULL; tkn = tkn->next) {
31 printf("Token: %.*s", (int)tkn->token_name_len, tkn->token_name);
32 if (tkn->type == LWJSON_TYPE_ARRAY || tkn->type == LWJSON_TYPE_OBJECT) {
33 printf(": Token is array or object...check children tokens if any, in recursive mode..");
34 /* Get first child of token */
35 //lwjson_get_first_child(tkn);
36 }
37 printf("\n");
38 }
39
40 /* Call this when not used anymore */
41 lwjson_free(&lwjson);
42 }
43}
Tip
Check lwjson_print_json()
to print data on stream output
Find token in JSON tree
Instead of manually traversing through all tokens, LwJSON implements simple search algorithm to quickly get token from application standpoint.
Let’s consider following JSON as input:
{
"name":"John",
"born": {
"city": "Munich",
"year": 1993
},
"cars":[
{
"brand":"Porsche",
"year":2018
},
{
"brand":"Range",
"year":2020,
"repainted":true
}
]
}
There is one John, born in Munich in 1993
and has 2
cars, Porsche and Range.
name
is string with valueJohn
born
is object with2
fieldscars
is array of2
objectsobject 1
brand
is set to Porscheyear
is set to2018
object 2
brand
is set to Rangeyear
is set to2020
repainted
is set totrue
as this car was recently repainted
To find the person’s name, application must first name
key and print its value.
This can be done by scanning entire object and check which token matches name
keyword.
LwJSON implements find functionality to find the token in simple way.
This is done by providing full path to token in JSON tree, separated by dot .
character.
To find person name, application would then simply call lwjson_find()
and pass name
as path parameter.
If token exists, function will return handle of the token where application can print its value.
If application is interested in city of birth, it will set path as born.city
and search
algorithm will:
First search for
born
token and check if it is objectIt will enter the object and search for
city
token and return it on matchIt will return
NULL
of object is not found
Tip
Application shall use lwjson_find()
to get the token based on input path.
When JSON contains arrays (these do not have keys), special character #
may be used,
indicating any element in array to be checked until first match is found.
cars.#.brand
will return first token matching path, the one with string valuePorsche
in first objectcars.#.repainted
will return first token matching path, the one with boolean valuetrue
in second object
In first case, brand
keyword exists already in first object, so find function will get the match immediately.
Because in second case, repainted
only exists in second object, function will return value from second object.
Access array index
It is possible to access specific array index by adding decimal number after hash character, in format #[0-9]+
cars.#0.brand
will returnbrand
token from first object in array (index = 0
) with value set to Porschecars.#1.brand
will returnbrand
token from second object in array (index = 1
) with value set to Range
To retrieve full object of the array, application may only apply #[0.9]+
in search pattern.
cars.#0
will return first object token in arraycars.#1
will return second object token in arraycars.#
will return error as there is no valid index. Usecars
to retrieve full array
Warning
Passing path in format path.to.cars.#
(hashtag as last element without index number) will always return NULL
as this is considered invalid path. To retrieve full array, pass path to array path.to.cars
only, without trailling #
.
Stream parser
Streaming parser implementation is alternative option versus standard tokenized one, in the sense that:
There is no need to have full JSON available at one time to have successful parsing
It can be utilized to parse very large JSON strings on very small systems with limited memory
It allows users to take from the stream only necessary parts and store them to local more system-friendly variable
This type of parser does not utilize use of tokens, rather focuses on the callback function, where user is in charge to manually understand token structure and get useful data from it.
Stream parser introduces stack mechanism instead - to keep the track of depthness during parsing the process.
3
different element types are stored on local stack:
Start of object, with
{
characterStart of array, with
[
characterKey from the object entry
Note
Stack is nested as long as JSON input stream is nested in the same way
Consider this input string: {"k1":"v1","k2":[true, false]}
.
During parsing procedure, at some point of time, these events will occur:
Start of object detected - object pushed to stack
key element with name
k1
detected and pushed to stackstring
v1
parsed as string-value
key element with name
k1
popped from stackkey element with name
k2
detected and pushed to stackStart of array detected - array pushed to stack
true
primitive detectedfalse
primitive detected
End of array detected - array popped from stack
key element with name
k2
popped from stack
End of object detected - object popped from stack
Each of these events is reported to user in the callback function.
An example of the stream parsing:
1#include <stdio.h>
2#include "lwjson/lwjson.h"
3
4/* Test string to parser */
5static const char* json_str = "{\"k1\":\"v1\",\"k2\":[true, false]}";
6
7/* LwJSON stream parser */
8static lwjson_stream_parser_t stream_parser;
9
10/**
11 * \brief Callback function for various events
12 * \param jsp: JSON stream parser object
13 * \param type: Event type
14 */
15void
16prv_example_callback_func(lwjson_stream_parser_t* jsp, lwjson_stream_type_t type) {
17 /* Get a value corresponsing to "k1" key */
18 if (jsp->stack_pos >= 2 /* Number of stack entries must be high */
19 && jsp->stack[0].type == LWJSON_STREAM_TYPE_OBJECT /* First must be object */
20 && jsp->stack[1].type == LWJSON_STREAM_TYPE_KEY /* We need key to be before */
21 && strcmp(jsp->stack[1].meta.name, "k1") == 0) {
22 printf("Got key '%s' with value '%s'\r\n", jsp->stack[1].meta.name, jsp->data.str.buff);
23 }
24 (void)type;
25}
26
27/* Parse JSON */
28void
29example_stream_run(void) {
30 lwjsonr_t res;
31 printf("\r\n\r\nParsing stream\r\n");
32 lwjson_stream_init(&stream_parser, prv_example_callback_func);
33
34 /* Demonstrate as stream inputs */
35 for (const char* c = json_str; *c != '\0'; ++c) {
36 if ((res = lwjson_stream_parse(&stream_parser, *c)) == lwjsonOK) {
37 printf("OK\r\n");
38 } else if (res == lwjsonSTREAMDONE) {
39 printf("Done\r\n");
40 } else {
41 printf("Error\r\n");
42 break;
43 }
44 }
45 printf("Parsing completed\r\n");
46}
API reference
List of all the modules:
LwJSON
- group LWJSON
LwJSON - Lightweight JSON format parser.
Defines
-
LWJSON_ARRAYSIZE(x)
Get size of statically allocated array.
- Parameters
x – [in] Object to get array size of
- Returns
Number of elements in array
-
lwjson_get_tokens_used(lw)
Get number of tokens used to parse JSON.
- Parameters
lw – [in] Pointer to LwJSON instance
- Returns
Number of tokens used to parse JSON
-
lwjson_get_first_token(lw)
Get very first token of LwJSON instance.
- Parameters
lw – [in] Pointer to LwJSON instance
- Returns
Pointer to first token
-
lwjson_get_val_int(token)
Get token value for LWJSON_TYPE_NUM_INT type.
- Parameters
token – [in] token with integer type
- Returns
Int number if type is integer,
0
otherwise
-
lwjson_get_val_real(token)
Get token value for LWJSON_TYPE_NUM_REAL type.
- Parameters
token – [in] token with real type
- Returns
Real numbeer if type is real,
0
otherwise
-
lwjson_get_first_child(token)
Get first child token for LWJSON_TYPE_OBJECT or LWJSON_TYPE_ARRAY types.
- Parameters
token – [in] token with integer type
- Returns
Pointer to first child or
NULL
if parent token is not object or array
-
lwjson_get_val_string_length(token)
Get length of string for LWJSON_TYPE_STRING token type.
- Parameters
token – [in] token with string type
- Returns
Length of string in units of bytes
Typedefs
-
typedef LWJSON_CFG_REAL_TYPE lwjson_real_t
Real data type.
-
typedef LWJSON_CFG_INT_TYPE lwjson_int_t
Integer data type.
-
typedef void (*lwjson_stream_parser_callback_fn)(struct lwjson_stream_parser *jsp, lwjson_stream_type_t type)
Callback function for various events.
Enums
-
enum lwjson_type_t
List of supported JSON types.
Values:
-
enumerator LWJSON_TYPE_STRING
String/Text format. Everything that has beginning and ending quote character
-
enumerator LWJSON_TYPE_NUM_INT
Number type for integer
-
enumerator LWJSON_TYPE_NUM_REAL
Number type for real number
-
enumerator LWJSON_TYPE_OBJECT
Object data type
-
enumerator LWJSON_TYPE_ARRAY
Array data type
-
enumerator LWJSON_TYPE_TRUE
True boolean value
-
enumerator LWJSON_TYPE_FALSE
False boolean value
-
enumerator LWJSON_TYPE_NULL
Null value
-
enumerator LWJSON_TYPE_STRING
-
enum lwjsonr_t
JSON result enumeration.
Values:
-
enumerator lwjsonOK = 0x00
Function returns successfully
-
enumerator lwjsonERR
Generic error message
-
enumerator lwjsonERRJSON
Error JSON format
-
enumerator lwjsonERRMEM
Memory error
-
enumerator lwjsonERRPAR
Parameter error
-
enumerator lwjsonSTREAMWAITFIRSTCHAR
Streaming parser did not yet receive first valid character indicating start of JSON sequence
-
enumerator lwjsonSTREAMDONE
Streaming parser is done, closing character matched the stream opening one
-
enumerator lwjsonSTREAMINPROG
Stream parsing is still in progress
-
enumerator lwjsonOK = 0x00
-
enum lwjson_stream_type_t
Object type for streaming parser.
Values:
-
enumerator LWJSON_STREAM_TYPE_NONE
No entry - not used
-
enumerator LWJSON_STREAM_TYPE_OBJECT
Object indication
-
enumerator LWJSON_STREAM_TYPE_OBJECT_END
Object end indication
-
enumerator LWJSON_STREAM_TYPE_ARRAY
Array indication
-
enumerator LWJSON_STREAM_TYPE_ARRAY_END
Array end indication
-
enumerator LWJSON_STREAM_TYPE_KEY
Key string
-
enumerator LWJSON_STREAM_TYPE_STRING
Strin type
-
enumerator LWJSON_STREAM_TYPE_TRUE
True primitive
-
enumerator LWJSON_STREAM_TYPE_FALSE
False primitive
-
enumerator LWJSON_STREAM_TYPE_NULL
Null primitive
-
enumerator LWJSON_STREAM_TYPE_NUMBER
Generic number
-
enumerator LWJSON_STREAM_TYPE_NONE
-
enum lwjson_stream_state_t
Values:
-
enumerator LWJSON_STREAM_STATE_WAITINGFIRSTCHAR = 0x00
State to wait for very first opening character
-
enumerator LWJSON_STREAM_STATE_PARSING
In parsing of the first char state - detecting next character state
-
enumerator LWJSON_STREAM_STATE_PARSING_STRING
Parse string primitive
-
enumerator LWJSON_STREAM_STATE_PARSING_PRIMITIVE
Parse any primitive that is non-string, either “true”, “false”, “null” or a number
-
enumerator LWJSON_STREAM_STATE_WAITINGFIRSTCHAR = 0x00
Functions
-
lwjsonr_t lwjson_init(lwjson_t *lw, lwjson_token_t *tokens, size_t tokens_len)
Setup LwJSON instance for parsing JSON strings.
-
lwjsonr_t lwjson_parse_ex(lwjson_t *lw, const void *json_data, size_t len)
Parse JSON data with length parameter JSON format must be complete and must comply with RFC4627.
-
lwjsonr_t lwjson_parse(lwjson_t *lw, const char *json_str)
Parse input JSON format JSON format must be complete and must comply with RFC4627.
-
const lwjson_token_t *lwjson_find(lwjson_t *lw, const char *path)
Find first match in the given path for JSON entry JSON must be valid and parsed with lwjson_parse function.
- Parameters
lw – [in] JSON instance with parsed JSON string
path – [in] Path with dot-separated entries to search for the JSON key to return
- Returns
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)
Find first match in the given path for JSON path JSON must be valid and parsed with lwjson_parse function.
- Parameters
lw – [in] JSON instance with parsed JSON string
token – [in] Root token to start search at. Token must be type LWJSON_TYPE_OBJECT or LWJSON_TYPE_ARRAY. Set to
NULL
to use root token of LwJSON objectpath – [in] path with dot-separated entries to search for JSON key
- Returns
Pointer to found token on success,
NULL
if token cannot be found
-
lwjsonr_t lwjson_free(lwjson_t *lw)
Free token instances (specially used in case of dynamic memory allocation)
-
void lwjson_print_token(const lwjson_token_t *token)
Prints and outputs token data to the stream output.
Note
This function is not re-entrant
- Parameters
token – [in] Token to print
-
void lwjson_print_json(const lwjson_t *lw)
Prints and outputs full parsed LwJSON instance.
Note
This function is not re-entrant
- Parameters
lw – [in] LwJSON instance to print
-
lwjsonr_t lwjson_stream_init(lwjson_stream_parser_t *jsp, lwjson_stream_parser_callback_fn evt_fn)
Initialize LwJSON stream object before parsing takes place.
-
lwjsonr_t lwjson_stream_reset(lwjson_stream_parser_t *jsp)
Reset LwJSON stream structure.
-
lwjsonr_t lwjson_stream_parse(lwjson_stream_parser_t *jsp, char c)
Parse JSON string in streaming mode.
- Parameters
jsp – [inout] Stream JSON structure
c – [in] Character to parse
- Returns
lwjsonOK if parsing is in progress and no hard error detected lwjsonSTREAMDONE when valid JSON was detected and stack level reached back
0
level
-
static inline const char *lwjson_get_val_string(const lwjson_token_t *token, size_t *str_len)
Get string value from JSON token.
- Parameters
token – [in] Token with string type
str_len – [out] Pointer to variable holding length of string. Set to
NULL
if not used
- Returns
Pointer to string or
NULL
if invalid token type
-
static inline uint8_t lwjson_string_compare(const lwjson_token_t *token, const char *str)
Compare string token with user input string for a case-sensitive match.
- Parameters
token – [in] Token with string type
str – [in] NULL-terminated string to compare
- Returns
1
if equal,0
otherwise
-
static inline uint8_t lwjson_string_compare_n(const lwjson_token_t *token, const char *str, size_t len)
Compare string token with user input string for a case-sensitive match.
- Parameters
token – [in] Token with string type
str – [in] NULL-terminated string to compare
len – [in] Length of the string in bytes
- Returns
1
if equal,0
otherwise
-
struct lwjson_token_t
- #include <lwjson.h>
JSON token.
Public Members
-
struct lwjson_token *next
Next token on a list
-
lwjson_type_t type
Token type
-
const char *token_name
Token name (if exists)
-
size_t token_name_len
Length of token name (this is needed to support const input strings to parse)
-
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)
-
struct lwjson_token_t::[anonymous]::[anonymous] 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 for object or array type
-
union lwjson_token_t::[anonymous] u
Union with different data types
-
struct lwjson_token *next
-
struct lwjson_t
- #include <lwjson.h>
LwJSON instance.
Public Members
-
lwjson_token_t *tokens
Pointer to array of tokens
-
size_t tokens_len
Size of all tokens
-
size_t next_free_token_pos
Position of next free token instance
-
lwjson_token_t first_token
First token on a list
-
uint8_t parsed
Flag indicating JSON parsing has finished successfully
-
lwjson_token_t *tokens
-
struct lwjson_stream_stack_t
- #include <lwjson.h>
Stream parsing stack object.
Public Members
-
lwjson_stream_type_t type
Streaming type - current value
-
char name[LWJSON_CFG_STREAM_KEY_MAX_LEN + 1]
Last known key name, used only for LWJSON_STREAM_TYPE_KEY type
-
uint16_t index
Current index when type is an array
-
union lwjson_stream_stack_t::[anonymous] meta
Meta information
-
lwjson_stream_type_t type
-
struct lwjson_stream_parser_t
- #include <lwjson.h>
LwJSON streaming structure.
Public Members
-
lwjson_stream_stack_t stack[LWJSON_CFG_STREAM_STACK_SIZE]
Stack used for parsing. TODO: Add conditional compilation flag
-
size_t stack_pos
Current stack position
-
lwjson_stream_state_t parse_state
Parser state
-
lwjson_stream_parser_callback_fn evt_fn
Event function for user
-
char buff[LWJSON_CFG_STREAM_STRING_MAX_LEN + 1]
Buffer to write temporary data. TODO: Size to be variable with define
Temporary write buffer
-
size_t buff_pos
Buffer position for next write (length of bytes in buffer)
Buffer position for next write
-
size_t buff_total_pos
Total buffer position used up to now (in several data chunks)
-
uint8_t is_last
Status indicates if this is the last part of the string
-
struct lwjson_stream_parser_t::[anonymous]::[anonymous] str
String structure. It is only used for keys and string objects. Use primitive part for all other options
-
struct lwjson_stream_parser_t::[anonymous]::[anonymous] prim
Primitive object. Used for all types, except key or string
-
union lwjson_stream_parser_t::[anonymous] data
Data union used to parse various
-
char prev_c
History of characters
-
lwjson_stream_stack_t stack[LWJSON_CFG_STREAM_STACK_SIZE]
-
LWJSON_ARRAYSIZE(x)
Configuration
This is the default configuration of the middleware.
When any of the settings shall be modified, it shall be done in dedicated application config lwjson_opts.h
file.
Note
Check Getting started for guidelines on how to create and use configuration file.
- group LWJSON_OPT
LwJSON options.
Defines
-
LWJSON_CFG_REAL_TYPE
Real data type used to parse numbers with floating point number.
This is used for numbers in LWJSON_TYPE_NUM_REAL token data type.
Note
Data type must be signed, normally
float
ordouble
-
LWJSON_CFG_INT_TYPE
Integer type used to parse numbers.
This is used for numbers in LWJSON_TYPE_NUM_INT token data type.
Note
Data type must be signed integer
-
LWJSON_CFG_COMMENTS
Enables
1
or disables0
support for inline comments.Default set to
0
to be JSON compliant
JSON streaming confiuration.
Defines
-
LWJSON_CFG_STREAM_KEY_MAX_LEN
Max length of token key (object key name) to be available for stack storage.
-
LWJSON_CFG_STREAM_STACK_SIZE
Max stack size (depth) in units of lwjson_stream_stack_t structure.
-
LWJSON_CFG_STREAM_STRING_MAX_LEN
Max size of string for single parsing in units of bytes.
-
LWJSON_CFG_STREAM_PRIMITIVE_MAX_LEN
Max number of bytes used to parse primitive.
Primitives are all numbers and logical values (null, true, false)
-
LWJSON_CFG_REAL_TYPE
Changelog
# Changelog
## Develop
## 1.6.0
- Split CMakeLists.txt files between library and executable
- Change license year to 2022
- Fix GCC warning for incompatible comparison types
- Update code style with astyle
- Add support for stream parsing - first version
- Add `.clang-format`
- Add `lwjsonSTREAMDONE` return code when streamer well parsed some JSON and reached end of string
- Add option to reset stream state machine
## 1.5.0
- Add string compare feature
- Add string compare with custom length feature
## 1.4.0
- Add support with input string with length specifier
- Add VSCode project for Win32 compilation
## 1.3.0
- Added support for inline `/* */` comments
## v1.2.0
- Added `lwjson_find_ex` function to accept token pointer as starting reference
- Update of the docs for *find*
- Remove unused reset and add free function for future dynamic allocation support
## v1.1.0
- Improved find algorithm to match array index
- Added more test code
## v1.0.2
- Fix wrong parsing of hex in some corner cases
- Add more robust code to handle errorneous JSON input
## v1.0.1
- Added test code
- Fixed bug with improper string parsing
## v1.0.0
- First stable release
- Compliant with RFC 4627 for JSON
- Full features JSON parser