akheron / jansson

C library for encoding, decoding and manipulating JSON data
http://www.digip.org/jansson/
Other
3.05k stars 809 forks source link

Support `s#` and/or `s%` for `json_unpack` #580

Open gonzus opened 3 years ago

gonzus commented 3 years ago

Given a JSON object j containing something like

{"schema": {"foo": true}}

it would be great to be able to say

int enabled = 0;
char* cptr = 0;
int clen = 0; // or size_t
json_unpack(j, "{s:{s#:b}}", "schema", cptr, &clen, &enabled); // or s%

and get the string "foo" in cptr and the length 3 in clen. This way you don't have to compute that length afterwards, which is something you most likely already know inside the library.

Zer0-One commented 3 years ago

https://jansson.readthedocs.io/en/2.13/apiref.html#parsing-and-validating-values

I might be confused about what you're asking, but does s% here not behave the way you're describing?

gonzus commented 3 years ago

I think the confusion is all mine... I was trying to do basically what amounts to this:

const char* nptr = 0;
size_t nlen = 0;
const char* sptr = 0;
size_t slen = 0;
int ret = json_unpack_ex(j, &error, JSON_STRICT, "{s%:s%}", &nptr, &nlen, &sptr, &slen);

but this doesn't work because you cannot retrieve object key names with json_unpack; you need to provide the key name in order to get the corresponding value. If instead I do this:

int ret = json_unpack_ex(j, &error, JSON_STRICT, "{s:s%}", "schema", &sptr, &slen);

it works as expected.

I am now guessing it doesn't make sense to try to fetch the key name in this way, because you do need to know it in order to fetch its corresponding value. I did not see this because in my use case, my object has a single (key, value) pair.

gonzus commented 3 years ago

Ok, so now that I have clarified my own mind about this, here is something I would really like to be able to do. Instead of writing this:

int ret = json_unpack_ex(j, &error, JSON_STRICT, "{s:s%}", "schema", &sptr, &slen);

I would like to be able to write this:

int ret = json_unpack_ex(j, &error, JSON_STRICT, "{s@:s%}", "schema", 6, &sptr, &slen);

where that s@ is a placeholder for some kind of format that tells jansson that I am passing a string "schema" and its length 6 as the key value I am trying to extract. Perhaps this is already possible? Maybe s# could be used for this, since it doesn't seem to be used for json_unpack?