json_pure 1.0.0

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 (83) hide show
  1. data/CHANGES +25 -0
  2. data/GPL +340 -0
  3. data/README +77 -0
  4. data/Rakefile +250 -0
  5. data/TODO +1 -0
  6. data/VERSION +1 -0
  7. data/benchmarks/benchmark.txt +133 -0
  8. data/benchmarks/benchmark_generator.rb +44 -0
  9. data/benchmarks/benchmark_parser.rb +22 -0
  10. data/benchmarks/benchmark_rails.rb +26 -0
  11. data/bin/edit_json.rb +11 -0
  12. data/data/example.json +1 -0
  13. data/data/index.html +37 -0
  14. data/data/prototype.js +2515 -0
  15. data/ext/json/ext/generator/Makefile +149 -0
  16. data/ext/json/ext/generator/extconf.rb +9 -0
  17. data/ext/json/ext/generator/generator.c +729 -0
  18. data/ext/json/ext/generator/unicode.c +184 -0
  19. data/ext/json/ext/generator/unicode.h +40 -0
  20. data/ext/json/ext/parser/Makefile +149 -0
  21. data/ext/json/ext/parser/extconf.rb +9 -0
  22. data/ext/json/ext/parser/parser.c +1551 -0
  23. data/ext/json/ext/parser/parser.rl +515 -0
  24. data/ext/json/ext/parser/unicode.c +156 -0
  25. data/ext/json/ext/parser/unicode.h +44 -0
  26. data/install.rb +26 -0
  27. data/lib/json.rb +205 -0
  28. data/lib/json/Array.xpm +21 -0
  29. data/lib/json/FalseClass.xpm +21 -0
  30. data/lib/json/Hash.xpm +21 -0
  31. data/lib/json/Key.xpm +73 -0
  32. data/lib/json/NilClass.xpm +21 -0
  33. data/lib/json/Numeric.xpm +28 -0
  34. data/lib/json/String.xpm +96 -0
  35. data/lib/json/TrueClass.xpm +21 -0
  36. data/lib/json/common.rb +184 -0
  37. data/lib/json/editor.rb +1207 -0
  38. data/lib/json/ext.rb +13 -0
  39. data/lib/json/json.xpm +1499 -0
  40. data/lib/json/pure.rb +75 -0
  41. data/lib/json/pure/generator.rb +321 -0
  42. data/lib/json/pure/parser.rb +210 -0
  43. data/lib/json/version.rb +8 -0
  44. data/tests/fixtures/fail1.json +1 -0
  45. data/tests/fixtures/fail10.json +1 -0
  46. data/tests/fixtures/fail11.json +1 -0
  47. data/tests/fixtures/fail12.json +1 -0
  48. data/tests/fixtures/fail13.json +1 -0
  49. data/tests/fixtures/fail14.json +1 -0
  50. data/tests/fixtures/fail15.json +1 -0
  51. data/tests/fixtures/fail16.json +1 -0
  52. data/tests/fixtures/fail17.json +1 -0
  53. data/tests/fixtures/fail19.json +1 -0
  54. data/tests/fixtures/fail2.json +1 -0
  55. data/tests/fixtures/fail20.json +1 -0
  56. data/tests/fixtures/fail21.json +1 -0
  57. data/tests/fixtures/fail22.json +1 -0
  58. data/tests/fixtures/fail23.json +1 -0
  59. data/tests/fixtures/fail24.json +1 -0
  60. data/tests/fixtures/fail25.json +1 -0
  61. data/tests/fixtures/fail26.json +1 -0
  62. data/tests/fixtures/fail27.json +2 -0
  63. data/tests/fixtures/fail28.json +2 -0
  64. data/tests/fixtures/fail3.json +1 -0
  65. data/tests/fixtures/fail4.json +1 -0
  66. data/tests/fixtures/fail5.json +1 -0
  67. data/tests/fixtures/fail6.json +1 -0
  68. data/tests/fixtures/fail7.json +1 -0
  69. data/tests/fixtures/fail8.json +1 -0
  70. data/tests/fixtures/fail9.json +1 -0
  71. data/tests/fixtures/pass1.json +56 -0
  72. data/tests/fixtures/pass18.json +1 -0
  73. data/tests/fixtures/pass2.json +1 -0
  74. data/tests/fixtures/pass3.json +6 -0
  75. data/tests/runner.rb +24 -0
  76. data/tests/test_json.rb +235 -0
  77. data/tests/test_json_addition.rb +94 -0
  78. data/tests/test_json_fixtures.rb +30 -0
  79. data/tests/test_json_generate.rb +81 -0
  80. data/tests/test_json_unicode.rb +55 -0
  81. data/tools/fuzz.rb +133 -0
  82. data/tools/server.rb +62 -0
  83. metadata +146 -0
