JSON
Header file
#include "mln_json.h"
Module
json
Functions/Macros
mln_json_init
mln_json_init(j)
Description: Initialize JSON type node j
, the node type is NONE
.
Return value: None
mln_json_string_init
mln_json_string_init(j, s)
Description: Initialize JSON type node j
to string type and assign value s
of type mln_string_t *
. s
will be taken over by the JSON structure. The caller needs to ensure the memory life cycle of s
and cannot modify the content of s
.
Return value: None
mln_json_number_init
mln_json_number_init(j, n)
Description: Initialize the JSON type node j
to a numeric type and assign a value n
of type double
.
Return value: None
mln_json_true_init
mln_json_true_init(j)
Description: Initialize JSON type node j
to type true
.
Return value: None
mln_json_false_init
mln_json_false_init(j)
Description: Initialize the JSON type node j
to the false
type.
Return value: None
mln_json_null_init
mln_json_null_init(j)
Description: Initialize JSON type node j
to null
type.
Return value: None
mln_json_obj_init
int mln_json_obj_init(mln_json_t *j);
Description: Initialize JSON type node j
to object type.
Return value:
0
- on success-1
- on failure
mln_json_array_init
int mln_json_array_init(mln_json_t *j);
Description: Initialize JSON type node j
to array type.
Return value:
0
- on success-1
- on failure
mln_json_decode
int mln_json_decode(mln_string_t *jstr, mln_json_t *out, mln_json_policy_t *policy);
Description: Parse the JSON string jstr
into a data structure, and the result will be put into the parameter out
. The policy is a security policy structure initialized by mln_json_policy_init.
Return value:
0
- on success-1
- on failure. If policy is not NULL, you need to use mln_json_policy_error to check which specific security constraint has been violated.
mln_json_destroy
void mln_json_destroy(mln_json_t *j;
Description: Release the j
node memory of type mln_json_t
.
Return value: None
mln_json_dump
void mln_json_dump(mln_json_t *j, int n_space, char *prefix);
Description: Output the details of json node j
to standard output. n_space
represents the current number of indented spaces, and prefix
is the prefix of the output content.
Return value: None
mln_json_encode
mln_string_t *mln_json_encode(mln_json_t *j);
Description: Generate a JSON string from the mln_json_t
node structure. The return value needs to be released by calling mln_string_free
after use.
Return value: mln_string_t
string pointer is returned successfully, otherwise NULL
is returned
mln_json_obj_search
mln_json_t *mln_json_obj_search(mln_json_t *j, mln_string_t *key);
Description: Search the value content with key key
from object type node j
.
Return value: If successful, return a value of type mln_json_t
, otherwise return NULL
mln_json_array_search
mln_json_t *mln_json_array_search(mln_json_t *j, mln_uauto_t index);
Description: Search the element content with subscript index
from array type node j
.
Return value: If successful, an element node of type mln_json_t
is returned, otherwise NULL
is returned.
mln_json_array_length
mln_uauto_t mln_json_array_length(mln_json_t *j);
Description: Get the length of the array. At this time j
must be of array type.
Return value: array length
mln_json_obj_update
int mln_json_obj_update(mln_json_t *j, mln_json_t *key, mln_json_t *val);
Description: Add the key
and val
pairs to the j
JSON node. At this time, j
needs to be an object type. If key
already exists, the original key
and value
will be replaced by the new parameters. Therefore the parameters key
and val
will be taken over by j
after the call.
Return value: Returns 0
on success, otherwise returns -1
mln_json_array_append
int mln_json_array_append(mln_json_t *j, mln_json_t *value);
Description: Add value
to the JSON structure j
of array type.
Return value: Returns 0
on success, otherwise returns -1
mln_json_array_update
int mln_json_array_update(mln_json_t *j, mln_json_t *value, mln_uauto_t index);
Description: Update value
to the position where the index is index
of the array type JSON structure j
. If the subscript does not exist, it will fail.
Return value: Returns 0
on success, otherwise returns -1
mln_json_reset
void mln_json_reset(mln_json_t *j);
Description: Reset the JSON node j
data structure and release its original data.
Return value: None
mln_json_obj_remove
void mln_json_obj_remove(mln_json_t *j, mln_string_t *key);
Description: Delete and release the key-value pair with key value key
from the JSON structure j
of the object type.
Return value: If it exists, return the JSON node corresponding to the value part, otherwise return NULL
mln_json_array_remove
void mln_json_array_remove(mln_json_t *j, mln_uauto_t index);
Description: Delete and release the element with index index
from the array type JSON node.
Return value: Returns the element pointer if it exists, otherwise returns NULL
is_type
mln_json_is_object(json)
mln_json_is_array(json)
mln_json_is_string(json)
mln_json_is_number(json)
mln_json_is_true(json)
mln_json_is_false(json)
mln_json_is_null(json)
mln_json_is_none(json)
Description: Determine the json
type of the mln_json_t
structure, which are: object, array, string, number, Boolean true, Boolean false, NULL, and no type.
Return value: Returns non-0
if the conditions are met, otherwise returns 0
set_type
mln_json_none_type_set(json)
mln_json_object_type_set(json)
mln_json_array_type_set(json)
mln_json_string_type_set(json)
mln_json_number_type_set(json)
mln_json_true_type_set(json)
mln_json_false_type_set(json)
mln_json_null_type_set(json)
Description: Set the type for the json
node of type mln_json_t
, in order: no type, object, array, string, number, Boolean true, Boolean false, NULL.
Return value: None
get_data
mln_json_object_data_get(json)
mln_json_array_data_get(json)
mln_json_string_data_get(json)
mln_json_number_data_get(json)
mln_json_true_data_get(json)
mln_json_false_data_get(json)
mln_json_null_data_get(json)
Description: Get the data part of the corresponding type in the json
node of type mln_json_t
. The types are: object, array, string, number, Boolean true, Boolean false, and NULL.
Return value:
- The object type is
mln_hash_t
type pointer - The array type is
mln_rbtree_t
type pointer - The string type is
mln_string_t
type pointer - The number type is a
double
type value - Boolean true for
mln_u8_t
type value - Boolean false for
mln_u8_t
type value - NULL type is a NULL value of type
mln_u8ptr_t
mln_json_policy_init
mln_json_policy_init(policy, _depth, _keylen, _strlen, _elemnum, _kvnum);
Description: Initialize the policy
of type mln_json_policy_t
. The meanings of the remaining parameters are as follows:
_depth
The maximum nesting depth of the JSON. During parsing, the nesting depth increases when encountering an array or object, and decreases when the array or object is fully parsed._keylen
The maximum length of keys in objects._strlen
The maximum length of string values._elemnum
The maximum number of elements in an array._kvnum
The maximum number of key-value pairs in an object.
Return Value: None
mln_json_policy_error
mln_json_policy_error(policy)
Description: Get the error code from the policy
of type mln_json_policy_t
. This macro is typically used to check for security policy violations when mln_json_decode
returns -1
.
Return Value: An int type error code with the following values:
M_JSON_OK
No security policy violations.M_JSON_DEPTH
The nesting depth is too deep.M_JSON_KEYLEN
The length of the object key exceeds the limit.M_JSON_STRLEN
The length of the string value exceeds the limit.M_JSON_ARRELEM
The number of elements in the array exceeds the limit.M_JSON_OBJKV
The number of key-value pairs in the object exceeds the limit.
mln_json_parse
int mln_json_parse(mln_json_t *j, mln_string_t *exp, mln_json_iterator_t iterator, void *data)
typedef int (*mln_json_iterator_t)(mln_json_t *, void *);
Description:
From the JSON managed by the j
node, obtain the matching mln_json_t
child node according to exp
. If there is a matching child node, the iterator
callback function will be called for processing. data
is User-defined data is passed in when iterator
is called.
Suppose we have the following JSON:
{
"a": [1, {
"c": 3
}],
"b": 2
}
The content of exp
is as follows:
Content | Meaning |
---|---|
a |
Get the value with key a (each value is saved in the mln_json_t structure) |
b |
Get the value with key b |
a.0 |
Get the key a, and its value should be an array, and then get the 0th subscript element of the array |
a.2.c |
Get the array corresponding to the value with key a , then get the array element with subscript 2 , which should be an object, and finally get the value with key c of the element object. This expression will cause mln_json_parse in this case returns -1 because the array element with index 2 does not exist |
Return value:
0
- on success-1
- on failure
mln_json_generate
int mln_json_generate(mln_json_t *j, char *fmt, ...);
Description:
According to the format given by fmt
, fill the subsequent arguments into j
.
fmt
supports the following format characters:
{}
- Indicates that what is inside the curly brackets is an object type. The key and value of the object are separated by:
, and each group of key-value is separated by,
.[]
- Indicates that what is in the square brackets is an array type, and each array element is separated by,
.j
- Indicates that the variable parameter part is passed in amln_json_t
pointer.d
- Indicates that the variable parameter part is passed in a 32-bit signed value, such asint
ormln_s32_t
.D
- Indicates that the variable parameter part is passed in a 64-bit signed value, such aslong long
ormln_s64_t
.u
- Indicates that the variable parameter part is passed in a 32-bit unsigned value, such asunsigned int
ormln_u32_t
.U
- Indicates that the variable parameter part is passed in a 64-bit unsigned value, such asunsigned long long
ormln_u64_t
.F
- Indicates that the variable parameter part is passed in a value of typedouble
.t
- Indicates that atrue
is filled in at this position. This placeholder does not need to pass in the corresponding variable parameters.f
- Indicates that afalse
is filled in at this position. This placeholder does not need to pass in the corresponding variable parameters.n
- Indicates that anull
is filled in at this position. This placeholder does not need to pass in the corresponding variable parameters.s
- Indicates that the variable parameter part is passed in achar *
type string, such as"Hello"
.S
- Indicates that the variable parameter part is passed in amln_string_t *
type string.- 'c' - Indicates that the variable parameter part is passed in a
struct mln_json_call_attr *
type structure. This structure contains two memberscallback
anddata
. The meaning is: the value at this position is parsed by the functioncallback
with user-defineddata
.
Notes:
- Only the above format symbols can appear in
fmt
, and there cannot be any other types of symbols such as spaces, tabs, or enters. - After successfully executing this function, the variable parameter corresponding to the format symbol
j
cannot be released, i.e.mln_json_destroy
ormln_json_reset
.
For example:
mln_json_generate(&j, "[{s:d,s:d,s:{s:d}},d]", "a", 1, "b", 3, "c", "d", 4, 5);
mln_string_t *res = mln_json_encode(&j);
// The result is: [{"b":3,"c":{"d":4},"a":1},5]
Return value:
0
- on success-1
- on failure
mln_json_object_iterate
int mln_json_object_iterate(mln_json_t *j, mln_json_object_iterator_t it, void *data);
typedef int (*mln_json_object_iterator_t)(mln_json_t * /*key*/, mln_json_t * /*val*/, void *);
Description: Traverse each key
-value
pair in object j
, and use it
to process the key-value pair. data
is user-defined data, which will be processed when it
is called. and passed in.
Return value
0
- on success-1
- on failure
mln_json_array_iterate
mln_json_array_iterate(j, it, data);
typedef int (*mln_json_array_iterator_t)(mln_json_t *, void *);
Description: Traverse each element in the array j
, and use it
to process the array elements. data
is user-defined data, which will be passed in when it
is called.
Return value
0
- Successnon-zero
- Failed or other meaning. Anynon-zero
value returned byit
will interrupt the traversal of the array
Example
Example 1
#include <stdio.h>
#include "mln_string.h"
#include "mln_json.h"
static int callback(mln_json_t *j, void *data)
{
mln_json_number_init(j, *(int *)data);
return 0;
}
static int handler(mln_json_t *j, void *data)
{
mln_json_dump(j, 0, "");
return 0;
}
int main(int argc, char *argv[])
{
mln_json_t j, k;
struct mln_json_call_attr ca;
mln_string_t *res, exp = mln_string("protocols.0");
mln_string_t tmp = mln_string("{\"paths\":[\"/mock\"],\"methods\":null,\"sources\":null,\"destinations\":null,\"name\":\"example_route\",\"headers\":null,\"hosts\":null,\"preserve_host\":false,\"regex_priority\":0,\"snis\":null,\"https_redirect_status_code\":426,\"tags\":null,\"protocols\":[\"http\",\"https\"],\"path_handling\":\"v0\",\"id\":\"52d58293-ae25-4c69-acc8-6dd729718a61\",\"updated_at\":1661345592,\"service\":{\"id\":\"c1e98b2b-6e77-476c-82ca-a5f1fb877e07\"},\"response_buffering\":true,\"strip_path\":true,\"request_buffering\":true,\"created_at\":1661345592}");
if (mln_json_decode(&tmp, &j, NULL) < 0) { //Decode the string and generate the node of mln_json_t
fprintf(stderr, "decode error\n");
return -1;
}
mln_json_parse(&j, &exp, handler, NULL); //Get the first element of the array whose key is protocols in the JSON and hand it to the handler for processing
//Fill in user-defined data parsing structure
ca.callback = callback;
ca.data = &i;
//Generate JSON structure using format characters
mln_json_init(&k);//Uninitialized json variables must be initialized before mln_json_generate
if (mln_json_generate(&k, "[{s:d,s:d,s:{s:d}},d,[],j,c]", "a", 1, "b", 3, "c", "d", 4, 5, &j, &ca) < 0) {
fprintf(stderr, "generate failed\n");
return -1;
}
mln_json_generate(&k, "[s,d]", "g", 99);//These two elements will be added to the k array
res = mln_json_encode(&k); //Generate corresponding JSON string for the generated structure
mln_json_destroy(&k); //Note, do not release j here, because k will release the memory in j
if (res == NULL) {
fprintf(stderr, "encode failed\n");
return -1;
}
write(STDOUT_FILENO, res->data, res->len);
write(STDOUT_FILENO, "\n", 1);
mln_string_free(res);
return 0;
}
The output of this example:
type:string val:[http]
[{"b":3,"c":{"d":4},"a":1},5,[],{"preserve_host":false,"name":"example_route","destinations":null,"methods":null,"tags":null,"hosts":null,"response_buffering":true,"snis":null,"https_redirect_status_code":426,"headers":null,"request_buffering":true,"sources":null,"strip_path":true,"protocols":["http","https"],"path_handling":"v0","created_at":1661345592,"id":"52d58293-ae25-4c69-acc8-6dd729718a61","updated_at":1661345592,"paths":["/mock"],"regex_priority":0,"service":{"id":"c1e98b2b-6e77-476c-82ca-a5f1fb877e07"}},1024,"g",99]
The first line is the output of mln_dump
called in handler
. The second line is the JSON string encoded by mln_json_encode
.
Example 2
#include "mln_json.h"
#include "mln_log.h"
static int obj_iterator(mln_json_t *k, mln_json_t *v, void *data)
{
mln_string_t *s = mln_json_string_data_get(k);
int i = (int)mln_json_number_data_get(v);
mln_log(none, "%S: %d\n", s, i);
return 0;
}
static int array_iterator(mln_json_t *j, void *data)
{
return mln_json_object_iterate(j, obj_iterator, data);
}
static int handler(mln_json_t *j, void *data)
{
return mln_json_array_iterate(j, array_iterator, data);
}
static void parse(mln_string_t *p)
{
mln_json_t j;
mln_json_policy_t policy;
mln_string_t exp = mln_string("resolutions");
mln_json_policy_init(policy, 3, 11, 10, 1, 2);
mln_json_decode(p, &j, &policy);
mln_json_parse(&j, &exp, handler, NULL);
mln_json_destroy(&j);
}
int main(void)
{
mln_string_t p = mln_string("{\"name\":\"Awesome 4K\",\"resolutions\":[{\"width\":1280,\"height\":720}]}");
parse(&p);
return 0;
}
The running result is:
width: 1280
height: 720