@@ -2,6 +2,7 @@ module Parser # JSON
22
33using Mmap
44using .. Common
5+ import Parsers
56
67include (" pushvector.jl" )
78
2728# it is convenient to access MemoryParserState like a Vector{UInt8} to avoid copies
2829Base. @propagate_inbounds Base. getindex (state:: MemoryParserState , i:: Int ) = codeunit (state. utf8, i)
2930Base. length (state:: MemoryParserState ) = sizeof (state. utf8)
30- Base. unsafe_convert (:: Type{Ptr{UInt8}} , state:: MemoryParserState ) = Base. unsafe_convert (Ptr{UInt8}, state. utf8)
3131
3232mutable struct StreamingParserState{T <: IO } <: ParserState
3333 io:: T
@@ -317,12 +317,21 @@ end
317317Parse a float from the given bytes vector, starting at `from` and ending at the
318318byte 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
326335end
327336
328337"""
0 commit comments