-
Notifications
You must be signed in to change notification settings - Fork 4.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Allow JsonReader to tell if it peeked a long or double #1621
Comments
If I'm not mistaken and remember how Gson readers work, you can check whether the peeked token type indicates a number, and then read it as a string. This would allow any parsing strategy since JSON is not restricted only with longs and doubles. |
Yep, you can read a numeric type as a string. |
Also! If your JSON needs to differentiate between long and double, your JSON is going to cause you grief. In particular you cannot use it with JavaScript where there is no such distinction. |
But I do NOT want to read numbers as strings. I am wondering if we are misunderstanding each other. I want to read the data in the best-fit type possible. Right now, I cannot. The API tells me "I peeked a number" ( |
Well, I can't very well tell customers that their JSON is "wrong", their REST APIs is what I've got. It specifies |
JSON syntax does not provide any mention on a concrete type for numeric values, therefore JSON numbers are not limited to 64-bit integer or IEEE374 double precision values, so final BigInteger valueBefore = new BigInteger(2048, new Random());
final String json = valueBefore.toString(); // produces a valid JSON document
try ( final JsonReader jsonReader = new JsonReader(new StringReader(json)) ) {
final JsonToken jsonToken = jsonReader.peek();
assert jsonToken == JsonToken.NUMBER;
final String stringValue = jsonReader.nextString();
final BigInteger valueAfter = new BigInteger(stringValue);
assert valueBefore.equals(valueAfter);
} Also, reading the numeric token as a string would allow to parse the number using any parsing strategy. private static Number parseNaively(final String s) {
@Nullable final Integer i = Ints.tryParse(s); if ( i != null ) { return i; }
@Nullable final Long l = Longs.tryParse(s); if ( l != null ) { return l; }
@Nullable final Float f = Floats.tryParse(s); if ( f != null ) { return f; }
@Nullable final Double d = Doubles.tryParse(s); if ( d != null ) { return d; }
... BigInteger, BigDecimal and so on
} In short, reading the number using |
This issue is interesting to me from a different perspective. I have a use case where I only want to perform processing on String values in a JSON document, and pass any primitive values (numbers, booleans, nulls) as-is. I'm looking for the most performant way to do this, without needing to parse any values for these JsonTokens. Would something like the following guarantee that no internal parsing or 're-serialization' is going to occur for number types?
Since there's no JsonNumber abstraction, and no Also, in response to the JSON spec not defining concrete types for numeric values, I think this issue should be interpreted more in regards to the GSON implementation as opposed to the JSON specification. I say this because the JsonReader class actually defines methods for nextDouble(), nextLong(), and nextInt(), but does not provide a nextNumber() method that corresponds to the abstract JSON 'Number' token. With that in mind, I think the question is valid (not just for my own selfish reasons given my use case above!) :-) |
What |
Related to #1267 |
Fixed by #1290. |
Problem: I need to tell apart long from doubles when generically using a
JsonReader
.Example:
{ "amount" : "93.21948702", "count": 12 }
Today I need to know in advance that one is a double and the other an int/long so I can call
nextDouble()
ornextLong()
. I want the reader to provide me enough information so that I can know which one to call or just give me the right object.Solution 1: Add
JSonReader#getPeeked()
and makePEEKED_LONG
andPEEKED_NUMBER
public.This leave me to do:
Solution 2: Add
JsonReader#getNumber()
returnsjava.lang.Number
.Which leaves me to do:
reader.nextNumber()
and I can deal with a
Double
orLong
down the line.I can propose a PR but I'd like to know if there are alternatives. Right now I am using, arg, reflection to get to
JSonReader.peeked
,PEEKED_LONG
andPEEKED_NUMBER
.The text was updated successfully, but these errors were encountered: