Open wryun opened 1 year ago
I suppose you refer to blobmsg_add_json_element()
?
I would propose to implement a new API bool blobmsg_add_json_element_ex(struct blob_buf *b, const char *name, struct json_object *obj, unsigned int flags)
which accepts a number of flag such as:
BLOBMSG_NUMBERS_PREFER_DOUBLE
- Convert both json_type_int
and json_type_double
to BLOBMSG_TYPE_DOUBLE
BLOBMSG_NUMBERS_PREFER_INT64
- Convert json_type_int
and integral json_type_double
to BLOBMSG_TYPE_INT64
, fractional JSON doubles to BLOBMSG_TYPE_DOUBLE
BLOBMSG_NUMBERS_PREFER_INT32
- Convert json_type_int
[-2147483647..2147483647] to BLOBMSG_TYPE_INT32
, smaller/larger json_type_int
to BLOBMSG_TYPE_INT64
, integral json_type_double
to BLOBMSG_TYPE_INT32 (or BLOBMSG_TYPE_INT64 if it exceeds range) and other doubles to BLOBMSG_TYPE_DOUBLE
BLOBMSG_NUMBERS_FORCE_INT32
- Like above but truncate values outside of the int32_t rangeAdding a cast mechanism analogous to the existing BLOBMSG_CAST_INT64
machinery makes sense to me.
Treating anything numeric as double internally, while being more in line with JSON's idea of numeric types, sounds not very resource efficient wrt. embedded system usage.
The root issue is that Blobs' have a lot of numeric types and JSON only has one. The JSON-C library attempts to guess the type and this guess is reflected in the blob format:
However, consider the case of passing a double in via JSON. The upstream code might pass something like 2.1, or it might pass something like 2, noting that JSON/Javascript thinks of all things as Numbers; the former will be turned into a
BLOBMSG_TYPE_DOUBLE
while the latter will be turned into aBLOBMSG_TYPE_INT32
. As far as I understand it, the only way to handle this with a policy when parsing the resulting message is to useBLOBMSG_TYPE_UNSPEC
and then write your own conversion. e.g.This whole situation makes me a little uncomfortable. My preference would be for all JSON numbers to be represented as doubles in the blobmsg, but this is hardly backwards compatible. A conservative approach would be to add a BLOBMSG_CAST_DOUBLE type (cf
BLOBMSG_CAST_INT64
) and the helper functions above. I'd also like there to be equivalent double->int casting functions, potentially changing the behaviour of BLOBMSG_CAST_INT64 to support doubles.Thoughts?