@@ -0,0 +1,30 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'test/unit'
4
+ require 'json'
5
+
6
+ class TC_JSONFixtures < Test::Unit::TestCase
7
+ def setup
8
+ $KCODE = 'UTF8'
9
+ fixtures = File.join(File.dirname(__FILE__), 'fixtures/*.json')
10
+ passed, failed = Dir[fixtures].partition { |f| f['pass'] }
11
+ @passed = passed.inject([]) { |a, f| a << [ f, File.read(f) ] }.sort
12
+ @failed = failed.inject([]) { |a, f| a << [ f, File.read(f) ] }.sort
13
+ end
14
+
15
+ def test_passing
16
+ for (name, source) in @passed
17
+ assert JSON.parse(source),
18
+ "Did not pass for fixture '#{name}'"
19
+ end
20
+ end
21
+
22
+ def test_failing
23
+ for (name, source) in @failed
24
+ assert_raises(JSON::ParserError,
25
+ "Did not fail for fixture '#{name}'") do
26
+ JSON.parse(source)
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,81 @@
1
+ require 'test/unit'
2
+ require 'json'
3
+
4
+ class TC_JSONGenerate < Test::Unit::TestCase
5
+ include JSON
6
+
7
+ def setup
8
+ $KCODE = 'UTF8'
9
+ @hash = {
10
+ 'a' => 2,
11
+ 'b' => 3.141,
12
+ 'c' => 'c',
13
+ 'd' => [ 1, "b", 3.14 ],
14
+ 'e' => { 'foo' => 'bar' },
15
+ 'g' => "\"\0\037",
16
+ 'h' => 1000.0,
17
+ 'i' => 0.001
18
+ }
19
+ @json2 = '{"a":2,"b":3.141,"c":"c","d":[1,"b",3.14],"e":{"foo":"bar"},' +
20
+ '"g":"\\"\\u0000\\u001f","h":1000.0,"i":0.001}'
21
+ @json3 = <<'EOT'.chomp
22
+ {
23
+ "a": 2,
24
+ "b": 3.141,
25
+ "c": "c",
26
+ "d": [
27
+ 1,
28
+ "b",
29
+ 3.14
30
+ ],
31
+ "e": {
32
+ "foo": "bar"
33
+ },
34
+ "g": "\"\u0000\u001f",
35
+ "h": 1000.0,
36
+ "i": 0.001
37
+ }
38
+ EOT
39
+ end
40
+
41
+ def test_unparse
42
+ json = unparse(@hash)
43
+ assert_equal(@json2, json)
44
+ parsed_json = parse(json)
45
+ assert_equal(@hash, parsed_json)
46
+ json = generate({1=>2})
47
+ assert_equal('{"1":2}', json)
48
+ parsed_json = parse(json)
49
+ assert_equal({"1"=>2}, parsed_json)
50
+ end
51
+
52
+ def test_unparse_pretty
53
+ json = pretty_unparse(@hash)
54
+ assert_equal(@json3, json)
55
+ parsed_json = parse(json)
56
+ assert_equal(@hash, parsed_json)
57
+ json = pretty_generate({1=>2})
58
+ assert_equal(<<'EOT'.chomp, json)
59
+ {
60
+ "1": 2
61
+ }
62
+ EOT
63
+ parsed_json = parse(json)
64
+ assert_equal({"1"=>2}, parsed_json)
65
+ end
66
+
67
+ def test_states
68
+ json = generate({1=>2}, nil)
69
+ assert_equal('{"1":2}', json)
70
+ s = JSON.state.new(:check_circular => true)
71
+ #assert s.check_circular
72
+ h = { 1=>2 }
73
+ h[3] = h
74
+ assert_raises(JSON::CircularDatastructure) { generate(h, s) }
75
+ s = JSON.state.new(:check_circular => true)
76
+ #assert s.check_circular
77
+ a = [ 1, 2 ]
78
+ a << a
79
+ assert_raises(JSON::CircularDatastructure) { generate(a, s) }
80
+ end
81
+ end
@@ -0,0 +1,55 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'test/unit'
4
+ require 'json'
5
+
6
+ class TC_JSONUnicode < Test::Unit::TestCase
7
+ include JSON
8
+
9
+ def setup
10
+ $KCODE = 'UTF8'
11
+ end
12
+
13
+ def test_unicode
14
+ assert_equal '""', ''.to_json
15
+ assert_equal '"\\b"', "\b".to_json
16
+ assert_equal '"\u0001"', 0x1.chr.to_json
17
+ assert_equal '"\u001f"', 0x1f.chr.to_json
18
+ assert_equal '" "', ' '.to_json
19
+ assert_equal "\"#{0x7f.chr}\"", 0x7f.chr.to_json
20
+ utf8 = [ "© ≠ €! \01" ]
21
+ json = '["\u00a9 \u2260 \u20ac! \u0001"]'
22
+ assert_equal json, utf8.to_json
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 = "[\"\\u3042\\u3044\\u3046\\u3048\\u304a\"]"
26
+ assert_equal json, utf8.to_json
27
+ assert_equal utf8, parse(json)
28
+ utf8 = ['საქართველო']
29
+ json = "[\"\\u10e1\\u10d0\\u10e5\\u10d0\\u10e0\\u10d7\\u10d5\\u10d4\\u10da\\u10dd\"]"
30
+ assert_equal json, utf8.to_json
31
+ assert_equal utf8, parse(json)
32
+ assert_equal '["\\u00c3"]', JSON.generate(["Ã"])
33
+ assert_equal ["€"], JSON.parse('["\u20ac"]')
34
+ utf8 = ["\xf0\xa0\x80\x81"]
35
+ json = '["\ud840\udc01"]'
36
+ assert_equal json, JSON.generate(utf8)
37
+ assert_equal utf8, JSON.parse(json)
38
+ end
39
+
40
+ def test_chars
41
+ (0..0x7f).each do |i|
42
+ json = '["\u%04x"]' % i
43
+ assert_equal i, JSON.parse(json).first[0]
44
+ if [?\b, ?\n, ?\r, ?\t, ?\f].include?(i)
45
+ assert_equal '[' << ('' << i).dump << ']', JSON.generate(["" << i])
46
+ elsif i < 0x20
47
+ assert_equal json, JSON.generate(["" << i])
48
+ end
49
+ end
50
+ assert_raises(JSON::GeneratorError) do
51
+ JSON.generate(["" << 0x80])
52
+ end
53
+ assert_equal "\302\200", JSON.parse('["\u0080"]').first
54
+ end
55
+ end
data/tools/fuzz.rb ADDED
@@ -0,0 +1,133 @@
1
+ $KCODE='UTF8'
2
+ require 'json'
3
+ require 'irb'
4
+ require 'pp'
5
+
6
+ class Fuzzer
7
+ def initialize(n, freqs = {})
8
+ sum = freqs.inject(0.0) { |s, x| s + x.last }
9
+ freqs.each_key { |x| freqs[x] /= sum }
10
+ s = 0.0
11
+ freqs.each_key do |x|
12
+ freqs[x] = s .. (s + t = freqs[x])
13
+ s += t
14
+ end
15
+ @freqs = freqs
16
+ @n = n
17
+ @alpha = (0..0x7f).to_a
18
+ end
19
+
20
+ def random_string
21
+ s = ''
22
+ 30.times { s << @alpha[rand(@alpha.size)] }
23
+ s
24
+ end
25
+
26
+ def pick
27
+ r = rand
28
+ found = @freqs.find { |k, f| f.include? rand }
29
+ found && found.first
30
+ end
31
+
32
+ def make_pick
33
+ k = pick
34
+ case
35
+ when k == Hash, k == Array
36
+ k.new
37
+ when k == true, k == false, k == nil
38
+ k
39
+ when k == String
40
+ random_string
41
+ when k == Fixnum
42
+ rand(2 ** 30) - 2 ** 29
43
+ when k == Bignum
44
+ rand(2 ** 70) - 2 ** 69
45
+ end
46
+ end
47
+
48
+ def fuzz(current = nil)
49
+ if @n > 0
50
+ case current
51
+ when nil
52
+ @n -= 1
53
+ current = fuzz [ Hash, Array ][rand(2)].new
54
+ when Array
55
+ while @n > 0
56
+ @n -= 1
57
+ current << case p = make_pick
58
+ when Array, Hash
59
+ fuzz(p)
60
+ else
61
+ p
62
+ end
63
+ end
64
+ when Hash
65
+ while @n > 0
66
+ @n -= 1
67
+ current[random_string] = case p = make_pick
68
+ when Array, Hash
69
+ fuzz(p)
70
+ else
71
+ p
72
+ end
73
+ end
74
+ end
75
+ end
76
+ current
77
+ end
78
+ end
79
+
80
+ class MyState < JSON.state
81
+ WS = " \r\t\n"
82
+
83
+ def initialize
84
+ super(
85
+ :indent => make_spaces,
86
+ :space => make_spaces,
87
+ :space_before => make_spaces,
88
+ :object_nl => make_spaces,
89
+ :array_nl => make_spaces
90
+ )
91
+ end
92
+
93
+ def make_spaces
94
+ s = ''
95
+ rand(1).times { s << WS[rand(WS.size)] }
96
+ s
97
+ end
98
+ end
99
+
100
+ n = (ARGV.shift || 500).to_i
101
+ loop do
102
+ fuzzer = Fuzzer.new(n,
103
+ Hash => 25,
104
+ Array => 25,
105
+ String => 10,
106
+ Fixnum => 10,
107
+ Bignum => 10,
108
+ nil => 5,
109
+ true => 5,
110
+ false => 5
111
+ )
112
+ o1 = fuzzer.fuzz
113
+ json = JSON.generate o1, MyState.new
114
+ if $DEBUG
115
+ puts "-" * 80
116
+ puts json, json.size
117
+ else
118
+ puts json.size
119
+ end
120
+ begin
121
+ o2 = JSON.parse(json)
122
+ rescue JSON::ParserError => e
123
+ puts "Caught #{e.class}: #{e.message}\n#{e.backtrace * "\n"}"
124
+ puts "o1 = #{o1.inspect}", "json = #{json}", "json_str = #{json.inspect}"
125
+ puts "locals = #{local_variables.inspect}"
126
+ exit
127
+ end
128
+ if o1 != o2
129
+ puts "mismatch", "o1 = #{o1.inspect}", "o2 = #{o2.inspect}",
130
+ "json = #{json}", "json_str = #{json.inspect}"
131
+ puts "locals = #{local_variables.inspect}"
132
+ end
133
+ end
data/tools/server.rb ADDED
@@ -0,0 +1,62 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ $KCODE='UTF8'
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
metadata ADDED
@@ -0,0 +1,146 @@
1
+ --- !ruby/object:Gem::Specification
2
+ rubygems_version: 0.9.2
3
+ specification_version: 1
4
+ name: json_pure
5
+ version: !ruby/object:Gem::Version
6
+ version: 1.0.0
7
+ date: 2007-03-27 00:00:00 +02:00
8
+ summary: A JSON implementation in Ruby
9
+ require_paths:
10
+ - lib
11
+ email: flori@ping.de
12
+ homepage: http://json.rubyforge.org
13
+ rubyforge_project: json
14
+ description: ""
15
+ autorequire:
16
+ default_executable: edit_json.rb
17
+ bindir: bin
18
+ has_rdoc: true
19
+ required_ruby_version: !ruby/object:Gem::Version::Requirement
20
+ requirements:
21
+ - - ">"
22
+ - !ruby/object:Gem::Version
23
+ version: 0.0.0
24
+ version:
25
+ platform: ruby
26
+ signing_key:
27
+ cert_chain:
28
+ post_install_message:
29
+ authors:
30
+ - Florian Frank
31
+ files:
32
+ - bin
33
+ - VERSION
34
+ - TODO
35
+ - tests
36
+ - GPL
37
+ - install.rb
38
+ - ext
39
+ - diagrams
40
+ - benchmarks
41
+ - Rakefile
42
+ - data
43
+ - lib
44
+ - README
45
+ - tools
46
+ - CHANGES
47
+ - bin/edit_json.rb
48
+ - tests/test_json_fixtures.rb
49
+ - tests/runner.rb
50
+ - tests/test_json.rb
51
+ - tests/fixtures
52
+ - tests/test_json_unicode.rb
53
+ - tests/test_json_generate.rb
54
+ - tests/test_json_addition.rb
55
+ - tests/fixtures/fail27.json
56
+ - tests/fixtures/fail22.json
57
+ - tests/fixtures/fail26.json
58
+ - tests/fixtures/fail16.json
59
+ - tests/fixtures/fail28.json
60
+ - tests/fixtures/fail25.json
61
+ - tests/fixtures/pass18.json
62
+ - tests/fixtures/fail9.json
63
+ - tests/fixtures/fail20.json
64
+ - tests/fixtures/fail24.json
65
+ - tests/fixtures/fail14.json
66
+ - tests/fixtures/fail4.json
67
+ - tests/fixtures/fail7.json
68
+ - tests/fixtures/fail10.json
69
+ - tests/fixtures/fail13.json
70
+ - tests/fixtures/fail6.json
71
+ - tests/fixtures/fail21.json
72
+ - tests/fixtures/fail23.json
73
+ - tests/fixtures/fail3.json
74
+ - tests/fixtures/fail1.json
75
+ - tests/fixtures/fail11.json
76
+ - tests/fixtures/fail5.json
77
+ - tests/fixtures/pass1.json
78
+ - tests/fixtures/fail12.json
79
+ - tests/fixtures/fail15.json
80
+ - tests/fixtures/pass3.json
81
+ - tests/fixtures/fail8.json
82
+ - tests/fixtures/fail17.json
83
+ - tests/fixtures/fail19.json
84
+ - tests/fixtures/pass2.json
85
+ - tests/fixtures/fail2.json
86
+ - ext/json
87
+ - ext/json/ext
88
+ - ext/json/ext/generator
89
+ - ext/json/ext/parser
90
+ - ext/json/ext/generator/Makefile
91
+ - ext/json/ext/generator/unicode.c
92
+ - ext/json/ext/generator/unicode.h
93
+ - ext/json/ext/generator/extconf.rb
94
+ - ext/json/ext/generator/generator.c
95
+ - ext/json/ext/parser/Makefile
96
+ - ext/json/ext/parser/parser.c
97
+ - ext/json/ext/parser/unicode.c
98
+ - ext/json/ext/parser/parser.rl
99
+ - ext/json/ext/parser/unicode.h
100
+ - ext/json/ext/parser/extconf.rb
101
+ - benchmarks/benchmark_generator.rb
102
+ - benchmarks/benchmark.txt
103
+ - benchmarks/benchmark_parser.rb
104
+ - benchmarks/benchmark_rails.rb
105
+ - data/example.json
106
+ - data/prototype.js
107
+ - data/index.html
108
+ - lib/json
109
+ - lib/json.rb
110
+ - lib/json/FalseClass.xpm
111
+ - lib/json/TrueClass.xpm
112
+ - lib/json/ext.rb
113
+ - lib/json/common.rb
114
+ - lib/json/Hash.xpm
115
+ - lib/json/pure
116
+ - lib/json/Key.xpm
117
+ - lib/json/Numeric.xpm
118
+ - lib/json/Array.xpm
119
+ - lib/json/editor.rb
120
+ - lib/json/String.xpm
121
+ - lib/json/pure.rb
122
+ - lib/json/NilClass.xpm
123
+ - lib/json/version.rb
124
+ - lib/json/json.xpm
125
+ - lib/json/pure/parser.rb
126
+ - lib/json/pure/generator.rb
127
+ - tools/server.rb
128
+ - tools/fuzz.rb
129
+ test_files:
130
+ - tests/runner.rb
131
+ rdoc_options:
132
+ - --title
133
+ - JSON -- A JSON implemention
134
+ - --main
135
+ - JSON
136
+ - --line-numbers
137
+ extra_rdoc_files: []
138
+
139
+ executables:
140
+ - edit_json.rb
141
+ extensions: []
142
+
143
+ requirements: []
144
+
145
+ dependencies: []
146
+