JSON
Mongoose library is often used to exchange data in JSON format, therefore we have provided utility functions to format JSON strings easily:
mg_http_reply(c, 200, "Content-Type: application/json\r\n",
"{%m: %u}", MG_ESC("value"), 123); // {"value": 123}
Therefore, for full JSON support, a set of parsing functions is required - which is described below.
mg_json_get()
enum { MG_JSON_TOO_DEEP = -1, MG_JSON_INVALID = -2, MG_JSON_NOT_FOUND = -3 };
int mg_json_get(struct mg_str json, const char *path, int *toklen);
Parse JSON string json and return the offset of the element
specified by the JSON path. The length of the element is stored
in the toklen.
Parameters:
json- a string containing valid JSONpath- a JSON path. Must start with$, e.g.$.usertoklen- a pointer that receives element's length, can be NULL
Return value: offset of the element, or negative MG_JSON_* on error.
Usage example:
// Create a json string: { "a": 1, "b": [2, 3] }
char *buf = mg_mprintf("{ %m: %d, %m: [%d, %d] }",
MG_ESC("a"), 1,
MG_ESC("b"), 2, 3);
struct mg_str json = mg_str(buf);
int offset, length;
// Lookup "$", which is the whole JSON. Can be used for validation
offset = mg_json_get(json, "$", &length); // offset = 0, length = 23
// Lookup attribute "a". Point to value "1"
offset = mg_json_get(json, "$.a", &length); // offset = 7, length = 1
// Lookup attribute "b". Point to array [2, 3]
offset = mg_json_get(json, "$.b", &length); // offset = 15, length = 6
// Lookup attribute "b[1]". Point to value "3"
offset = mg_json_get(json, "$.b[1]", &length); // offset = 19, length = 1
mg_free(buf);
mg_json_get_tok()
struct mg_str mg_json_get_tok(struct mg_str json, const char *path);
Parse JSON string json and return a struct mg_str pointing to the value of the element
specified by the JSON path. Useful to check if a token is present, or inspect when it can have different types.
Parameters:
json- a string containing valid JSONpath- a JSON path. Must start with$, e.g.$.user
Return value: a struct mg_str pointing to the value of the element, or with a NULL pointer on error.
Usage example:
json = mg_str("{\"a\":\"b:c\"}");
val = mg_json_get_tok(json, "$.a"); // "b:c"
mg_json_get_num()
bool mg_json_get_num(struct mg_str json, const char *path, double *v);
Fetch numeric (double) value from the json string json at JSON path
path into a placeholder v. Return true if successful.
Parameters:
json- a string containing valid JSONpath- a JSON path. Must start with$v- a placeholder for value
Return value: true on success, false on error
Usage example:
double d = 0.0;
mg_json_get_num(mg_str("[1,2,3]", "$[1]", &d)); // d == 2
mg_json_get_num(mg_str("{\"a\":1.23}", "$.a", &d)); // d == 1.23
mg_json_get_bool()
bool mg_json_get_bool(struct mg_str json, const char *path, bool *v);
Fetch boolean (bool) value from the json string json at JSON path
path into a placeholder v. Return true if successful.
Parameters:
json- a string containing valid JSONpath- a JSON path. Must start with$v- a placeholder for value
Return value: true on success, false on error
Usage example:
bool b = false;
mg_json_get_bool(mg_str("[123]", "$[0]", &b)); // Error. b remains to be false
mg_json_get_bool(mg_str("[true]", "$[0]", &b)); // b is true
mg_json_get_long()
long mg_json_get_long(struct mg_str json, const char *path, long default_val);
Fetch integer numeric (long) value from the json string json at JSON path
path. Return it if found, or default_val if not found.
Parameters:
json- a string containing valid JSONpath- a JSON path. Must start with$default_val- a default value for the failure case
Return value: found value, or default_val value
Usage example:
long a = mg_json_get_long(mg_str("[123]", "$a", -1)); // a = -1
long b = mg_json_get_long(mg_str("[123]", "$[0]", -1)); // b = 123
mg_json_get_str()
char *mg_json_get_str(struct mg_str json, const char *path);
Fetch string value from the json string json at JSON path
path. If found, a string is allocated using mg_calloc(),
un-escaped, and returned to the caller. It is the caller's responsibility to
mg_free() the returned string.
Parameters:
json- a string containing valid JSONpath- a JSON path. Must start with$
Return value: non-NULL on success, NULL on error
Usage example:
struct mg_str json = mg_str("{\"a\": \"hi\"}"); // json = {"a": "hi"}
char *str = mg_json_get_str(json, "$.a"); // str = "hi"
mg_free(str);
mg_json_get_hex()
char *mg_json_get_hex(struct mg_str json, const char *path, int *len);
Fetch hex-encoded buffer from the json string json at JSON path
path. If found, a buffer is allocated using mg_calloc(), decoded,
and returned to the caller. It is the caller's responsibility to
mg_free() the returned string. Returned buffer is nul-terminated.
Parameters:
json- a string containing valid JSONpath- a JSON path. Must start with$len- a pointer that receives decoded length. Can be NULL
Return value: non-NULL on success, NULL on error
Usage example:
struct mg_str json = mg_str("{\"a\": \"6869\"}"); // json = {"a": "6869"}
char *str = mg_json_get_hex(json, "$.a", NULL); // str = "hi"
mg_free(str);
mg_json_get_b64()
char *mg_json_get_b4(struct mg_str json, const char *path, int *len);
Fetch base64-encoded buffer from the json string json at JSON path
path. If found, a buffer is allocated using mg_calloc(), decoded,
and returned to the caller. It is the caller's responsibility to
mg_free() the returned string. Returned buffer is nul-terminated.
Parameters:
json- a string containing valid JSONpath- a JSON path. Must start with$len- a pointer that receives decoded length. Can be NULL
Return value: non-NULL on success, NULL on error
Usage example:
struct mg_str json = mg_str("{\"a\": \"YWJj\"}"); // json = {"a": "YWJj"}
char *str = mg_json_get_b64(json, "$.a", NULL); // str = "abc"
mg_free(str);
mg_json_unescape()
bool mg_json_unescape(struct mg_str str, char *buf, size_t len);
Unescape a JSON string
Parameters:
str- a string containing valid JSON to be unescapedbuf- buffer where to place the resultlen- buffer length
Return value: true on success, false on error
Usage example:
struct mg_str str = mg_str("{\"a\": \"b\\u0063d\"}"); // escaped json = {"a": "b\u0063d"}
char json[20];
bool result = mg_json_unescape(str, result, 20); // json = {"a": "bcd"}
mg_json_next()
size_t mg_json_next(struct mg_str obj, size_t ofs, struct mg_str *key, struct mg_str *val);
Iterate over elements of an object or array. An initial value for ofs must be
0, then on each iteration a previously returned value should be passed.
Parameters:
json- a string containing valid JSONofs- an offset of the elementkey- a pointer that receives key. For arrays, set to empty. Can be NULLval- a pointer that receives value. Can be NULL
Return value: non-0 on success, 0 when there are no more elements
Usage example:
struct mg_str key, val, obj = mg_str("{\"a\": [true], \"b\": 12345}");
size_t ofs = 0;
while ((ofs = mg_json_next(obj, ofs, &key, &val)) > 0) {
printf("%.*s -> %.*s\n", (int) key.len, key.buf, (int) val.len, val.buf);
}
For an example on how to iterate over an arbitrary JSON string, see json_scan() function in the unit test.