json_pure 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
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
+