-
Notifications
You must be signed in to change notification settings - Fork 1.2k
[JSONSerialization] Use Int64 and UInt64 for integer parsing #1654
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
Closed
Closed
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't believe pointer distances are sufficient to tell whether the numeric values are equivalent. For instance, on my machine:
produces
For
UINT64_MAX
, for instance,strtod
,strtoll
, andstrtoull
all read the same number of characters but produce very different results — onlystrtoull
returns the correct results. This might've worked when we just hadDouble
andInt
, but no longer; we'll likely need to take a more involved approach here:strtod
. If the result is 0 and*doubleEndPointer
is notNUL
, bail out (failure to parse); if the result is ±HUGE_VAL
anderrno
is set toERANGE
(and wasn't before), it's too large to fit in aDouble
, in which case bailstrtoll
. If the result is 0 and*int64EndPointer
is notNUL
, return theDouble
value if parsed correctly (otherwise bail, failure to parse). If the result isLLONG_MAX
orLLONG_MIN
anderrno
is set toERANGE
then bail ifLLONG_MIN
(since the value was negative and won't be parsed correctly bystrtoull
). Also, if the string started with a-
, return this int value as there's no point in parsing as unsignedstrtoull
. If the result is 0 and*uint64EndPointer
is notNUL
, bail; if the result isULLONG_MAX
anderrno
is set toERANGE
, bail.doubleDistance
is > thanint64Distance
anduint64Distance
, return theDouble
value; otherwise, theInt64
value if it fit in anInt64
; otherwise, theUInt64
valueI don't remember if Swift has any good facilities for working with
errno
as it is allowed to be a macro IIRC but I can take a look. I'll sketch this out in C to clarify the intent.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To illustrate, this is what I had in mind (rough code, no testing yet):
/cc @spevans
We can also introduce
Decimal
into the above to better representDouble
values to preserve as much precision as possible.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
With the above code:
yields
So this might get us a bit closer.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm, yes, this is quite a bit more involved than I'd thought. In any case, though, to match Darwin behavior fully, we would ultimately need something like #1655. This was meant to be an incremental improvement in the meantime that, given my responsibility for #1634, I could feasibly contribute in some spare time. However, @spevans is much further along here and I'll go ahead and close this.