Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

Add a decoding flag to get all numbers as strings #10

Open
akheron opened this Issue · 8 comments

2 participants

@akheron
Owner

All numbers or only overflowing numbers, or maybe two separate flags?

@keenerd

Bump.

I've gotten a bug report in my program (jshon) from this one. For example

# test case
jshon -e test <<< '{"test":200.123456789}'
# ver >= 2.1 (JSON_ENCODE_ANY)
200.12345678899999
# ver < 2.1
200.123457

Neither of these outcomes are good.

@akheron
Owner

So you'd like to decode the value as a string? Or is the imprecise decimal representation the problem?

@keenerd

I would like to skip decoding altogether and access the original string. The imprecise decimal notation is only a symptom of why it is needed. Jshon does not do any math - it is only supposed to extract and spit out chunks of json. (Arguably one could attach a precision field to the json_t struct and dig this value out when it comes time to printf and generate a printf format string on the fly. But that seems silly.)

@akheron
Owner

Ok. But this decoding flag would give you a string, i.e. "200.123456789", not a special value that's a number but whose contained value is a string. So you would lose the information that the value in JSON input was a number.

@keenerd

That seems not good. And breaks a chunk of the json spec, since the type information would be screwed up. Two ideas of the top of my head...

Two more int fields in the structs. These int fields would contain the index and length of substring from the original input that the decoded value was derived from. Probably accessed by a json_get_source() function? Hacky, but less hacky than denying that numbers exist at all.

A new non-numerical number type. It would be neither int nor float, just javascript-style "number". Internally represented as a string, up to the user to decode however they want. This also makes the people who want a single JS-style numerical type happy. Probably enabled by a parse flag?

@akheron
Owner

Adding a precision field to the json_real_t struct sounds the best option this far, only used by the decoder and encoder (if set).

@keenerd

Darn. I was hoping for a cleaner fix, something that did not involve throwing more patches onto a string -> number -> string conversion, by way of using sprintf to dynamically generate format string for printf. Yuck.

To that end, I've got half of the code put together for a new SNUMBER type at https://github.com/keenerd/jansson

Only the code for basic loading and dumping has been written. It is missing the almost all the helper functions (setting, deleting, etc) and is a little kludgy because the parse flags are not available in the lexing stage (can't have a TOKEN_SNUMBER). It does build, but I have not been able to test it properly because cmake refuses to build shared .so libraries. Figuring out how to make cmake build these was more complicated that writing the prototype SNUMBER code.

@akheron
Owner

Introducing a new type for this use case doesn't sound so good. The ultimately correct fix would be to replace sprintf("%.17g") with the algorithm in David Gay's dtoa.c or similar.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.