Skip to content

Commit

Permalink
Squashed 'packages/JSON/' content from commit 4b3913d
Browse files Browse the repository at this point in the history
git-subtree-dir: packages/JSON
git-subtree-split: 4b3913d58f04cc5bb2f8d23c6ef82e0fbed20525
  • Loading branch information
davidanthoff committed Jan 17, 2023
0 parents commit 9a0feac
Show file tree
Hide file tree
Showing 105 changed files with 2,814 additions and 0 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
*.cov
*.mem
data/*.json
12 changes: 12 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
language: julia
os:
- osx
- linux
julia:
- 0.7
- 1.0
- nightly
notifications:
email: false
after_success:
- julia -e 'import Pkg; Pkg.add("Coverage"); using Coverage; Codecov.submit(process_folder())';
25 changes: 25 additions & 0 deletions LICENSE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
The Julia JSON package is licensed under the MIT Expat License:

> Copyright (c) 2002: JSON.org, 2012–2016: Avik Sengupta, Stefan Karpinski,
> David de Laat, Dirk Gadsen, Milo Yip and other contributors
> https://github.com/JuliaLang/JSON.jl/contributors
> and https://github.com/miloyip/nativejson-benchmark/contributors
>
> Permission is hereby granted, free of charge, to any person obtaining
> a copy of this software and associated documentation files (the
> "Software"), to deal in the Software without restriction, including
> without limitation the rights to use, copy, modify, merge, publish,
> distribute, sublicense, and/or sell copies of the Software, and to
> permit persons to whom the Software is furnished to do so, subject to
> the following conditions:
>
> The above copyright notice and this permission notice shall be
> included in all copies or substantial portions of the Software.
>
> THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
> EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
> MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
> NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
> LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
> OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
> WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 changes: 22 additions & 0 deletions Project.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
name = "JSON"
uuid = "682c06a0-de6a-54ab-a142-c8b1cf79cde6"
version = "0.20.1"

[deps]
Dates = "ade2ca70-3891-5945-98fb-dc099432e06a"
Mmap = "a63ad114-7e13-5084-954f-fe012c677804"
Unicode = "4ec0a83e-493e-50e2-b9ac-8f72acf5a8f5"

[extras]
DataStructures = "864edb3b-99cc-5e75-8d2d-829cb0a9cfe8"
Distributed = "8ba89e20-285c-5b6f-9357-94700520ee1b"
FixedPointNumbers = "53c48c17-4a7d-5ca2-90c5-79b7896eea93"
OffsetArrays = "6fe1bfb0-de20-5000-8ca7-80f57d26f881"
Sockets = "6462fe0b-24de-5631-8697-dd941f90decc"
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"

[compat]
julia = "0.7, 1"

[targets]
test = ["DataStructures", "Distributed", "FixedPointNumbers", "OffsetArrays", "Sockets", "Test"]
108 changes: 108 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
# JSON.jl
### Parsing and printing JSON in pure Julia.

[![Build Status](https://travis-ci.org/JuliaIO/JSON.jl.svg)](https://travis-ci.org/JuliaIO/JSON.jl)
[![Build status](https://ci.appveyor.com/api/projects/status/2sfomjwl29k6y6oy)](https://ci.appveyor.com/project/staticfloat/json-jl)
[![codecov.io](http://codecov.io/github/JuliaIO/JSON.jl/coverage.svg?branch=master)](http://codecov.io/github/JuliaIO/JSON.jl?branch=master)

[![JSON](http://pkg.julialang.org/badges/JSON_0.3.svg)](http://pkg.julialang.org/?pkg=JSON&ver=0.3)
[![JSON](http://pkg.julialang.org/badges/JSON_0.4.svg)](http://pkg.julialang.org/?pkg=JSON&ver=0.4)
[![JSON](http://pkg.julialang.org/badges/JSON_0.5.svg)](http://pkg.julialang.org/?pkg=JSON&ver=0.5)
[![JSON](http://pkg.julialang.org/badges/JSON_0.6.svg)](http://pkg.julialang.org/?pkg=JSON&ver=0.6)

**Installation**: `julia> Pkg.add("JSON")`


## Basic Usage


```julia
import JSON

# JSON.parse - string or stream to Julia data structures
s = "{\"a_number\" : 5.0, \"an_array\" : [\"string\", 9]}"
j = JSON.parse(s)
# Dict{AbstractString,Any} with 2 entries:
# "an_array" => {"string",9}
# "a_number" => 5.0

# JSON.json - Julia data structures to a string
JSON.json([2,3])
# "[2,3]"
JSON.json(j)
# "{\"an_array\":[\"string\",9],\"a_number\":5.0}"
```

## Documentation


```julia
JSON.print(io::IO, s::AbstractString)
JSON.print(io::IO, s::Union{Integer, AbstractFloat})
JSON.print(io::IO, n::Nothing)
JSON.print(io::IO, b::Bool)
JSON.print(io::IO, a::AbstractDict)
JSON.print(io::IO, v::AbstractVector)
JSON.print{T, N}(io::IO, v::Array{T, N})
```

Writes a compact (no extra whitespace or indentation) JSON representation
to the supplied IO.

```julia
JSON.print(a::AbstractDict, indent)
JSON.print(io::IO, a::AbstractDict, indent)
```

Writes a JSON representation with newlines, and indentation if specified. Non-zero `indent` will be applied recursively to nested elements.


```julia
json(a::Any)
```

Returns a compact JSON representation as an `AbstractString`.

```julia
JSON.parse(s::AbstractString; dicttype=Dict, inttype=Int64)
JSON.parse(io::IO; dicttype=Dict, inttype=Int64)
JSON.parsefile(filename::AbstractString; dicttype=Dict, inttype=Int64, use_mmap=true)
```

Parses a JSON `AbstractString` or IO stream into a nested `Array` or `Dict`.

The `dicttype` indicates the dictionary type (`<: Associative`), or a function that
returns an instance of a dictionary type,
that JSON objects are parsed to. It defaults to `Dict` (the built-in Julia
dictionary), but a different type can be passed for additional functionality.
For example, if you `import DataStructures`
(assuming the [DataStructures
package](https://github.com/JuliaLang/DataStructures.jl) is
installed)

- you can pass `dicttype=DataStructures.OrderedDict` to maintain the insertion order
of the items in the object;
- or you can pass `()->DefaultDict{String,Any}(Missing)` to having any non-found keys
return `missing` when you index the result.


The `inttype` argument controls how integers are parsed. If a number in a JSON
file is recognized to be an integer, it is parsed as one; otherwise it is parsed
as a `Float64`. The `inttype` defaults to `Int64`, but, for example, if you know
that your integer numbers are all small and want to save space, you can pass
`inttype=Int32`. Alternatively, if your JSON input has integers which are too large
for Int64, you can pass `inttype=Int128` or `inttype=BigInt`. `inttype` can be any
subtype of `Real`.

```julia
JSONText(s::AbstractString)
```
A wrapper around a Julia string representing JSON-formatted text,
which is inserted *as-is* in the JSON output of `JSON.print` and `JSON.json`.

```julia
JSON.lower(p::Point2D) = [p.x, p.y]
```

Define a custom serialization rule for a particular data type. Must return a
value that can be directly serialized; see help for more details.
43 changes: 43 additions & 0 deletions appveyor.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
environment:
matrix:
- julia_version: 0.7
- julia_version: 1
- julia_version: nightly

platform:
- x86 # 32-bit
- x64 # 64-bit

# # Uncomment the following lines to allow failures on nightly julia
# # (tests will run but not make your overall status red)
# matrix:
# allow_failures:
# - julia_version: nightly

branches:
only:
- master
- /release-.*/

