@@ -25,8 +25,11 @@ Read JSON.
25
25
* `allow_inf`: Allow reading of `Inf` and `NaN` values (not part of the JSON standard). [default `false`]
26
26
* `dateformat`: A [`DateFormat`](https://docs.julialang.org/en/v1/stdlib/Dates/#Dates.DateFormat) describing the format of dates in the JSON so that they can be read into `Date`s, `Time`s, or `DateTime`s when reading into a type. [default `Dates.default_format(T)`]
27
27
* `parsequoted`: Accept quoted values when reading into a NumberType. [default `false`]
28
+ * `numbertype`: Type to parse numbers as. [default `nothing`, which parses numbers as Int if possible, Float64 otherwise]
28
29
"""
29
- function read (str:: AbstractString ; jsonlines:: Bool = false , kw... )
30
+ function read (str:: AbstractString ; jsonlines:: Bool = false ,
31
+ numbertype:: Union{DataType, Nothing} = nothing , kw... )
32
+
30
33
buf = codeunits (str)
31
34
len = length (buf)
32
35
if len == 0
@@ -39,10 +42,18 @@ function read(str::AbstractString; jsonlines::Bool=false, kw...)
39
42
@wh
40
43
tape = len < 1000 ? Vector {UInt64} (undef, len + 4 ) :
41
44
Vector {UInt64} (undef, div (len, 10 ))
45
+ if numbertype === nothing
46
+ checkint = true
47
+ elseif numbertype == Float64
48
+ checkint = false
49
+ else
50
+ throw (ArgumentError (" numbertype $numbertype is not supported. " *
51
+ " Only `nothing` (default) and `Float64` are supported so far." ))
52
+ end
42
53
if jsonlines
43
- pos, tapeidx = jsonlines! (buf, pos, len, b, tape, Int64 (1 ); kw... )
54
+ pos, tapeidx = jsonlines! (buf, pos, len, b, tape, Int64 (1 ), checkint ; kw... )
44
55
else
45
- pos, tapeidx = read! (buf, pos, len, b, tape, Int64 (1 ), Any; kw... )
56
+ pos, tapeidx = read! (buf, pos, len, b, tape, Int64 (1 ), Any, checkint ; kw... )
46
57
end
47
58
@inbounds t = tape[1 ]
48
59
if isobject (t)
@@ -74,9 +85,9 @@ const FLOAT_INT_BOUND = 2.0^53
74
85
75
86
function read! (buf, pos, len, b, tape, tapeidx, :: Type{Any} , checkint= true ; allow_inf:: Bool = false )
76
87
if b == UInt8 (' {' )
77
- return read! (buf, pos, len, b, tape, tapeidx, Object; allow_inf= allow_inf)
88
+ return read! (buf, pos, len, b, tape, tapeidx, Object, checkint ; allow_inf= allow_inf)
78
89
elseif b == UInt8 (' [' )
79
- return read! (buf, pos, len, b, tape, tapeidx, Array; allow_inf= allow_inf)
90
+ return read! (buf, pos, len, b, tape, tapeidx, Array, checkint ; allow_inf= allow_inf)
80
91
elseif b == UInt8 (' "' )
81
92
return read! (buf, pos, len, b, tape, tapeidx, String)
82
93
elseif b == UInt8 (' n' )
@@ -203,7 +214,7 @@ function read!(buf, pos, len, b, tape, tapeidx, ::Type{Nothing})
203
214
end
204
215
end
205
216
206
- function read! (buf, pos, len, b, tape, tapeidx, :: Type{Object} ; kw... )
217
+ function read! (buf, pos, len, b, tape, tapeidx, :: Type{Object} , checkint = true ; kw... )
207
218
objidx = tapeidx
208
219
eT = EMPTY
209
220
pos += 1
@@ -263,7 +274,7 @@ function read!(buf, pos, len, b, tape, tapeidx, ::Type{Object}; kw...)
263
274
@wh
264
275
# now positioned at start of value
265
276
prevtapeidx = tapeidx
266
- pos, tapeidx = read! (buf, pos, len, b, tape, tapeidx, Any; kw... )
277
+ pos, tapeidx = read! (buf, pos, len, b, tape, tapeidx, Any, checkint ; kw... )
267
278
@eof
268
279
b = getbyte (buf, pos)
269
280
@wh
@@ -297,7 +308,7 @@ function read!(buf, pos, len, b, tape, tapeidx, ::Type{Object}; kw...)
297
308
invalid (error, buf, pos, Object)
298
309
end
299
310
300
- function read! (buf, pos, len, b, tape, tapeidx, :: Type{Array} ; kw... )
311
+ function read! (buf, pos, len, b, tape, tapeidx, :: Type{Array} , checkint = true ; kw... )
301
312
arridx = tapeidx
302
313
eT = EMPTY
303
314
pos += 1
@@ -317,7 +328,8 @@ function read!(buf, pos, len, b, tape, tapeidx, ::Type{Array}; kw...)
317
328
while true
318
329
# positioned at start of value
319
330
prevtapeidx = tapeidx
320
- pos, tapeidx = read! (buf, pos, len, b, tape, tapeidx, Any, eT != FLOAT && eT != (FLOAT | NULL); kw... )
331
+ check_int = checkint ? eT != FLOAT && eT != (FLOAT | NULL) : false
332
+ pos, tapeidx = read! (buf, pos, len, b, tape, tapeidx, Any, check_int; kw... )
321
333
@eof
322
334
b = getbyte (buf, pos)
323
335
@wh
@@ -345,7 +357,7 @@ function read!(buf, pos, len, b, tape, tapeidx, ::Type{Array}; kw...)
345
357
invalid (error, buf, pos, Array)
346
358
end
347
359
348
- function jsonlines! (buf, pos, len, b, tape, tapeidx; kw... )
360
+ function jsonlines! (buf, pos, len, b, tape, tapeidx, checkint = true ; kw... )
349
361
arridx = tapeidx
350
362
eT = EMPTY
351
363
if pos > len
@@ -361,7 +373,8 @@ function jsonlines!(buf, pos, len, b, tape, tapeidx; kw...)
361
373
@wh
362
374
# positioned at start of value
363
375
prevtapeidx = tapeidx
364
- pos, tapeidx = read! (buf, pos, len, b, tape, tapeidx, Any, eT != FLOAT && eT != (FLOAT | NULL); kw... )
376
+ check_int = checkint ? eT != FLOAT && eT != (FLOAT | NULL) : false
377
+ pos, tapeidx = read! (buf, pos, len, b, tape, tapeidx, Any, check_int; kw... )
365
378
@inbounds eT = promoteeltype (eT, gettypemask (tape[prevtapeidx]))
366
379
nelem += 1
367
380
if pos > len
0 commit comments