Add mg_json_get_hex(), mg_json_get_b64()

This commit is contained in:
Sergey Lyubka 2022-06-22 16:28:22 +01:00
parent a68f3dc4eb
commit 898e2b1e30
6 changed files with 117 additions and 2 deletions

View File

@ -2846,6 +2846,58 @@ char *str = mg_json_get_str(json, "$.a"); // str = "hi"
free(str);
```
### mg\_json\_get\_hex()
```c
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 `calloc()`, decoded,
and returned to the caller. It is the caller's responsibility to
`free()` the returned string. Returned buffer is 0-terminated.
Parameters:
- `json` - a string containing valid JSON
- `path` - 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:
```c
struct mg_str json = mg_str("{\"a\": \"6869\"}"); // json = {"a": "6869"}
char *str = mg_json_get_hex(json, "$.a", NULL); // str = "hi"
free(str);
```
### mg\_json\_get\_b64()
```c
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 `calloc()`, decoded,
and returned to the caller. It is the caller's responsibility to
`free()` the returned string. Returned buffer is 0-terminated.
Parameters:
- `json` - a string containing valid JSON
- `path` - 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:
```c
struct mg_str json = mg_str("{\"a\": \"YWJj\"}"); // json = {"a": "YWJj"}
char *str = mg_json_get_b64(json, "$.a", NULL); // str = "abc"
free(str);
```
## Utility
### mg\_call()

View File

@ -2026,6 +2026,7 @@ void mg_iobuf_free(struct mg_iobuf *io) {
#endif
static const char *escapeseq(int esc) {
return esc ? "\b\f\n\r\t\\\"" : "bfnrt\\\"";
}
@ -2246,6 +2247,31 @@ char *mg_json_get_str(struct mg_str json, const char *path) {
return result;
}
char *mg_json_get_b64(struct mg_str json, const char *path, int *len) {
int n, toklen;
char *result = NULL;
if ((n = mg_json_get(json.ptr, (int) json.len, path, &toklen)) >= 0 &&
json.ptr[n] == '"' && toklen > 1 &&
(result = (char *) calloc(1, (size_t) toklen)) != NULL) {
int k = mg_base64_decode(json.ptr + n + 1, toklen - 2, result);
if (len != NULL) *len = k;
}
return result;
}
char *mg_json_get_hex(struct mg_str json, const char *path, int *len) {
int n, toklen;
char *result = NULL;
if ((n = mg_json_get(json.ptr, (int) json.len, path, &toklen)) >= 0 &&
json.ptr[n] == '"' && toklen > 1 &&
(result = (char *) calloc(1, (size_t) toklen / 2)) != NULL) {
mg_unhex(json.ptr + n + 1, (size_t) (toklen - 2), (uint8_t *) result);
result[(toklen - 2) / 2] = '\0';
if (len != NULL) *len = (toklen - 2) / 2;
}
return result;
}
#ifdef MG_ENABLE_LINES
#line 1 "src/log.c"
#endif

View File

@ -1310,7 +1310,8 @@ int mg_json_get(const char *buf, int len, const char *path, int *toklen);
bool mg_json_get_num(struct mg_str json, const char *path, double *v);
bool mg_json_get_bool(struct mg_str json, const char *path, bool *v);
char *mg_json_get_str(struct mg_str json, const char *path);
char *mg_json_get_hex(struct mg_str json, const char *path);
char *mg_json_get_hex(struct mg_str json, const char *path, int *len);
char *mg_json_get_b64(struct mg_str json, const char *path, int *len);

View File

@ -1,4 +1,5 @@
#include "json.h"
#include "base64.h"
static const char *escapeseq(int esc) {
return esc ? "\b\f\n\r\t\\\"" : "bfnrt\\\"";
@ -219,3 +220,28 @@ char *mg_json_get_str(struct mg_str json, const char *path) {
}
return result;
}
char *mg_json_get_b64(struct mg_str json, const char *path, int *len) {
int n, toklen;
char *result = NULL;
if ((n = mg_json_get(json.ptr, (int) json.len, path, &toklen)) >= 0 &&
json.ptr[n] == '"' && toklen > 1 &&
(result = (char *) calloc(1, (size_t) toklen)) != NULL) {
int k = mg_base64_decode(json.ptr + n + 1, toklen - 2, result);
if (len != NULL) *len = k;
}
return result;
}
char *mg_json_get_hex(struct mg_str json, const char *path, int *len) {
int n, toklen;
char *result = NULL;
if ((n = mg_json_get(json.ptr, (int) json.len, path, &toklen)) >= 0 &&
json.ptr[n] == '"' && toklen > 1 &&
(result = (char *) calloc(1, (size_t) toklen / 2)) != NULL) {
mg_unhex(json.ptr + n + 1, (size_t) (toklen - 2), (uint8_t *) result);
result[(toklen - 2) / 2] = '\0';
if (len != NULL) *len = (toklen - 2) / 2;
}
return result;
}

View File

@ -14,4 +14,5 @@ int mg_json_get(const char *buf, int len, const char *path, int *toklen);
bool mg_json_get_num(struct mg_str json, const char *path, double *v);
bool mg_json_get_bool(struct mg_str json, const char *path, bool *v);
char *mg_json_get_str(struct mg_str json, const char *path);
char *mg_json_get_hex(struct mg_str json, const char *path);
char *mg_json_get_hex(struct mg_str json, const char *path, int *len);
char *mg_json_get_b64(struct mg_str json, const char *path, int *len);

View File

@ -2363,6 +2363,7 @@ static void test_json(void) {
{
double d = 0;
bool b = false;
int len;
const char *json = "{\"a\": \"hi\\nthere\",\"b\": [12345, true]}";
char *str = mg_json_get_str(mg_str(json), "$.a");
@ -2379,6 +2380,14 @@ static void test_json(void) {
ASSERT(mg_json_get_bool(mg_str(json), "$.b[0]", &b) == false);
ASSERT(mg_json_get_bool(mg_str(json), "$.b[1]", &b) == true);
ASSERT(b == true);
json = "[\"YWJj\", \"0100026869\"]";
ASSERT((str = mg_json_get_b64(mg_str(json), "$[0]", &len)) != NULL);
ASSERT(len == 3 && memcmp(str, "abc", (size_t) len) == 0);
free(str);
ASSERT((str = mg_json_get_hex(mg_str(json), "$[1]", &len)) != NULL);
ASSERT(len == 5 && memcmp(str, "\x01\x00\x02hi", (size_t) len) == 0);
free(str);
}
}