json 1.8.6 → 2.7.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (107) hide show
  1. checksums.yaml +5 -5
  2. data/{CHANGES → CHANGES.md} +292 -96
  3. data/LICENSE +56 -0
  4. data/README.md +185 -114
  5. data/ext/json/ext/fbuffer/fbuffer.h +0 -3
  6. data/ext/json/ext/generator/generator.c +328 -117
  7. data/ext/json/ext/generator/generator.h +8 -8
  8. data/ext/json/ext/parser/extconf.rb +29 -0
  9. data/ext/json/ext/parser/parser.c +540 -569
  10. data/ext/json/ext/parser/parser.h +10 -6
  11. data/ext/json/ext/parser/parser.rl +269 -261
  12. data/ext/json/extconf.rb +1 -1
  13. data/json.gemspec +0 -0
  14. data/lib/json/add/bigdecimal.rb +40 -10
  15. data/lib/json/add/complex.rb +32 -9
  16. data/lib/json/add/core.rb +1 -0
  17. data/lib/json/add/date.rb +27 -7
  18. data/lib/json/add/date_time.rb +26 -9
  19. data/lib/json/add/exception.rb +25 -7
  20. data/lib/json/add/ostruct.rb +32 -9
  21. data/lib/json/add/range.rb +33 -8
  22. data/lib/json/add/rational.rb +30 -8
  23. data/lib/json/add/regexp.rb +28 -10
  24. data/lib/json/add/set.rb +48 -0
  25. data/lib/json/add/struct.rb +29 -7
  26. data/lib/json/add/symbol.rb +28 -5
  27. data/lib/json/add/time.rb +27 -6
  28. data/lib/json/common.rb +402 -188
  29. data/lib/json/ext.rb +0 -6
  30. data/lib/json/generic_object.rb +11 -6
  31. data/lib/json/pure/generator.rb +120 -137
  32. data/lib/json/pure/parser.rb +64 -86
  33. data/lib/json/pure.rb +2 -8
  34. data/lib/json/version.rb +2 -1
  35. data/lib/json.rb +559 -29
  36. metadata +18 -129
  37. data/.gitignore +0 -17
  38. data/.travis.yml +0 -18
  39. data/Gemfile +0 -7
  40. data/README-json-jruby.markdown +0 -33
  41. data/Rakefile +0 -402
  42. data/TODO +0 -1
  43. data/VERSION +0 -1
  44. data/data/example.json +0 -1
  45. data/data/index.html +0 -38
  46. data/data/prototype.js +0 -4184
  47. data/diagrams/.keep +0 -0
  48. data/install.rb +0 -23
  49. data/java/src/json/ext/ByteListTranscoder.java +0 -166
  50. data/java/src/json/ext/Generator.java +0 -446
  51. data/java/src/json/ext/GeneratorMethods.java +0 -231
  52. data/java/src/json/ext/GeneratorService.java +0 -42
  53. data/java/src/json/ext/GeneratorState.java +0 -542
  54. data/java/src/json/ext/OptionsReader.java +0 -113
  55. data/java/src/json/ext/Parser.java +0 -2644
  56. data/java/src/json/ext/Parser.rl +0 -968
  57. data/java/src/json/ext/ParserService.java +0 -34
  58. data/java/src/json/ext/RuntimeInfo.java +0 -120
  59. data/java/src/json/ext/StringDecoder.java +0 -166
  60. data/java/src/json/ext/StringEncoder.java +0 -111
  61. data/java/src/json/ext/Utils.java +0 -88
  62. data/json-java.gemspec +0 -38
  63. data/json_pure.gemspec +0 -37
  64. data/lib/json/ext/.keep +0 -0
  65. data/tests/fixtures/fail1.json +0 -1
  66. data/tests/fixtures/fail10.json +0 -1
  67. data/tests/fixtures/fail11.json +0 -1
  68. data/tests/fixtures/fail12.json +0 -1
  69. data/tests/fixtures/fail13.json +0 -1
  70. data/tests/fixtures/fail14.json +0 -1
  71. data/tests/fixtures/fail18.json +0 -1
  72. data/tests/fixtures/fail19.json +0 -1
  73. data/tests/fixtures/fail2.json +0 -1
  74. data/tests/fixtures/fail20.json +0 -1
  75. data/tests/fixtures/fail21.json +0 -1
  76. data/tests/fixtures/fail22.json +0 -1
  77. data/tests/fixtures/fail23.json +0 -1
  78. data/tests/fixtures/fail24.json +0 -1
  79. data/tests/fixtures/fail25.json +0 -1
  80. data/tests/fixtures/fail27.json +0 -2
  81. data/tests/fixtures/fail28.json +0 -2
  82. data/tests/fixtures/fail3.json +0 -1
  83. data/tests/fixtures/fail4.json +0 -1
  84. data/tests/fixtures/fail5.json +0 -1
  85. data/tests/fixtures/fail6.json +0 -1
  86. data/tests/fixtures/fail7.json +0 -1
  87. data/tests/fixtures/fail8.json +0 -1
  88. data/tests/fixtures/fail9.json +0 -1
  89. data/tests/fixtures/pass1.json +0 -56
  90. data/tests/fixtures/pass15.json +0 -1
  91. data/tests/fixtures/pass16.json +0 -1
  92. data/tests/fixtures/pass17.json +0 -1
  93. data/tests/fixtures/pass2.json +0 -1
  94. data/tests/fixtures/pass26.json +0 -1
  95. data/tests/fixtures/pass3.json +0 -6
  96. data/tests/setup_variant.rb +0 -11
  97. data/tests/test_json.rb +0 -519
  98. data/tests/test_json_addition.rb +0 -196
  99. data/tests/test_json_encoding.rb +0 -65
  100. data/tests/test_json_fixtures.rb +0 -35
  101. data/tests/test_json_generate.rb +0 -348
  102. data/tests/test_json_generic_object.rb +0 -75
  103. data/tests/test_json_string_matching.rb +0 -39
  104. data/tests/test_json_unicode.rb +0 -72
  105. data/tools/diff.sh +0 -18
  106. data/tools/fuzz.rb +0 -139
  107. data/tools/server.rb +0 -62
