@@ -37,7 +37,7 @@ mutable struct StreamingParserState{T <: IO} <: ParserState
37
37
end
38
38
StreamingParserState (io:: IO ) = StreamingParserState (io, 0x00 , true , PushVector {UInt8} ())
39
39
40
- struct ParserContext{DictType, IntType, AllowNanInf} end
40
+ struct ParserContext{DictType, IntType, AllowNanInf, NullValue } end
41
41
42
42
"""
43
43
Return the byte at the current position of the `ParserState`. If there is no
@@ -173,7 +173,8 @@ function parse_value(pc::ParserContext, ps::ParserState)
173
173
end
174
174
end
175
175
176
- function parse_jsconstant (:: ParserContext{<:Any,<:Any,AllowNanInf} , ps:: ParserState ) where AllowNanInf
176
+ function parse_jsconstant (:: ParserContext{<:Any,<:Any,AllowNanInf,NullValue} ,
177
+ ps:: ParserState ) where {AllowNanInf,NullValue}
177
178
c = advance! (ps)
178
179
if c == LATIN_T # true
179
180
skip! (ps, LATIN_R, LATIN_U, LATIN_E)
@@ -183,7 +184,7 @@ function parse_jsconstant(::ParserContext{<:Any,<:Any,AllowNanInf}, ps::ParserSt
183
184
false
184
185
elseif c == LATIN_N # null
185
186
skip! (ps, LATIN_U, LATIN_L, LATIN_L)
186
- nothing
187
+ NullValue
187
188
elseif AllowNanInf && c == LATIN_UPPER_N
188
189
skip! (ps, LATIN_A, LATIN_UPPER_N)
189
190
NaN
@@ -427,20 +428,21 @@ function unparameterize_type(T::Type)
427
428
end
428
429
429
430
# Workaround for slow dynamic dispatch for creating objects
430
- const DEFAULT_PARSERCONTEXT = ParserContext {Dict{String, Any}, Int64, false} ()
431
- function _get_parsercontext (dicttype, inttype, allownan)
431
+ const DEFAULT_PARSERCONTEXT = ParserContext {Dict{String, Any}, Int64, false, nothing } ()
432
+ function _get_parsercontext (dicttype, inttype, allownan, null )
432
433
if dicttype == Dict{String, Any} && inttype == Int64 && ! allownan
433
434
DEFAULT_PARSERCONTEXT
434
435
else
435
- ParserContext{unparameterize_type (dicttype), inttype, allownan}. instance
436
+ ParserContext{unparameterize_type (dicttype), inttype, allownan, null }. instance
436
437
end
437
438
end
438
439
439
440
"""
440
441
parse{T<:Associative}(str::AbstractString;
441
442
dicttype::Type{T}=Dict,
442
443
inttype::Type{<:Real}=Int64,
443
- allownan::Bool=true)
444
+ allownan::Bool=true,
445
+ null=nothing)
444
446
445
447
Parses the given JSON string into corresponding Julia types.
446
448
@@ -449,12 +451,14 @@ Keyword arguments:
449
451
• inttype: Real number type to use when parsing JSON numbers that can be parsed
450
452
as integers (default: Int64)
451
453
• allownan: allow parsing of NaN, Infinity, and -Infinity (default: true)
454
+ • null: value to use for parsed JSON `null` values (default: `nothing`)
452
455
"""
453
456
function parse (str:: AbstractString ;
454
457
dicttype= Dict{String,Any},
455
458
inttype:: Type{<:Real} = Int64,
456
- allownan:: Bool = true )
457
- pc = _get_parsercontext (dicttype, inttype, allownan)
459
+ allownan:: Bool = true ,
460
+ null= nothing )
461
+ pc = _get_parsercontext (dicttype, inttype, allownan, null)
458
462
ps = MemoryParserState (str, 1 )
459
463
v = parse_value (pc, ps)
460
464
chomp_space! (ps)
468
472
parse{T<:Associative}(io::IO;
469
473
dicttype::Type{T}=Dict,
470
474
inttype::Type{<:Real}=Int64,
471
- allownan=true)
475
+ allownan=true,
476
+ null=nothing)
472
477
473
478
Parses JSON from the given IO stream into corresponding Julia types.
474
479
@@ -477,12 +482,14 @@ Keyword arguments:
477
482
• inttype: Real number type to use when parsing JSON numbers that can be parsed
478
483
as integers (default: Int64)
479
484
• allownan: allow parsing of NaN, Infinity, and -Infinity (default: true)
485
+ • null: value to use for parsed JSON `null` values (default: `nothing`)
480
486
"""
481
487
function parse (io:: IO ;
482
488
dicttype= Dict{String,Any},
483
489
inttype:: Type{<:Real} = Int64,
484
- allownan:: Bool = true )
485
- pc = _get_parsercontext (dicttype, inttype, allownan)
490
+ allownan:: Bool = true ,
491
+ null= nothing )
492
+ pc = _get_parsercontext (dicttype, inttype, allownan, null)
486
493
ps = StreamingParserState (io)
487
494
parse_value (pc, ps)
488
495
end
492
499
dicttype=Dict{String, Any},
493
500
inttype::Type{<:Real}=Int64,
494
501
allownan::Bool=true,
502
+ null=nothing,
495
503
use_mmap::Bool=true)
496
504
497
505
Convenience function to parse JSON from the given file into corresponding Julia types.
@@ -501,17 +509,19 @@ Keyword arguments:
501
509
• inttype: Real number type to use when parsing JSON numbers that can be parsed
502
510
as integers (default: Int64)
503
511
• allownan: allow parsing of NaN, Infinity, and -Infinity (default: true)
512
+ • null: value to use for parsed JSON `null` values (default: `nothing`)
504
513
• use_mmap: use mmap when opening the file (default: true)
505
514
"""
506
515
function parsefile (filename:: AbstractString ;
507
516
dicttype= Dict{String, Any},
508
517
inttype:: Type{<:Real} = Int64,
518
+ null= nothing ,
509
519
allownan:: Bool = true ,
510
520
use_mmap:: Bool = true )
511
521
sz = filesize (filename)
512
522
open (filename) do io
513
523
s = use_mmap ? String (Mmap. mmap (io, Vector{UInt8}, sz)) : read (io, String)
514
- parse (s; dicttype= dicttype, inttype= inttype, allownan= allownan)
524
+ parse (s; dicttype= dicttype, inttype= inttype, allownan= allownan, null = null )
515
525
end
516
526
end
517
527
0 commit comments