notifications:
- provider: Email
on_build_success: false
on_build_failure: false
on_build_status_changed: false

install:
- ps: iex ((new-object net.webclient).DownloadString("https://raw.githubusercontent.com/JuliaCI/Appveyor.jl/version-1/bin/install.ps1"))

build_script:
- echo "%JL_BUILD_SCRIPT%"
- C:\julia\bin\julia -e "%JL_BUILD_SCRIPT%"

test_script:
- echo "%JL_TEST_SCRIPT%"
- C:\julia\bin\julia -e "%JL_TEST_SCRIPT%"

# # Uncomment to support code coverage upload. Should only be enabled for packages
# # which would have coverage gaps without running on Windows
# on_success:
# - echo "%JL_CODECOV_SCRIPT%"
# - C:\julia\bin\julia -e "%JL_CODECOV_SCRIPT%"
92 changes: 92 additions & 0 deletions bench/bench.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
#!/usr/bin/julia --color=yes

using ArgParse
using JSON


function bench(f, simulate=false)
fp = joinpath(JSON_DATA_DIR, string(f, ".json"))
if !isfile(fp)
println("Downloading benchmark file...")
download(DATA_SOURCES[f], fp)
end
GC.gc() # run gc so it doesn't affect benchmarks
t = if args["parse"]["parse-file"]
@elapsed JSON.parsefile(fp)
else
data = read(fp, String)
@elapsed JSON.Parser.parse(data)
end

if !simulate
printstyled(" [Bench$FLAGS] "; color=:yellow)
println(f, " ", t, " seconds")
end
t
end


const JSON_DATA_DIR = joinpath(dirname(dirname(@__FILE__)), "data")
const s = ArgParseSettings(description="Benchmark JSON.jl")

const DATA_SOURCES = Dict(
"canada" => "https://raw.githubusercontent.com/miloyip/nativejson-benchmark/v1.0.0/data/canada.json",
"citm_catalog" => "https://raw.githubusercontent.com/miloyip/nativejson-benchmark/v1.0.0/data/citm_catalog.json",
"citylots" => "https://raw.githubusercontent.com/zemirco/sf-city-lots-json/master/citylots.json",
"twitter" => "https://raw.githubusercontent.com/miloyip/nativejson-benchmark/v1.0.0/data/twitter.json")

