1
0
mirror of https://github.com/systemd/systemd synced 2024-07-01 07:34:28 +00:00

json: add sd_json_dispatch_double() helper

This commit is contained in:
Lennart Poettering 2024-05-08 09:11:13 +02:00 committed by Luca Boccassi
parent 10880ae3c4
commit 4fae650ad8
4 changed files with 60 additions and 0 deletions

View File

@ -851,6 +851,7 @@ global:
sd_json_buildv;
sd_json_dispatch;
sd_json_dispatch_const_string;
sd_json_dispatch_double;
sd_json_dispatch_full;
sd_json_dispatch_id128;
sd_json_dispatch_int16;

View File

@ -4954,6 +4954,20 @@ _public_ int sd_json_dispatch_uint8(const char *name, sd_json_variant *variant,
return 0;
}
_public_ int sd_json_dispatch_double(const char *name, sd_json_variant *variant, sd_json_dispatch_flags_t flags, void *userdata) {
double *d = ASSERT_PTR(userdata);
/* Note, this will take care of parsing NaN, -Infinity, Infinity for us */
if (sd_json_variant_is_string(variant) && safe_atod(sd_json_variant_string(variant), d) >= 0)
return 0;
if (!sd_json_variant_is_real(variant))
return json_log(variant, flags, SYNTHETIC_ERRNO(EINVAL), "JSON field '%s' is not a floating point value, nor one formatted as string.", strna(name));
*d = sd_json_variant_real(variant);
return 0;
}
_public_ int sd_json_dispatch_string(const char *name, sd_json_variant *variant, sd_json_dispatch_flags_t flags, void *userdata) {
char **s = ASSERT_PTR(userdata);
int r;

View File

@ -315,6 +315,7 @@ int sd_json_dispatch_uint16(const char *name, sd_json_variant *variant, sd_json_
int sd_json_dispatch_int16(const char *name, sd_json_variant *variant, sd_json_dispatch_flags_t flags, void *userdata);
int sd_json_dispatch_int8(const char *name, sd_json_variant *variant, sd_json_dispatch_flags_t flags, void *userdata);
int sd_json_dispatch_uint8(const char *name, sd_json_variant *variant, sd_json_dispatch_flags_t flags, void *userdata);
int sd_json_dispatch_double(const char *name, sd_json_variant *variant, sd_json_dispatch_flags_t flags, void *userdata);
int sd_json_dispatch_uid_gid(const char *name, sd_json_variant *variant, sd_json_dispatch_flags_t flags, void *userdata);
int sd_json_dispatch_id128(const char *name, sd_json_variant *variant, sd_json_dispatch_flags_t flags, void *userdata);
int sd_json_dispatch_unsupported(const char *name, sd_json_variant *variant, sd_json_dispatch_flags_t flags, void *userdata);

View File

@ -947,6 +947,50 @@ TEST(json_dispatch_enum_define) {
assert(data.d < 0);
}
TEST(json_dispatch_double) {
_cleanup_(sd_json_variant_unrefp) sd_json_variant *j = NULL;
assert_se(sd_json_build(&j, SD_JSON_BUILD_OBJECT(
SD_JSON_BUILD_PAIR("x1", SD_JSON_BUILD_REAL(0.5)),
SD_JSON_BUILD_PAIR("x2", SD_JSON_BUILD_REAL(-0.5)),
SD_JSON_BUILD_PAIR("x3", JSON_BUILD_CONST_STRING("infinity")),
SD_JSON_BUILD_PAIR("x4", JSON_BUILD_CONST_STRING("-infinity")),
SD_JSON_BUILD_PAIR("x5", JSON_BUILD_CONST_STRING("nan")),
SD_JSON_BUILD_PAIR("x6", JSON_BUILD_CONST_STRING("inf")),
SD_JSON_BUILD_PAIR("x7", JSON_BUILD_CONST_STRING("-inf")))) >= 0);
struct data {
double x1, x2, x3, x4, x5, x6, x7;
} data = {};
assert_se(sd_json_dispatch(j,
(const sd_json_dispatch_field[]) {
{ "x1", _SD_JSON_VARIANT_TYPE_INVALID, sd_json_dispatch_double, offsetof(struct data, x1), 0 },
{ "x2", _SD_JSON_VARIANT_TYPE_INVALID, sd_json_dispatch_double, offsetof(struct data, x2), 0 },
{ "x3", _SD_JSON_VARIANT_TYPE_INVALID, sd_json_dispatch_double, offsetof(struct data, x3), 0 },
{ "x4", _SD_JSON_VARIANT_TYPE_INVALID, sd_json_dispatch_double, offsetof(struct data, x4), 0 },
{ "x5", _SD_JSON_VARIANT_TYPE_INVALID, sd_json_dispatch_double, offsetof(struct data, x5), 0 },
{ "x6", _SD_JSON_VARIANT_TYPE_INVALID, sd_json_dispatch_double, offsetof(struct data, x6), 0 },
{ "x7", _SD_JSON_VARIANT_TYPE_INVALID, sd_json_dispatch_double, offsetof(struct data, x7), 0 },
{},
},
/* flags= */ 0,
&data) >= 0);
assert_se(fabs(data.x1 - 0.5) < 0.01);
assert_se(fabs(data.x2 + 0.5) < 0.01);
assert_se(isinf(data.x3));
assert_se(data.x3 > 0);
assert_se(isinf(data.x4));
assert_se(data.x4 < 0);
assert_se(isnan(data.x5));
assert_se(isinf(data.x6));
assert_se(data.x6 > 0);
assert_se(isinf(data.x7));
assert_se(data.x7 < 0);
}
TEST(json_sensitive) {
_cleanup_(sd_json_variant_unrefp) sd_json_variant *a = NULL, *b = NULL, *v = NULL;
_cleanup_free_ char *s = NULL;