Skip to content

Commit 654b5b5

Browse files
committed
Parse floats using Parsers.jl
1 parent 7eeb0c7 commit 654b5b5

File tree

2 files changed

+16
-8
lines changed

2 files changed

+16
-8
lines changed

src/Parser.jl

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ module Parser # JSON
22

33
using Mmap
44
using ..Common
5+
import Parsers
56

67
include("pushvector.jl")
78

@@ -27,7 +28,6 @@ end
2728
# it is convenient to access MemoryParserState like a Vector{UInt8} to avoid copies
2829
Base.@propagate_inbounds Base.getindex(state::MemoryParserState, i::Int) = codeunit(state.utf8, i)
2930
Base.length(state::MemoryParserState) = sizeof(state.utf8)
30-
Base.unsafe_convert(::Type{Ptr{UInt8}}, state::MemoryParserState) = Base.unsafe_convert(Ptr{UInt8}, state.utf8)
3131

3232
mutable struct StreamingParserState{T <: IO} <: ParserState
3333
io::T
@@ -317,12 +317,21 @@ end
317317
Parse a float from the given bytes vector, starting at `from` and ending at the
318318
byte before `to`. Bytes enclosed should all be ASCII characters.
319319
"""
320-
function float_from_bytes(bytes, from::Int, to::Int)
321-
# The ccall is not ideal (Base.tryparse would be better), but it actually
322-
# makes an 2× difference to performance
323-
hasvalue, val = ccall(:jl_try_substrtod, Tuple{Bool, Float64},
324-
(Ptr{UInt8}, Csize_t, Csize_t), bytes, from - 1, to - from + 1)
325-
hasvalue ? val : nothing
320+
float_from_bytes(bytes::PushVector, from::Int, to::Int) = _float_from_bytes(bytes.v, from, to)
321+
float_from_bytes(bytes::MemoryParserState, from::Int, to::Int) = _float_from_bytes(bytes.utf8, from, to)
322+
323+
function _float_from_bytes(bytes, from::Int, to::Int)::Union{Float64,Nothing}
324+
# Would like to use tryparse, but we want it to consume the full input,
325+
# and the version in Parsers does not do this.
326+
327+
# return Parsers.tryparse(Float64, @view bytes.utf8[from:to])
328+
329+
len = to - from + 1
330+
x, code, vpos, vlen, tlen = Parsers.xparse(Float64, bytes, from, to, Parsers.OPTIONS)
331+
if !Parsers.ok(code) || vlen < len
332+
return nothing
333+
end
334+
return x::Float64
326335
end
327336

328337
"""

src/pushvector.jl

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ end
99
# Default length of 20 should be enough to never need to grow in most cases
1010
PushVector{T}() where {T} = PushVector(Vector{T}(undef, 20), 0)
1111

12-
Base.unsafe_convert(::Type{Ptr{UInt8}}, v::PushVector) = pointer(v.v)
1312
Base.length(v::PushVector) = v.l
1413
Base.size(v::PushVector) = (v.l,)
1514
@inline function Base.getindex(v::PushVector, i)

0 commit comments

Comments
 (0)