@@ -1,75 +0,0 @@
1
- #!/usr/bin/env ruby
2
- # encoding: utf-8
3
-
4
- require 'test/unit'
5
- require File.join(File.dirname(__FILE__), 'setup_variant')
6
- class TestJSONGenericObject < Test::Unit::TestCase
7
- include JSON
8
-
9
- def setup
10
- @go = GenericObject[ :a => 1, :b => 2 ]
11
- end
12
-
13
- def test_attributes
14
- assert_equal 1, @go.a
15
- assert_equal 1, @go[:a]
16
- assert_equal 2, @go.b
17
- assert_equal 2, @go[:b]
18
- assert_nil @go.c
19
- assert_nil @go[:c]
20
- end
21
-
22
- def test_generate_json
23
- switch_json_creatable do
24
- assert_equal @go, JSON(JSON(@go), :create_additions => true)
25
- end
26
- end
27
-
28
- def test_parse_json
29
- assert_kind_of Hash, JSON('{ "json_class": "JSON::GenericObject", "a": 1, "b": 2 }', :create_additions => true)
30
- switch_json_creatable do
31
- assert_equal @go, l = JSON('{ "json_class": "JSON::GenericObject", "a": 1, "b": 2 }', :create_additions => true)
32
- assert_equal 1, l.a
33
- assert_equal @go, l = JSON('{ "a": 1, "b": 2 }', :object_class => GenericObject)
34
- assert_equal 1, l.a
35
- assert_equal GenericObject[:a => GenericObject[:b => 2]],
36
- l = JSON('{ "a": { "b": 2 } }', :object_class => GenericObject)
37
- assert_equal 2, l.a.b
38
- end
39
- end
40
-
41
- def test_from_hash
42
- result = GenericObject.from_hash(
43
- :foo => { :bar => { :baz => true }, :quux => [ { :foobar => true } ] })
44
- assert_kind_of GenericObject, result.foo
45
- assert_kind_of GenericObject, result.foo.bar
46
- assert_equal true, result.foo.bar.baz
47
- assert_kind_of GenericObject, result.foo.quux.first
48
- assert_equal true, result.foo.quux.first.foobar
49
- assert_equal true, GenericObject.from_hash(true)
50
- end
51
-
52
- def test_json_generic_object_load
53
- empty = JSON::GenericObject.load(nil)
54
- assert_kind_of JSON::GenericObject, empty
55
- simple_json = '{"json_class":"JSON::GenericObject","hello":"world"}'
56
- simple = JSON::GenericObject.load(simple_json)
57
- assert_kind_of JSON::GenericObject, simple
58
- assert_equal "world", simple.hello
59
- converting = JSON::GenericObject.load('{ "hello": "world" }')
60
- assert_kind_of JSON::GenericObject, converting
61
- assert_equal "world", converting.hello
62
-
63
- json = JSON::GenericObject.dump(JSON::GenericObject[:hello => 'world'])
64
- assert_equal JSON(json), JSON('{"json_class":"JSON::GenericObject","hello":"world"}')
65
- end
66
-
67
- private
68
-
69
- def switch_json_creatable
70
- JSON::GenericObject.json_creatable = true
71
- yield
72
- ensure
73
- JSON::GenericObject.json_creatable = false
74
- end
75
- end
@@ -1,39 +0,0 @@
1
- #!/usr/bin/env ruby
2
- # encoding: utf-8
3
-
4
- require 'test/unit'
5
- require File.join(File.dirname(__FILE__), 'setup_variant')
6
- require 'stringio'
7
- require 'time'
8
-
9
- class TestJSONStringMatching < Test::Unit::TestCase
10
- include JSON
11
-
12
- class TestTime < ::Time
13
- def self.json_create(string)
14
- Time.parse(string)
15
- end
16
-
17
- def to_json(*)
18
- %{"#{strftime('%FT%T%z')}"}
19
- end
20
-
21
- def ==(other)
22
- to_i == other.to_i
23
- end
24
- end
25
-
26
- def test_match_date
27
- t = TestTime.new
28
- t_json = [ t ].to_json
29
- assert_equal [ t ],
30
- JSON.parse(t_json, :create_additions => true,
31
- :match_string => { /\A\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}[+-]\d{4}\z/ => TestTime })
32
- assert_equal [ t.strftime('%FT%T%z') ],
33
- JSON.parse(t_json, :create_additions => true,
34
- :match_string => { /\A\d{3}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}[+-]\d{4}\z/ => TestTime })
35
- assert_equal [ t.strftime('%FT%T%z') ],
36
- JSON.parse(t_json,
37
- :match_string => { /\A\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}[+-]\d{4}\z/ => TestTime })
38
- end
39
- end
@@ -1,72 +0,0 @@
1
- #!/usr/bin/env ruby
2
- # encoding: utf-8
3
-
4
- require 'test/unit'
5
- require File.join(File.dirname(__FILE__), 'setup_variant')
6
-
7
- class TestJSONUnicode < Test::Unit::TestCase
8
- include JSON
9
-
10
- def test_unicode
11
- assert_equal '""', ''.to_json
12
- assert_equal '"\\b"', "\b".to_json
13
- assert_equal '"\u0001"', 0x1.chr.to_json
14
- assert_equal '"\u001f"', 0x1f.chr.to_json
15
- assert_equal '" "', ' '.to_json
16
- assert_equal "\"#{0x7f.chr}\"", 0x7f.chr.to_json
17
- utf8 = [ "© ≠ €! \01" ]
18
- json = '["© ≠ €! \u0001"]'
19
- assert_equal json, utf8.to_json(:ascii_only => false)
20
- assert_equal utf8, parse(json)
21
- json = '["\u00a9 \u2260 \u20ac! \u0001"]'
22
- assert_equal json, utf8.to_json(:ascii_only => true)
23
- assert_equal utf8, parse(json)
24
- utf8 = ["\343\201\202\343\201\204\343\201\206\343\201\210\343\201\212"]
25
- json = "[\"\343\201\202\343\201\204\343\201\206\343\201\210\343\201\212\"]"
26
- assert_equal utf8, parse(json)
27
- assert_equal json, utf8.to_json(:ascii_only => false)
28
- utf8 = ["\343\201\202\343\201\204\343\201\206\343\201\210\343\201\212"]
29
- assert_equal utf8, parse(json)
30
- json = "[\"\\u3042\\u3044\\u3046\\u3048\\u304a\"]"
31
- assert_equal json, utf8.to_json(:ascii_only => true)
32
- assert_equal utf8, parse(json)
33
- utf8 = ['საქართველო']
34
- json = '["საქართველო"]'
35
- assert_equal json, utf8.to_json(:ascii_only => false)
36
- json = "[\"\\u10e1\\u10d0\\u10e5\\u10d0\\u10e0\\u10d7\\u10d5\\u10d4\\u10da\\u10dd\"]"
37
- assert_equal json, utf8.to_json(:ascii_only => true)
38
- assert_equal utf8, parse(json)
39
- assert_equal '["Ã"]', JSON.generate(["Ã"], :ascii_only => false)
40
- assert_equal '["\\u00c3"]', JSON.generate(["Ã"], :ascii_only => true)
41
- assert_equal ["€"], JSON.parse('["\u20ac"]')
42
- utf8 = ["\xf0\xa0\x80\x81"]
43
- json = "[\"\xf0\xa0\x80\x81\"]"
44
- assert_equal json, JSON.generate(utf8, :ascii_only => false)
45
- assert_equal utf8, JSON.parse(json)
46
- json = '["\ud840\udc01"]'
47
- assert_equal json, JSON.generate(utf8, :ascii_only => true)
48
- assert_equal utf8, JSON.parse(json)
49
- end
50
-
51
- def test_chars
52
- (0..0x7f).each do |i|
53
- json = '["\u%04x"]' % i
54
- if RUBY_VERSION >= "1.9."
55
- i = i.chr
56
- end
57
- assert_equal i, JSON.parse(json).first[0]
58
- if i == ?\b
59
- generated = JSON.generate(["" << i])
60
- assert '["\b"]' == generated || '["\10"]' == generated
61
- elsif [?\n, ?\r, ?\t, ?\f].include?(i)
62
- assert_equal '[' << ('' << i).dump << ']', JSON.generate(["" << i])
63
- elsif i.chr < 0x20.chr
64
- assert_equal json, JSON.generate(["" << i])
65
- end
66
- end
67
- assert_raise(JSON::GeneratorError) do
68
- JSON.generate(["\x80"], :ascii_only => true)
69
- end
70
- assert_equal "\302\200", JSON.parse('["\u0080"]').first
71
- end
72
- end
data/tools/diff.sh DELETED
@@ -1,18 +0,0 @@
1
- #!/bin/sh
2
-
3
- files=`find ext -name '*.[ch]' -o -name parser.rl`
4
-
5
- for f in $files
6
- do
7
- b=`basename $f`
8
- g=`find ../ruby/ext/json -name $b`
9
- d=`diff -u $f $g`
10
- test -z "$d" && continue
11
- echo "$d"
12
- read -p "Edit diff of $b? " a
13
- case $a in
14
- [yY]*)
15
- vimdiff $f $g
16
- ;;
17
- esac
18
- done
data/tools/fuzz.rb DELETED
@@ -1,139 +0,0 @@
1
- require 'json'
2
-
3
- require 'iconv'
4
- ISO_8859_1_TO_UTF8 = Iconv.new('utf-8', 'iso-8859-15')
5
- class ::String
6
- def to_utf8
7
- ISO_8859_1_TO_UTF8.iconv self
8
- end
9
- end
10
-
11
- class Fuzzer
12
- def initialize(n, freqs = {})
13
- sum = freqs.inject(0.0) { |s, x| s + x.last }
14
- freqs.each_key { |x| freqs[x] /= sum }
15
- s = 0.0
16
- freqs.each_key do |x|
17
- freqs[x] = s .. (s + t = freqs[x])
18
- s += t
19
- end
20
- @freqs = freqs
21
- @n = n
22
- @alpha = (0..0xff).to_a
23
- end
24
-
25
- def random_string
26
- s = ''
27
- 30.times { s << @alpha[rand(@alpha.size)] }
28
- s.to_utf8
29
- end
30
-
31
- def pick
32
- r = rand
33
- found = @freqs.find { |k, f| f.include? rand }
34
- found && found.first
35
- end
36
-
37
- def make_pick
38
- k = pick
39
- case
40
- when k == Hash, k == Array
41
- k.new
42
- when k == true, k == false, k == nil
43
- k
44
- when k == String
45
- random_string
46
- when k == Fixnum
47
- rand(2 ** 30) - 2 ** 29
48
- when k == Bignum
49
- rand(2 ** 70) - 2 ** 69
50
- end
51
- end
52
-
53
- def fuzz(current = nil)
54
- if @n > 0
55
- case current
56
- when nil
57
- @n -= 1
58
- current = fuzz [ Hash, Array ][rand(2)].new
59
- when Array
60
- while @n > 0
61
- @n -= 1
62
- current << case p = make_pick
63
- when Array, Hash
64
- fuzz(p)
65
- else
66
- p
67
- end
68
- end
69
- when Hash
70
- while @n > 0
71
- @n -= 1
72
- current[random_string] = case p = make_pick
73
- when Array, Hash
74
- fuzz(p)
75
- else
76
- p
77
- end
78
- end
79
- end
80
- end
81
- current
82
- end
83
- end
84
-
85
- class MyState < JSON.state
86
- WS = " \r\t\n"
87
-
88
- def initialize
89
- super(
90
- :indent => make_spaces,
91
- :space => make_spaces,
92
- :space_before => make_spaces,
93
- :object_nl => make_spaces,
94
- :array_nl => make_spaces,
95
- :max_nesting => false
96
- )
97
- end
98
-
99
- def make_spaces
100
- s = ''
101
- rand(1).times { s << WS[rand(WS.size)] }
102
- s
103
- end
104
- end
105
-
106
- n = (ARGV.shift || 500).to_i
107
- loop do
108
- fuzzer = Fuzzer.new(n,
109
- Hash => 25,
110
- Array => 25,
111
- String => 10,
112
- Fixnum => 10,
113
- Bignum => 10,
114
- nil => 5,
115
- true => 5,
116
- false => 5
117
- )
118
- o1 = fuzzer.fuzz
119
- json = JSON.generate o1, MyState.new
120
- if $DEBUG
121
- puts "-" * 80
122
- puts json, json.size
123
- else
124
- puts json.size
125
- end
126
- begin
127
- o2 = JSON.parse(json, :max_nesting => false)
128
- rescue JSON::ParserError => e
129
- puts "Caught #{e.class}: #{e.message}\n#{e.backtrace * "\n"}"
130
- puts "o1 = #{o1.inspect}", "json = #{json}", "json_str = #{json.inspect}"
131
- puts "locals = #{local_variables.inspect}"
132
- exit
133
- end
134
- if o1 != o2
135
- puts "mismatch", "o1 = #{o1.inspect}", "o2 = #{o2.inspect}",
136
- "json = #{json}", "json_str = #{json.inspect}"
137
- puts "locals = #{local_variables.inspect}"
138
- end
139
- end
data/tools/server.rb DELETED
@@ -1,62 +0,0 @@
1
- #!/usr/bin/env ruby
2
- # encoding: utf-8
3
-
4
- require 'webrick'
5
- include WEBrick
6
- $:.unshift 'ext'
7
- $:.unshift 'lib'
8
- require 'json'
9
-
10
- class JSONServlet < HTTPServlet::AbstractServlet
11
- @@count = 1
12
-
13
- def do_GET(req, res)
14
- obj = {
15
- "TIME" => Time.now.strftime("%FT%T"),
16
- "foo" => "Bär",
17
- "bar" => "© ≠ €!",
18
- 'a' => 2,
19
- 'b' => 3.141,
20
- 'COUNT' => @@count += 1,
21
- 'c' => 'c',
22
- 'd' => [ 1, "b", 3.14 ],
23
- 'e' => { 'foo' => 'bar' },
24
- 'g' => "松本行弘",
25
- 'h' => 1000.0,
26
- 'i' => 0.001,
27
- 'j' => "\xf0\xa0\x80\x81",
28
- }
29
- res.body = JSON.generate obj
30
- res['Content-Type'] = "application/json"
31
- end
32
- end
33
-
34
- def create_server(err, dir, port)
35
- dir = File.expand_path(dir)
36
- err.puts "Surf to:", "http://#{Socket.gethostname}:#{port}"
37
-
38
- s = HTTPServer.new(
39
- :Port => port,
40
- :DocumentRoot => dir,
41
- :Logger => WEBrick::Log.new(err),
42
- :AccessLog => [
43
- [ err, WEBrick::AccessLog::COMMON_LOG_FORMAT ],
44
- [ err, WEBrick::AccessLog::REFERER_LOG_FORMAT ],
45
- [ err, WEBrick::AccessLog::AGENT_LOG_FORMAT ]
46
- ]
47
- )
48
- s.mount("/json", JSONServlet)
49
- s
50
- end
51
-
52
- default_dir = File.expand_path(File.join(File.dirname(__FILE__), '..', 'data'))
53
- dir = ARGV.shift || default_dir
54
- port = (ARGV.shift || 6666).to_i
55
- s = create_server(STDERR, dir, 6666)
56
- t = Thread.new { s.start }
57
- trap(:INT) do
58
- s.shutdown
59
- t.join
60
- exit
61
- end
62
- sleep