diff options
author | Daniel Golle <daniel@makrotopia.org> | 2020-08-04 03:27:09 +0300 |
---|---|---|
committer | Daniel Golle <daniel@makrotopia.org> | 2020-08-06 16:29:36 +0300 |
commit | 9e52171d70def760a6949676800d0b73f85ee22d (patch) | |
tree | 8a69d6ff6d46ba0ccd8ec3d710375701be8b268b | |
parent | f4e9bf73ac5c0ee6b8f240e2a2100e70ca56d705 (diff) |
blobmsg: introduce BLOBMSG_CAST_INT64
When dealing with 64-bit integers in JSON documents, blobmsg_parse
becomes useless as blobmsg-json only uses BLOBMSG_TYPE_INT64 if the
value exceeds the range of a 32-bit integer, otherwise
BLOBMSG_TYPE_INT32 is used. This is because blobmsg-json parses the
JSON document ad-hoc without knowing the schema in advance and hence
a result of the design of blobmsg-json (and the absence of JSON
schema definitions).
In practise, this made code less readable as instead of using
blobmsg_parse() one had to to deal with *all* attributes manually just
to catch fields which can be both, BLOBMSG_TYPE_INT32 or
BLOBMSG_TYPE_INT64, but are always dealt with as uint64_t in code as
they potentially could exceed the 32-bit range.
To resolve this issue, introduce as special wildcard attribute
type BLOBMSG_CAST_INT64 which should only be used in policies used
by blobmsg_parse(). If used for an attribute in the policy,
blobmsg_parse shall accept all integer types and allow the user
to retrieve the value using the uint64_t blobmsg_cast_u64() and
int64_t blobmsg_cast_s64() functions which is also introduced by this
commit.
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
-rw-r--r-- | blobmsg.c | 8 | ||||
-rw-r--r-- | blobmsg.h | 33 |
2 files changed, 41 insertions, 0 deletions
@@ -195,9 +195,17 @@ int blobmsg_parse(const struct blobmsg_policy *policy, int policy_len, continue; if (policy[i].type != BLOBMSG_TYPE_UNSPEC && + policy[i].type != BLOBMSG_CAST_INT64 && blob_id(attr) != policy[i].type) continue; + if (policy[i].type == BLOBMSG_CAST_INT64 && + (blob_id(attr) != BLOBMSG_TYPE_INT64 && + blob_id(attr) != BLOBMSG_TYPE_INT32 && + blob_id(attr) != BLOBMSG_TYPE_INT16 && + blob_id(attr) != BLOBMSG_TYPE_INT8)) + continue; + if (blobmsg_namelen(hdr) != pslen[i]) continue; @@ -35,6 +35,7 @@ enum blobmsg_type { __BLOBMSG_TYPE_LAST, BLOBMSG_TYPE_LAST = __BLOBMSG_TYPE_LAST - 1, BLOBMSG_TYPE_BOOL = BLOBMSG_TYPE_INT8, + BLOBMSG_CAST_INT64, }; struct blobmsg_hdr { @@ -288,6 +289,38 @@ static inline uint64_t blobmsg_get_u64(struct blob_attr *attr) return tmp; } +static inline uint64_t blobmsg_cast_u64(struct blob_attr *attr) +{ + uint64_t tmp = 0; + + if (blobmsg_type(attr) == BLOBMSG_TYPE_INT64) + tmp = blobmsg_get_u64(attr); + else if (blobmsg_type(attr) == BLOBMSG_TYPE_INT32) + tmp = blobmsg_get_u32(attr); + else if (blobmsg_type(attr) == BLOBMSG_TYPE_INT16) + tmp = blobmsg_get_u16(attr); + else if (blobmsg_type(attr) == BLOBMSG_TYPE_INT8) + tmp = blobmsg_get_u8(attr); + + return tmp; +} + +static inline int64_t blobmsg_cast_s64(struct blob_attr *attr) +{ + int64_t tmp = 0; + + if (blobmsg_type(attr) == BLOBMSG_TYPE_INT64) + tmp = blobmsg_get_u64(attr); + else if (blobmsg_type(attr) == BLOBMSG_TYPE_INT32) + tmp = (int32_t)blobmsg_get_u32(attr); + else if (blobmsg_type(attr) == BLOBMSG_TYPE_INT16) + tmp = (int16_t)blobmsg_get_u16(attr); + else if (blobmsg_type(attr) == BLOBMSG_TYPE_INT8) + tmp = (int8_t)blobmsg_get_u8(attr); + + return tmp; +} + static inline double blobmsg_get_double(struct blob_attr *attr) { union { |