summaryrefslogtreecommitdiff
path: root/src/shared/json.c
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2020-12-01 13:45:32 +0100
committerLennart Poettering <lennart@poettering.net>2020-12-17 20:01:17 +0100
commit2d64d2b95538e00278d5a38c38171019dafab486 (patch)
tree92f78e78acdba8cad3240b8e336ba14fa8e2882a /src/shared/json.c
parent1403d48d6189f71d450cf9cfda1ac8494e16b20c (diff)
downloadsystemd-2d64d2b95538e00278d5a38c38171019dafab486.tar.gz
json: add APIs for quickly inserting hex blobs into as JSON strings
This is similar to the base64 support, but fixed-size hash values are typically preferably presented as series of hex values, hence store them here like that too.
Diffstat (limited to 'src/shared/json.c')
-rw-r--r--src/shared/json.c51
1 files changed, 51 insertions, 0 deletions
diff --git a/src/shared/json.c b/src/shared/json.c
index 6ea246a22b..6beb56cfa0 100644
--- a/src/shared/json.c
+++ b/src/shared/json.c
@@ -433,6 +433,19 @@ int json_variant_new_base64(JsonVariant **ret, const void *p, size_t n) {
return json_variant_new_stringn(ret, s, k);
}
+int json_variant_new_hex(JsonVariant **ret, const void *p, size_t n) {
+ _cleanup_free_ char *s = NULL;
+
+ assert_return(ret, -EINVAL);
+ assert_return(n == 0 || p, -EINVAL);
+
+ s = hexmem(p, n);
+ if (!s)
+ return -ENOMEM;
+
+ return json_variant_new_stringn(ret, s, n*2);
+}
+
int json_variant_new_id128(JsonVariant **ret, sd_id128_t id) {
char s[SD_ID128_STRING_MAX];
@@ -3603,6 +3616,36 @@ int json_buildv(JsonVariant **ret, va_list ap) {
break;
}
+ case _JSON_BUILD_HEX: {
+ const void *p;
+ size_t n;
+
+ if (!IN_SET(current->expect, EXPECT_TOPLEVEL, EXPECT_OBJECT_VALUE, EXPECT_ARRAY_ELEMENT)) {
+ r = -EINVAL;
+ goto finish;
+ }
+
+ p = va_arg(ap, const void *);
+ n = va_arg(ap, size_t);
+
+ if (current->n_suppress == 0) {
+ r = json_variant_new_hex(&add, p, n);
+ if (r < 0)
+ goto finish;
+ }
+
+ n_subtract = 1;
+
+ if (current->expect == EXPECT_TOPLEVEL)
+ current->expect = EXPECT_END;
+ else if (current->expect == EXPECT_OBJECT_VALUE)
+ current->expect = EXPECT_OBJECT_KEY;
+ else
+ assert(current->expect == EXPECT_ARRAY_ELEMENT);
+
+ break;
+ }
+
case _JSON_BUILD_ID128: {
sd_id128_t id;
@@ -4405,6 +4448,14 @@ int json_variant_unbase64(JsonVariant *v, void **ret, size_t *ret_size) {
return unbase64mem(json_variant_string(v), (size_t) -1, ret, ret_size);
}
+int json_variant_unhex(JsonVariant *v, void **ret, size_t *ret_size) {
+
+ if (!json_variant_is_string(v))
+ return -EINVAL;
+
+ return unhexmem(json_variant_string(v), (size_t) -1, ret, ret_size);
+}
+
static const char* const json_variant_type_table[_JSON_VARIANT_TYPE_MAX] = {
[JSON_VARIANT_STRING] = "string",
[JSON_VARIANT_INTEGER] = "integer",