This commit fixes an issue in which GJSON was not representing integers
correctly that were greater than 53-bits when calling the result.Int()
and result.Uint() functions. This happened because GJSON stored all
numbers as float64s in the result.Num field, and Int()/Uint() would
simply try to convert the float64 to int64/uint64 by issuing
int64(result.Num) or uint64(result.Num) operations.
Now rather than a simple cast, GJSON checks to see if the float64 is a
whole integer and if the integer can fit within 53-bits. If so, then
the cast method can be used. Otherwise GJSON attempts to parse the
result.Raw directly. If that fails too, it falls back to the original
method.
This fix should maintain compatibility with existing applications.
thanks @joelpresence for reporting
fixes#29
It's a drop in replacement for json.Unmarshal and you can typically see
a 3 to 4 times boost in performance without the need for external tools
or generators.
This function works almost identically to json.Unmarshal except that
it expects the json to be well-formed prior to being called. Invalid
json will not panic, but it may return back unexpected results.
Therefore the return value of this function will always be nil.
Another difference is that gjson.Unmarshal will automatically attempt
to convert JSON values to any Go type. For example, the JSON string
"100" or the JSON number 100 can be equally assigned to Go string,
int, byte, uint64, etc. This rule applies to all types.
This commit alters the behavior of string handling.
Prior to this change, calling result.String() for nonexistent and null
JSON members would return "null". This runs counter to the zero and omitempty
defaults of Go. Thus I've been seeing in the wild:
s := result.String()
if s == "null" || s == "" {
// ... handle empty string condition
}
Now we can simply write:
if result.String() == "" {
// ... handle empty string condition
}
It's still possible to explicitly check for null and existence.
result.Type == gjson.Null
result.Exists()