@add_arg_table s begin
"parse"
action = :command
help = "Run a JSON parser benchmark"
"list"
action = :command
help = "List available JSON files for use"
end

@add_arg_table s["parse"] begin
"--include-compile", "-c"
help = "If set, include the compile time in measurements"
action = :store_true
"--parse-file", "-f"
help = "If set, measure JSON.parsefile, hence including IO time"
action = :store_true
"file"
help = "The JSON file to benchmark (leave out to benchmark all)"
required = false
end

const args = parse_args(ARGS, s)

if args["%COMMAND%"] == "parse"
const FLAGS = string(
args["parse"]["include-compile"] ? "C" : "",
args["parse"]["parse-file"] ? "F" : "")

if args["parse"]["file"] nothing
const file = args["parse"]["file"]

if !args["parse"]["include-compile"]
bench(file, true)
end
bench(file)
else
times = 1.0
if args["parse"]["include-compile"]
error("Option --include-compile can only be used for single file.")
end
for k in sort(collect(keys(DATA_SOURCES)))
bench(k, true) # warm up compiler
end
for k in sort(collect(keys(DATA_SOURCES)))
times *= bench(k) # do benchmark
end
print_with_color(:yellow, " [Bench$FLAGS] ")
println("Total (G.M.) ", times^(1/length(DATA_SOURCES)), " seconds")
end
elseif args["%COMMAND%"] == "list"
println("Available benchmarks are:")
for k in sort(collect(keys(DATA_SOURCES)))
println("$k")
end
end
56 changes: 56 additions & 0 deletions bench/micro.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
# JSON Microbenchmarks
# 0.6 required for running benchmarks

using JSON
using BenchmarkTools
using Dates

const suite = BenchmarkGroup()

suite["print"] = BenchmarkGroup(["serialize"])
suite["pretty-print"] = BenchmarkGroup(["serialize"])

struct CustomListType
x::Int
y::Float64
z::Union{CustomListType, Nothing}
end

struct CustomTreeType
x::String
y::Union{CustomTreeType, Nothing}
z::Union{CustomTreeType, Nothing}
end

list(x) = x == 0 ? nothing : CustomListType(1, 1.0, list(x - 1))
tree(x) = x == 0 ? nothing : CustomTreeType("!!!", tree(x - 1), tree(x - 1))

const micros = Dict(
"integer" => 88,
"float" => -88.8,
"ascii" => "Hello World!",
"ascii-1024" => "x" ^ 1024,
"unicode" => "ສະ​ບາຍ​ດີ​ຊາວ​ໂລກ!",
"unicode-1024" => "" ^ 1024,
"bool" => true,
"null" => nothing,
"flat-homogenous-array-16" => collect(1:16),
"flat-homogenous-array-1024" => collect(1:1024),
"heterogenous-array" => [
1, 2, 3, 7, "A", "C", "E", "N", "Q", "R", "Shuttle to Grand Central"],
"nested-array-16^2" => [collect(1:16) for _ in 1:16],
"nested-array-16^3" => [[collect(1:16) for _ in 1:16] for _ in 1:16],
"small-dict" => Dict(
:a => :b, :c => "💙💙💙💙💙💙", :e => 10, :f => Dict(:a => :b)),
"flat-dict-128" => Dict(zip(collect(1:128), collect(1:128))),
"date" => Date(2016, 08, 09),
"matrix-16" => [i == j ? 1.0 : 0.0 for i in 1:16, j in 1:16],
"custom-list-128" => list(128),
"custom-tree-8" => tree(8))

for (k, v) in micros
io = IOBuffer()
suite["print"][k] = @benchmarkable JSON.print($(IOBuffer()), $v)
suite["pretty-print"][k] = @benchmarkable JSON.print(
$(IOBuffer()), $v, 4)
end
1 change: 1 addition & 0 deletions data/jsonchecker/fail01.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
fable
1 change: 1 addition & 0 deletions data/jsonchecker/fail02.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
["Unclosed array"
1 change: 1 addition & 0 deletions data/jsonchecker/fail03.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{unquoted_key: "keys must be quoted"}
1 change: 1 addition & 0 deletions data/jsonchecker/fail04.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
["extra comma",]
1 change: 1 addition & 0 deletions data/jsonchecker/fail05.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
["double extra comma",,]
1 change: 1 addition & 0 deletions data/jsonchecker/fail06.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
[ , "<-- missing value"]
1 change: 1 addition & 0 deletions data/jsonchecker/fail07.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
["Comma after the close"],
1 change: 1 addition & 0 deletions data/jsonchecker/fail08.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
["Extra close"]]
1 change: 1 addition & 0 deletions data/jsonchecker/fail09.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"Extra comma": true,}
1 change: 1 addition & 0 deletions data/jsonchecker/fail10.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"Extra value after close": true} "misplaced quoted value"
Loading

0 comments on commit 9a0feac

Please sign in to comment.