JSON
Header File
#include "mln_json.h"
Module
json
Functions/Macros
mln_json_init
mln_json_init(j)
Description: Initialize JSON type node j, setting its type to 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 *. The JSON structure takes ownership of s; the caller must ensure s remains valid and must not modify its content.
Return value: None
mln_json_number_init
mln_json_number_init(j, n)
Description: Initialize JSON type node j to number type and assign a double value n.
Return value: None
mln_json_true_init
mln_json_true_init(j)
Description: Initialize JSON type node j to true type.
Return value: None
mln_json_false_init
mln_json_false_init(j)
Description: Initialize JSON type node j to 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, storing the result in out. The policy parameter is a security policy structure initialized by mln_json_policy_init. On failure, out is automatically cleaned up — do not call mln_json_destroy on it.
Return value:
0- on success-1- on failure. Ifpolicyis notNULL, usemln_json_policy_errorto check which security constraint was violated.
mln_json_destroy
void mln_json_destroy(mln_json_t *j);
Description: Free all memory held by the mln_json_t node j.
Return value: None
mln_json_dump
void mln_json_dump(mln_json_t *j, int n_space, char *prefix);
Description: Print the details of JSON node j to standard output. n_space specifies the current indentation level in spaces, and prefix is prepended to the output.
Return value: None
mln_json_encode
mln_string_t *mln_json_encode(mln_json_t *j, mln_u32_t flags);
Description: Serialize the mln_json_t node structure into a JSON text string. The caller must free the returned value with mln_string_free.
Flags:
0- Output as standard JSON text format (default)M_JSON_ENCODE_UNICODE(0x1) - Escape non-ASCII characters (e.g. Chinese) to\uXXXXform
Return value: An mln_string_t pointer on success, or NULL on failure
mln_json_obj_search
mln_json_t *mln_json_obj_search(mln_json_t *j, mln_string_t *key);
Description: Search for the value associated with key in the object type node j.
Return value: The mln_json_t value on success, or NULL if not found
mln_json_array_search
mln_json_t *mln_json_array_search(mln_json_t *j, mln_uauto_t index);
Description: Retrieve the element at index index from the array type node j.
Return value: The mln_json_t element on success, or NULL if the index is out of range
mln_json_array_length
mln_uauto_t mln_json_array_length(mln_json_t *j);
Description: Get the length of the array. 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-val pair to the object type JSON node j. If key already exists, the existing key and value are replaced. The function copies the contents of key and val internally; the caller does not need to heap-allocate them.
Return value: 0 on success, -1 on failure
mln_json_obj_element_num
mln_size_t mln_json_obj_element_num(mln_json_t *j);
Description: Get the number of key-value pairs in the object type JSON node j.
Return value: Number of key-value pairs
mln_json_array_append
int mln_json_array_append(mln_json_t *j, mln_json_t *value);
Description: Append value to the end of the array type JSON node j. The function copies the contents of value internally.
Return value: 0 on success, -1 on failure
mln_json_array_update
int mln_json_array_update(mln_json_t *j, mln_json_t *value, mln_uauto_t index);
Description: Replace the element at index index in the array type JSON node j with value. Fails if the index does not exist. The function copies the contents of value internally.
Return value: 0 on success, -1 on failure
mln_json_reset
void mln_json_reset(mln_json_t *j);
Description: Reset JSON node j by releasing its data and restoring its type to NONE.
Return value: None
mln_json_obj_remove
void mln_json_obj_remove(mln_json_t *j, mln_string_t *key);
Description: Remove and free the key-value pair with key key from the object type JSON node j.
Return value: None
mln_json_array_remove
void mln_json_array_remove(mln_json_t *j, mln_uauto_t index);
Description: Remove and free the last element from the array type JSON node j. The index parameter must equal the last valid index (i.e., length - 1); it is used only for an assertion check in debug builds.
Return value: None
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: Check the type of the mln_json_t node json. The types are, in order: object, array, string, number, true, false, null, none.
Return value: Non-zero if the condition is met, 0 otherwise
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 mln_json_t node json. The types are, in order: none, object, array, string, number, true, 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 portion of the corresponding type from the mln_json_t node json.
Return value:
- Object type:
mln_json_obj_tpointer - Array type:
mln_array_tpointer - String type:
mln_string_tpointer - Number type:
doublevalue - True type:
mln_u8_tvalue - False type:
mln_u8_tvalue - Null type:
mln_u8ptr_tNULL value
mln_json_policy_init
mln_json_policy_init(policy, _depth, _keylen, _strlen, _elemnum, _kvnum);
Description: Initialize the mln_json_policy_t variable policy. The parameters are:
_depth- Maximum nesting depth. During parsing, the depth increases when entering an array or object, and decreases when leaving. A value of0means no limit._keylen- Maximum length of object keys. A value of0means no limit._strlen- Maximum length of string values. A value of0means no limit._elemnum- Maximum number of array elements. A value of0means no limit._kvnum- Maximum number of key-value pairs in an object. A value of0means no limit.
Return value: None
mln_json_policy_error
mln_json_policy_error(policy)
Description: Get the error code from the mln_json_policy_t variable policy. Typically used to check which security constraint was violated when mln_json_decode returns -1.
Return value: An int error code with the following possible values:
M_JSON_OK- No security policy violation.M_JSON_DEPTH- Nesting depth exceeded.M_JSON_KEYLEN- Object key length exceeded.M_JSON_STRLEN- String value length exceeded.M_JSON_ARRELEM- Array element count exceeded.M_JSON_OBJKV- Object key-value pair count exceeded.
mln_json_fetch
int mln_json_fetch(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:
Navigate the JSON tree rooted at j using the dot-separated expression exp to locate a matching child node. If a match is found and iterator is not NULL, the iterator callback is invoked with the matched node. data is user-defined data passed to iterator.
Given the following JSON:
{
"a": [1, {
"c": 3
}],
"b": 2
}
Example expressions:
| Expression | Meaning |
|---|---|
a |
Get the value with key a (each value is an mln_json_t node) |
b |
Get the value with key b |
a.0 |
Get the element at index 0 of the array under key a |
a.1.c |
Navigate into the array under key a, then element at index 1 (an object), then get the value with key c |
a.2.c |
Element at index 2 does not exist, so mln_json_fetch returns -1 |
Return value:
0- on success-1- on failure
mln_json_generate
int mln_json_generate(mln_json_t *j, char *fmt, ...);
Description:
Populate j according to the format string fmt using the subsequent variadic arguments.
Supported format specifiers in fmt:
{}- Object type. Keys and values are separated by:, key-value pairs are separated by,.[]- Array type. Elements are separated by,.j- The variadic argument is amln_json_tpointer.d- The variadic argument is a 32-bit signed integer (e.g.int,mln_s32_t).D- The variadic argument is a 64-bit signed integer (e.g.long long,mln_s64_t).u- The variadic argument is a 32-bit unsigned integer (e.g.unsigned int,mln_u32_t).U- The variadic argument is a 64-bit unsigned integer (e.g.unsigned long long,mln_u64_t).F- The variadic argument is adoublevalue.t- Insert atruevalue. No corresponding variadic argument is needed.f- Insert afalsevalue. No corresponding variadic argument is needed.n- Insert anullvalue. No corresponding variadic argument is needed.s- The variadic argument is achar *string.S- The variadic argument is amln_string_t *string.c- The variadic argument is astruct mln_json_call_attr *containing acallbackfunction anddatapointer. The value at this position is produced by invokingcallbackwithdata.
Notes:
- Only the format specifiers listed above may appear in
fmt. No spaces, tabs, newlines, or other characters are allowed. - After a successful call, the JSON node passed via the
jformat specifier is taken over by the output. The caller must not callmln_json_destroyormln_json_reseton it.
Example:
mln_json_init(&j);
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, 0);
// The result is: [{"a":1,"b":3,"c":{"d":4}},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: Iterate over each key-value pair in the object j, invoking it for each pair. data is user-defined data passed to it.
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: Iterate over each element in the array j, invoking it for each element. data is user-defined data passed to it.
Return value:
0- on success- Non-zero - Failure or early termination. Any non-zero value returned by
itstops the iteration.
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[])
{
int i = 1024;
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}");
/* Decode the string into an mln_json_t node */
if (mln_json_decode(&tmp, &j, NULL) < 0) {
fprintf(stderr, "decode error\n");
return -1;
}
/* Get the first element of the array under key "protocols" */
mln_json_fetch(&j, &exp, handler, NULL);
/* Set up the user-defined callback structure */
ca.callback = callback;
ca.data = &i;
/* Always initialize before calling mln_json_generate */
mln_json_init(&k);
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;
}
/* These two elements are appended to the k array */
mln_json_generate(&k, "[s,d]", "g", 99);
/* Encode the structure to a JSON string */
res = mln_json_encode(&k, 0);
/* Do not destroy j separately — its contents are now owned by k */
mln_json_destroy(&k);
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;
}
Output:
type:string val:[http]
[{"a":1,"b":3,"c":{"d":4}},5,[],{"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},1024,"g",99]
The first line is the output from mln_json_dump in handler. The second line is the JSON string produced 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_fetch(&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;
}
Output:
width: 1280
height: 720