Skip to content

Commit 1231b52

Browse files
authored
Merge pull request #285 from JuliaIO/kms/parsers-jl
Parse floats using Parsers.jl (fixes #284)
2 parents da20219 + 654b5b5 commit 1231b52

File tree

4 files changed

+23
-8
lines changed

4 files changed

+23
-8
lines changed

Manifest.toml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,12 @@ uuid = "d6f4376e-aef5-505a-96c1-9c027394607a"
2525
[[Mmap]]
2626
uuid = "a63ad114-7e13-5084-954f-fe012c677804"
2727

28+
[[Parsers]]
29+
deps = ["Dates", "Test"]
30+
git-tree-sha1 = "eaed2db080700f1013f0fc05667ecb2a082265a1"
31+
uuid = "69de0a69-1ddd-5017-9359-2bf0b02dc9f0"
32+
version = "0.3.5"
33+
2834
[[Printf]]
2935
deps = ["Unicode"]
3036
uuid = "de0858da-6303-5e67-8744-51eddeeeb8d7"

Project.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ uuid = "682c06a0-de6a-54ab-a142-c8b1cf79cde6"
55
Dates = "ade2ca70-3891-5945-98fb-dc099432e06a"
66
Distributed = "8ba89e20-285c-5b6f-9357-94700520ee1b"
77
Mmap = "a63ad114-7e13-5084-954f-fe012c677804"
8+
Parsers = "69de0a69-1ddd-5017-9359-2bf0b02dc9f0"
89
Sockets = "6462fe0b-24de-5631-8697-dd941f90decc"
910
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"
1011
Unicode = "4ec0a83e-493e-50e2-b9ac-8f72acf5a8f5"

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)