json 1.1.7 → 1.1.8
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of json might be problematic. Click here for more details.
- data/CHANGES +8 -0
- data/{RUBY → COPYING} +1 -1
- data/GPL +7 -7
- data/README +3 -3
- data/Rakefile +8 -13
- data/VERSION +1 -1
- data/benchmarks/generator_benchmark.rb +1 -1
- data/benchmarks/parser_benchmark.rb +1 -1
- data/doc-main.txt +283 -0
- data/ext/json/ext/generator/unicode.c +0 -2
- data/ext/json/ext/parser/parser.c +2 -2
- data/ext/json/ext/parser/parser.rl +2 -2
- data/lib/json/common.rb +2 -0
- data/lib/json/pure.rb +3 -3
- data/lib/json/pure/generator.rb +2 -3
- data/lib/json/pure/parser.rb +2 -2
- data/lib/json/version.rb +1 -1
- data/tests/test_json.rb +1 -1
- metadata +101 -85
- data/doc-templates/main.txt +0 -283
data/CHANGES
CHANGED
@@ -1,3 +1,11 @@
|
|
1
|
+
2009-08-23 (1.1.8)
|
2
|
+
* Applied a patch by OZAWA Sakuro <sakuro@2238club.org> to make json/pure
|
3
|
+
work in environments that don't provide iconv.
|
4
|
+
* Applied patch by okkez_ in order to fix Ruby Bug #1768:
|
5
|
+
http://redmine.ruby-lang.org/issues/show/1768.
|
6
|
+
* Finally got around to avoid the rather paranoid escaping of ?/ characters
|
7
|
+
in the generator's output. The parsers aren't affected by this change.
|
8
|
+
Thanks to Rich Apodaca <rapodaca@metamolecular.com> for the suggestion.
|
1
9
|
2009-06-29 (1.1.7)
|
2
10
|
* Security Fix for JSON::Pure::Parser. A specially designed string could
|
3
11
|
cause catastrophic backtracking in one of the parser's regular expressions
|
data/{RUBY → COPYING}
RENAMED
@@ -1,6 +1,6 @@
|
|
1
1
|
Ruby is copyrighted free software by Yukihiro Matsumoto <matz@netlab.co.jp>.
|
2
2
|
You can redistribute it and/or modify it under either the terms of the GPL
|
3
|
-
(see
|
3
|
+
(see GPL file), or the conditions below:
|
4
4
|
|
5
5
|
1. You may make and give away verbatim copies of the source form of the
|
6
6
|
software without restriction, provided that you duplicate all of the
|
data/GPL
CHANGED
@@ -1,12 +1,12 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
GNU GENERAL PUBLIC LICENSE
|
2
|
+
Version 2, June 1991
|
3
3
|
|
4
4
|
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
|
5
5
|
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
6
6
|
Everyone is permitted to copy and distribute verbatim copies
|
7
7
|
of this license document, but changing it is not allowed.
|
8
8
|
|
9
|
-
|
9
|
+
Preamble
|
10
10
|
|
11
11
|
The licenses for most software are designed to take away your
|
12
12
|
freedom to share and change it. By contrast, the GNU General Public
|
@@ -56,7 +56,7 @@ patent must be licensed for everyone's free use or not licensed at all.
|
|
56
56
|
The precise terms and conditions for copying, distribution and
|
57
57
|
modification follow.
|
58
58
|
|
59
|
-
|
59
|
+
GNU GENERAL PUBLIC LICENSE
|
60
60
|
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
61
61
|
|
62
62
|
0. This License applies to any program or other work which contains
|
@@ -255,7 +255,7 @@ make exceptions for this. Our decision will be guided by the two goals
|
|
255
255
|
of preserving the free status of all derivatives of our free software and
|
256
256
|
of promoting the sharing and reuse of software generally.
|
257
257
|
|
258
|
-
|
258
|
+
NO WARRANTY
|
259
259
|
|
260
260
|
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
261
261
|
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
@@ -277,9 +277,9 @@ YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
|
277
277
|
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
278
278
|
POSSIBILITY OF SUCH DAMAGES.
|
279
279
|
|
280
|
-
|
280
|
+
END OF TERMS AND CONDITIONS
|
281
281
|
|
282
|
-
|
282
|
+
How to Apply These Terms to Your New Programs
|
283
283
|
|
284
284
|
If you develop a new program, and you want it to be of the greatest
|
285
285
|
possible use to the public, the best way to achieve this is to make it
|
data/README
CHANGED
@@ -73,6 +73,6 @@ Florian Frank <flori@ping.de>
|
|
73
73
|
License
|
74
74
|
=======
|
75
75
|
|
76
|
-
Ruby License, see the
|
77
|
-
License includes the GNU General Public License (GPL), Version 2, so see
|
78
|
-
file GPL as well.
|
76
|
+
Ruby License, see the COPYING file included in the source distribution. The
|
77
|
+
Ruby License includes the GNU General Public License (GPL), Version 2, so see
|
78
|
+
the file GPL as well.
|
data/Rakefile
CHANGED
@@ -4,10 +4,12 @@ begin
|
|
4
4
|
rescue LoadError
|
5
5
|
end
|
6
6
|
require 'rake/clean'
|
7
|
+
CLOBBER.include Dir['benchmarks/data/*.{dat,log}']
|
7
8
|
|
8
9
|
require 'rbconfig'
|
9
10
|
include Config
|
10
11
|
|
12
|
+
MAKE = ENV['MAKE'] || %w[gmake make].find { |c| system(c, '-v') }
|
11
13
|
PKG_NAME = 'json'
|
12
14
|
PKG_VERSION = File.read('VERSION').chomp
|
13
15
|
PKG_FILES = FileList["**/*"].exclude(/CVS|pkg|tmp|coverage|Makefile/).exclude(/\.(so|bundle|o|#{CONFIG['DLEXT']})$/)
|
@@ -54,7 +56,7 @@ task :compile_ext => [ EXT_PARSER_DL, EXT_GENERATOR_DL ]
|
|
54
56
|
file EXT_PARSER_DL => EXT_PARSER_SRC do
|
55
57
|
cd EXT_PARSER_DIR do
|
56
58
|
ruby 'extconf.rb'
|
57
|
-
system
|
59
|
+
system MAKE
|
58
60
|
end
|
59
61
|
cp "#{EXT_PARSER_DIR}/parser.#{CONFIG['DLEXT']}", EXT_ROOT_DIR
|
60
62
|
end
|
@@ -62,7 +64,7 @@ end
|
|
62
64
|
file EXT_GENERATOR_DL => EXT_GENERATOR_SRC do
|
63
65
|
cd EXT_GENERATOR_DIR do
|
64
66
|
ruby 'extconf.rb'
|
65
|
-
system
|
67
|
+
system MAKE
|
66
68
|
end
|
67
69
|
cp "#{EXT_GENERATOR_DIR}/generator.#{CONFIG['DLEXT']}", EXT_ROOT_DIR
|
68
70
|
end
|
@@ -147,14 +149,9 @@ end
|
|
147
149
|
desc "Benchmarking library"
|
148
150
|
task :benchmark => [ :benchmark_parser, :benchmark_generator ]
|
149
151
|
|
150
|
-
desc "Clean benchmark data"
|
151
|
-
task :clean_benchmark_data do
|
152
|
-
rm_rf Dir['benchmarks/data/*.{dat,log}']
|
153
|
-
end
|
154
|
-
|
155
152
|
desc "Create RDOC documentation"
|
156
153
|
task :doc => [ :version, EXT_PARSER_SRC ] do
|
157
|
-
system "rdoc -
|
154
|
+
system "rdoc -o doc -m doc-main.txt doc-main.txt lib/json.rb #{FileList['lib/json/**/*.rb']} #{EXT_PARSER_SRC} #{EXT_GENERATOR_SRC}"
|
158
155
|
end
|
159
156
|
|
160
157
|
if defined?(Gem) and defined?(Rake::GemPackageTask) and defined?(Rake::ExtensionTask)
|
@@ -174,8 +171,7 @@ if defined?(Gem) and defined?(Rake::GemPackageTask) and defined?(Rake::Extension
|
|
174
171
|
|
175
172
|
s.has_rdoc = true
|
176
173
|
s.rdoc_options <<
|
177
|
-
'--title' << 'JSON -- A JSON implemention' <<
|
178
|
-
'--main' << 'JSON' << '--line-numbers'
|
174
|
+
'--title' << 'JSON -- A JSON implemention' << '--main' << 'doc-main.txt'
|
179
175
|
s.test_files.concat Dir['tests/*.rb']
|
180
176
|
|
181
177
|
s.author = "Florian Frank"
|
@@ -209,8 +205,7 @@ if defined?(Gem) and defined?(Rake::GemPackageTask) and defined?(Rake::Extension
|
|
209
205
|
|
210
206
|
s.has_rdoc = true
|
211
207
|
s.rdoc_options <<
|
212
|
-
'--title' << 'JSON -- A JSON implemention' <<
|
213
|
-
'--main' << 'JSON' << '--line-numbers'
|
208
|
+
'--title' << 'JSON -- A JSON implemention' << '--main' << 'doc-main.txt'
|
214
209
|
s.test_files.concat Dir['tests/*.rb']
|
215
210
|
|
216
211
|
s.author = "Florian Frank"
|
@@ -260,11 +255,11 @@ EOT
|
|
260
255
|
end
|
261
256
|
end
|
262
257
|
|
263
|
-
# TODO task :release => [ :version, :clean, :package_win ]
|
264
258
|
desc "Build all gems and archives for a new release."
|
265
259
|
task :release => [ :clean, :version, :cross, :native, :gem ] do
|
266
260
|
system "#$0 clean native gem"
|
267
261
|
system "#$0 clean package"
|
268
262
|
end
|
269
263
|
|
264
|
+
desc "Compile in the the source directory"
|
270
265
|
task :default => [ :version, :compile_ext ]
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
1.1.
|
1
|
+
1.1.8
|
@@ -147,7 +147,7 @@ if $0 == __FILE__
|
|
147
147
|
system "#{RAKE_PATH} clean"
|
148
148
|
system "#{RUBY_PATH} #$0 rails"
|
149
149
|
system "#{RUBY_PATH} #$0 pure"
|
150
|
-
system "#{RAKE_PATH}
|
150
|
+
system "#{RAKE_PATH} compile_ext"
|
151
151
|
system "#{RUBY_PATH} #$0 ext"
|
152
152
|
Bullshit.compare do
|
153
153
|
output_filename File.join(File.dirname(__FILE__), 'data', 'GeneratorBenchmarkComparison.log')
|
@@ -183,7 +183,7 @@ if $0 == __FILE__
|
|
183
183
|
system "#{RUBY_PATH} #$0 yaml"
|
184
184
|
system "#{RUBY_PATH} #$0 rails"
|
185
185
|
system "#{RUBY_PATH} #$0 pure"
|
186
|
-
system "#{RAKE_PATH}
|
186
|
+
system "#{RAKE_PATH} compile_ext"
|
187
187
|
system "#{RUBY_PATH} #$0 ext"
|
188
188
|
Bullshit.compare do
|
189
189
|
output_filename File.join(File.dirname(__FILE__), 'data', 'ParserBenchmarkComparison.log')
|
data/doc-main.txt
ADDED
@@ -0,0 +1,283 @@
|
|
1
|
+
== json - JSON Implementation for Ruby
|
2
|
+
|
3
|
+
=== Description
|
4
|
+
|
5
|
+
This is a implementation of the JSON specification according to RFC 4627
|
6
|
+
(http://www.ietf.org/rfc/rfc4627.txt). Starting from version 1.0.0 on there
|
7
|
+
will be two variants available:
|
8
|
+
|
9
|
+
* A pure ruby variant, that relies on the iconv and the stringscan
|
10
|
+
extensions, which are both part of the ruby standard library.
|
11
|
+
* The quite a bit faster C extension variant, which is in parts implemented
|
12
|
+
in C and comes with its own unicode conversion functions and a parser
|
13
|
+
generated by the ragel state machine compiler
|
14
|
+
(http://www.cs.queensu.ca/~thurston/ragel).
|
15
|
+
|
16
|
+
Both variants of the JSON generator escape all non-ASCII an control
|
17
|
+
characters with \uXXXX escape sequences, and support UTF-16 surrogate pairs
|
18
|
+
in order to be able to generate the whole range of unicode code points. This
|
19
|
+
means that generated JSON text is encoded as UTF-8 (because ASCII is a subset
|
20
|
+
of UTF-8) and at the same time avoids decoding problems for receiving
|
21
|
+
endpoints, that don't expect UTF-8 encoded texts. On the negative side this
|
22
|
+
may lead to a bit longer strings than necessarry.
|
23
|
+
|
24
|
+
All strings, that are to be encoded as JSON strings, should be UTF-8 byte
|
25
|
+
sequences on the Ruby side. To encode raw binary strings, that aren't UTF-8
|
26
|
+
encoded, please use the to_json_raw_object method of String (which produces
|
27
|
+
an object, that contains a byte array) and decode the result on the receiving
|
28
|
+
endpoint.
|
29
|
+
|
30
|
+
=== Author
|
31
|
+
|
32
|
+
Florian Frank <mailto:flori@ping.de>
|
33
|
+
|
34
|
+
=== License
|
35
|
+
|
36
|
+
This software is distributed under the same license as Ruby itself, see
|
37
|
+
http://www.ruby-lang.org/en/LICENSE.txt.
|
38
|
+
|
39
|
+
=== Download
|
40
|
+
|
41
|
+
The latest version of this library can be downloaded at
|
42
|
+
|
43
|
+
* http://rubyforge.org/frs?group_id=953
|
44
|
+
|
45
|
+
Online Documentation should be located at
|
46
|
+
|
47
|
+
* http://json.rubyforge.org
|
48
|
+
|
49
|
+
=== Usage
|
50
|
+
|
51
|
+
To use JSON you can
|
52
|
+
require 'json'
|
53
|
+
to load the installed variant (either the extension 'json' or the pure
|
54
|
+
variant 'json_pure'). If you have installed the extension variant, you can
|
55
|
+
pick either the extension variant or the pure variant by typing
|
56
|
+
require 'json/ext'
|
57
|
+
or
|
58
|
+
require 'json/pure'
|
59
|
+
|
60
|
+
You can choose to load a set of common additions to ruby core's objects if
|
61
|
+
you
|
62
|
+
require 'json/add/core'
|
63
|
+
|
64
|
+
After requiring this you can, e. g., serialise/deserialise Ruby ranges:
|
65
|
+
|
66
|
+
JSON JSON(1..10) # => 1..10
|
67
|
+
|
68
|
+
To find out how to add JSON support to other or your own classes, read the
|
69
|
+
Examples section below.
|
70
|
+
|
71
|
+
To get the best compatibility to rails' JSON implementation, you can
|
72
|
+
require 'json/add/rails'
|
73
|
+
|
74
|
+
Both of the additions attempt to require 'json' (like above) first, if it has
|
75
|
+
not been required yet.
|
76
|
+
|
77
|
+
=== Speed Comparisons
|
78
|
+
|
79
|
+
I have created some benchmark results (see the benchmarks/data-p4-3Ghz
|
80
|
+
subdir of the package) for the JSON-parser to estimate the speed up in the C
|
81
|
+
extension:
|
82
|
+
|
83
|
+
Comparing times (call_time_mean):
|
84
|
+
1 ParserBenchmarkExt#parser 900 repeats:
|
85
|
+
553.922304770 ( real) -> 21.500x
|
86
|
+
0.001805307
|
87
|
+
2 ParserBenchmarkYAML#parser 1000 repeats:
|
88
|
+
224.513358139 ( real) -> 8.714x
|
89
|
+
0.004454078
|
90
|
+
3 ParserBenchmarkPure#parser 1000 repeats:
|
91
|
+
26.755020642 ( real) -> 1.038x
|
92
|
+
0.037376163
|
93
|
+
4 ParserBenchmarkRails#parser 1000 repeats:
|
94
|
+
25.763381731 ( real) -> 1.000x
|
95
|
+
0.038814780
|
96
|
+
calls/sec ( time) -> speed covers
|
97
|
+
secs/call
|
98
|
+
|
99
|
+
In the table above 1 is JSON::Ext::Parser, 2 is YAML.load with YAML
|
100
|
+
compatbile JSON document, 3 is is JSON::Pure::Parser, and 4 is
|
101
|
+
ActiveSupport::JSON.decode. The ActiveSupport JSON-decoder converts the
|
102
|
+
input first to YAML and then uses the YAML-parser, the conversion seems to
|
103
|
+
slow it down so much that it is only as fast as the JSON::Pure::Parser!
|
104
|
+
|
105
|
+
If you look at the benchmark data you can see that this is mostly caused by
|
106
|
+
the frequent high outliers - the median of the Rails-parser runs is still
|
107
|
+
overall smaller than the median of the JSON::Pure::Parser runs:
|
108
|
+
|
109
|
+
Comparing times (call_time_median):
|
110
|
+
1 ParserBenchmarkExt#parser 900 repeats:
|
111
|
+
800.592479481 ( real) -> 26.936x
|
112
|
+
0.001249075
|
113
|
+
2 ParserBenchmarkYAML#parser 1000 repeats:
|
114
|
+
271.002390644 ( real) -> 9.118x
|
115
|
+
0.003690004
|
116
|
+
3 ParserBenchmarkRails#parser 1000 repeats:
|
117
|
+
30.227910865 ( real) -> 1.017x
|
118
|
+
0.033082008
|
119
|
+
4 ParserBenchmarkPure#parser 1000 repeats:
|
120
|
+
29.722384421 ( real) -> 1.000x
|
121
|
+
0.033644676
|
122
|
+
calls/sec ( time) -> speed covers
|
123
|
+
secs/call
|
124
|
+
|
125
|
+
I have benchmarked the JSON-Generator as well. This generated a few more
|
126
|
+
values, because there are different modes that also influence the achieved
|
127
|
+
speed:
|
128
|
+
|
129
|
+
Comparing times (call_time_mean):
|
130
|
+
1 GeneratorBenchmarkExt#generator_fast 1000 repeats:
|
131
|
+
547.354332608 ( real) -> 15.090x
|
132
|
+
0.001826970
|
133
|
+
2 GeneratorBenchmarkExt#generator_safe 1000 repeats:
|
134
|
+
443.968212317 ( real) -> 12.240x
|
135
|
+
0.002252414
|
136
|
+
3 GeneratorBenchmarkExt#generator_pretty 900 repeats:
|
137
|
+
375.104545883 ( real) -> 10.341x
|
138
|
+
0.002665923
|
139
|
+
4 GeneratorBenchmarkPure#generator_fast 1000 repeats:
|
140
|
+
49.978706968 ( real) -> 1.378x
|
141
|
+
0.020008521
|
142
|
+
5 GeneratorBenchmarkRails#generator 1000 repeats:
|
143
|
+
38.531868759 ( real) -> 1.062x
|
144
|
+
0.025952543
|
145
|
+
6 GeneratorBenchmarkPure#generator_safe 1000 repeats:
|
146
|
+
36.927649925 ( real) -> 1.018x 7 (>=3859)
|
147
|
+
0.027079979
|
148
|
+
7 GeneratorBenchmarkPure#generator_pretty 1000 repeats:
|
149
|
+
36.272134441 ( real) -> 1.000x 6 (>=3859)
|
150
|
+
0.027569373
|
151
|
+
calls/sec ( time) -> speed covers
|
152
|
+
secs/call
|
153
|
+
|
154
|
+
In the table above 1-3 are JSON::Ext::Generator methods. 4, 6, and 7 are
|
155
|
+
JSON::Pure::Generator methods and 5 is the Rails JSON generator. It is now a
|
156
|
+
bit faster than the generator_safe and generator_pretty methods of the pure
|
157
|
+
variant but slower than the others.
|
158
|
+
|
159
|
+
To achieve the fastest JSON text output, you can use the fast_generate
|
160
|
+
method. Beware, that this will disable the checking for circular Ruby data
|
161
|
+
structures, which may cause JSON to go into an infinite loop.
|
162
|
+
|
163
|
+
Here are the median comparisons for completeness' sake:
|
164
|
+
|
165
|
+
Comparing times (call_time_median):
|
166
|
+
1 GeneratorBenchmarkExt#generator_fast 1000 repeats:
|
167
|
+
708.258020939 ( real) -> 16.547x
|
168
|
+
0.001411915
|
169
|
+
2 GeneratorBenchmarkExt#generator_safe 1000 repeats:
|
170
|
+
569.105020353 ( real) -> 13.296x
|
171
|
+
0.001757145
|
172
|
+
3 GeneratorBenchmarkExt#generator_pretty 900 repeats:
|
173
|
+
482.825371244 ( real) -> 11.280x
|
174
|
+
0.002071142
|
175
|
+
4 GeneratorBenchmarkPure#generator_fast 1000 repeats:
|
176
|
+
62.717626652 ( real) -> 1.465x
|
177
|
+
0.015944481
|
178
|
+
5 GeneratorBenchmarkRails#generator 1000 repeats:
|
179
|
+
43.965681162 ( real) -> 1.027x
|
180
|
+
0.022745013
|
181
|
+
6 GeneratorBenchmarkPure#generator_safe 1000 repeats:
|
182
|
+
43.929073409 ( real) -> 1.026x 7 (>=3859)
|
183
|
+
0.022763968
|
184
|
+
7 GeneratorBenchmarkPure#generator_pretty 1000 repeats:
|
185
|
+
42.802514491 ( real) -> 1.000x 6 (>=3859)
|
186
|
+
0.023363113
|
187
|
+
calls/sec ( time) -> speed covers
|
188
|
+
secs/call
|
189
|
+
|
190
|
+
=== Examples
|
191
|
+
|
192
|
+
To create a JSON text from a ruby data structure, you can call JSON.generate
|
193
|
+
like that:
|
194
|
+
|
195
|
+
json = JSON.generate [1, 2, {"a"=>3.141}, false, true, nil, 4..10]
|
196
|
+
# => "[1,2,{\"a\":3.141},false,true,null,\"4..10\"]"
|
197
|
+
|
198
|
+
To create a valid JSON text you have to make sure, that the output is
|
199
|
+
embedded in either a JSON array [] or a JSON object {}. The easiest way to do
|
200
|
+
this, is by putting your values in a Ruby Array or Hash instance.
|
201
|
+
|
202
|
+
To get back a ruby data structure from a JSON text, you have to call
|
203
|
+
JSON.parse on it:
|
204
|
+
|
205
|
+
JSON.parse json
|
206
|
+
# => [1, 2, {"a"=>3.141}, false, true, nil, "4..10"]
|
207
|
+
|
208
|
+
Note, that the range from the original data structure is a simple
|
209
|
+
string now. The reason for this is, that JSON doesn't support ranges
|
210
|
+
or arbitrary classes. In this case the json library falls back to call
|
211
|
+
Object#to_json, which is the same as #to_s.to_json.
|
212
|
+
|
213
|
+
It's possible to add JSON support serialization to arbitrary classes by
|
214
|
+
simply implementing a more specialized version of the #to_json method, that
|
215
|
+
should return a JSON object (a hash converted to JSON with #to_json) like
|
216
|
+
this (don't forget the *a for all the arguments):
|
217
|
+
|
218
|
+
class Range
|
219
|
+
def to_json(*a)
|
220
|
+
{
|
221
|
+
'json_class' => self.class.name, # = 'Range'
|
222
|
+
'data' => [ first, last, exclude_end? ]
|
223
|
+
}.to_json(*a)
|
224
|
+
end
|
225
|
+
end
|
226
|
+
|
227
|
+
The hash key 'json_class' is the class, that will be asked to deserialise the
|
228
|
+
JSON representation later. In this case it's 'Range', but any namespace of
|
229
|
+
the form 'A::B' or '::A::B' will do. All other keys are arbitrary and can be
|
230
|
+
used to store the necessary data to configure the object to be deserialised.
|
231
|
+
|
232
|
+
If a the key 'json_class' is found in a JSON object, the JSON parser checks
|
233
|
+
if the given class responds to the json_create class method. If so, it is
|
234
|
+
called with the JSON object converted to a Ruby hash. So a range can
|
235
|
+
be deserialised by implementing Range.json_create like this:
|
236
|
+
|
237
|
+
class Range
|
238
|
+
def self.json_create(o)
|
239
|
+
new(*o['data'])
|
240
|
+
end
|
241
|
+
end
|
242
|
+
|
243
|
+
Now it possible to serialise/deserialise ranges as well:
|
244
|
+
|
245
|
+
json = JSON.generate [1, 2, {"a"=>3.141}, false, true, nil, 4..10]
|
246
|
+
# => "[1,2,{\"a\":3.141},false,true,null,{\"json_class\":\"Range\",\"data\":[4,10,false]}]"
|
247
|
+
JSON.parse json
|
248
|
+
# => [1, 2, {"a"=>3.141}, false, true, nil, 4..10]
|
249
|
+
|
250
|
+
JSON.generate always creates the shortest possible string representation of a
|
251
|
+
ruby data structure in one line. This good for data storage or network
|
252
|
+
protocols, but not so good for humans to read. Fortunately there's also
|
253
|
+
JSON.pretty_generate (or JSON.pretty_generate) that creates a more
|
254
|
+
readable output:
|
255
|
+
|
256
|
+
puts JSON.pretty_generate([1, 2, {"a"=>3.141}, false, true, nil, 4..10])
|
257
|
+
[
|
258
|
+
1,
|
259
|
+
2,
|
260
|
+
{
|
261
|
+
"a": 3.141
|
262
|
+
},
|
263
|
+
false,
|
264
|
+
true,
|
265
|
+
null,
|
266
|
+
{
|
267
|
+
"json_class": "Range",
|
268
|
+
"data": [
|
269
|
+
4,
|
270
|
+
10,
|
271
|
+
false
|
272
|
+
]
|
273
|
+
}
|
274
|
+
]
|
275
|
+
|
276
|
+
There are also the methods Kernel#j for generate, and Kernel#jj for
|
277
|
+
pretty_generate output to the console, that work analogous to Core Ruby's p
|
278
|
+
and the pp library's pp methods.
|
279
|
+
|
280
|
+
The script tools/server.rb contains a small example if you want to test, how
|
281
|
+
receiving a JSON object from a webrick server in your browser with the
|
282
|
+
javasript prototype library (http://www.prototypejs.org) works.
|
283
|
+
|
@@ -144,8 +144,6 @@ void JSON_convert_UTF8_to_JSON(VALUE buffer, VALUE string, ConversionFlags flags
|
|
144
144
|
rb_str_buf_cat2(buffer, "\\\"");
|
145
145
|
} else if (ch == '\\') {
|
146
146
|
rb_str_buf_cat2(buffer, "\\\\");
|
147
|
-
} else if (ch == '/') {
|
148
|
-
rb_str_buf_cat2(buffer, "\\/");
|
149
147
|
} else if (ch >= 0x20 && ch <= 0x7f) {
|
150
148
|
rb_str_buf_cat(buffer, (char *) source - 1, 1);
|
151
149
|
} else if (ch == '\n') {
|
@@ -80,7 +80,7 @@ static char *JSON_parse_object(JSON_Parser *json, char *p, char *pe, VALUE *resu
|
|
80
80
|
VALUE object_class = json->object_class;
|
81
81
|
|
82
82
|
if (json->max_nesting && json->current_nesting > json->max_nesting) {
|
83
|
-
rb_raise(eNestingError, "nesting of %d is
|
83
|
+
rb_raise(eNestingError, "nesting of %d is too deep", json->current_nesting);
|
84
84
|
}
|
85
85
|
|
86
86
|
*result = NIL_P(object_class) ? rb_hash_new() : rb_class_new_instance(0, 0, object_class);
|
@@ -1012,7 +1012,7 @@ static char *JSON_parse_array(JSON_Parser *json, char *p, char *pe, VALUE *resul
|
|
1012
1012
|
VALUE array_class = json->array_class;
|
1013
1013
|
|
1014
1014
|
if (json->max_nesting && json->current_nesting > json->max_nesting) {
|
1015
|
-
rb_raise(eNestingError, "nesting of %d is
|
1015
|
+
rb_raise(eNestingError, "nesting of %d is too deep", json->current_nesting);
|
1016
1016
|
}
|
1017
1017
|
*result = NIL_P(array_class) ? rb_ary_new() : rb_class_new_instance(0, 0, array_class);
|
1018
1018
|
|
@@ -123,7 +123,7 @@ static char *JSON_parse_object(JSON_Parser *json, char *p, char *pe, VALUE *resu
|
|
123
123
|
VALUE object_class = json->object_class;
|
124
124
|
|
125
125
|
if (json->max_nesting && json->current_nesting > json->max_nesting) {
|
126
|
-
rb_raise(eNestingError, "nesting of %d is
|
126
|
+
rb_raise(eNestingError, "nesting of %d is too deep", json->current_nesting);
|
127
127
|
}
|
128
128
|
|
129
129
|
*result = NIL_P(object_class) ? rb_hash_new() : rb_class_new_instance(0, 0, object_class);
|
@@ -336,7 +336,7 @@ static char *JSON_parse_array(JSON_Parser *json, char *p, char *pe, VALUE *resul
|
|
336
336
|
VALUE array_class = json->array_class;
|
337
337
|
|
338
338
|
if (json->max_nesting && json->current_nesting > json->max_nesting) {
|
339
|
-
rb_raise(eNestingError, "nesting of %d is
|
339
|
+
rb_raise(eNestingError, "nesting of %d is too deep", json->current_nesting);
|
340
340
|
}
|
341
341
|
*result = NIL_P(array_class) ? rb_ary_new() : rb_class_new_instance(0, 0, array_class);
|
342
342
|
|
data/lib/json/common.rb
CHANGED
data/lib/json/pure.rb
CHANGED
@@ -10,6 +10,9 @@ module JSON
|
|
10
10
|
# An iconv instance to convert from UTF16 Big Endian to UTF8.
|
11
11
|
UTF8toUTF16 = Iconv.new('utf-16be', 'utf-8') # :nodoc:
|
12
12
|
UTF8toUTF16.iconv('no bom')
|
13
|
+
rescue LoadError
|
14
|
+
raise MissingUnicodeSupport,
|
15
|
+
"iconv couldn't be loaded, which is required for UTF-8/UTF-16 conversions"
|
13
16
|
rescue Errno::EINVAL, Iconv::InvalidEncoding
|
14
17
|
# Iconv doesn't support big endian utf-16. Let's try to hack this manually
|
15
18
|
# into the converters.
|
@@ -51,9 +54,6 @@ module JSON
|
|
51
54
|
ensure
|
52
55
|
$VERBOSE = old_verbose
|
53
56
|
end
|
54
|
-
rescue LoadError
|
55
|
-
raise MissingUnicodeSupport,
|
56
|
-
"iconv couldn't be loaded, which is required for UTF-8/UTF-16 conversions"
|
57
57
|
end
|
58
58
|
|
59
59
|
# Swap consecutive bytes of _string_ in place.
|
data/lib/json/pure/generator.rb
CHANGED
@@ -34,7 +34,6 @@ module JSON
|
|
34
34
|
"\x1f" => '\u001f',
|
35
35
|
'"' => '\"',
|
36
36
|
'\\' => '\\\\',
|
37
|
-
'/' => '\/',
|
38
37
|
} # :nodoc:
|
39
38
|
|
40
39
|
# Convert a UTF8 encoded Ruby string _string_ to a JSON string, encoded with
|
@@ -44,7 +43,7 @@ module JSON
|
|
44
43
|
string = string.dup
|
45
44
|
string << '' # XXX workaround: avoid buffer sharing
|
46
45
|
string.force_encoding(Encoding::ASCII_8BIT)
|
47
|
-
string.gsub!(/["
|
46
|
+
string.gsub!(/["\\\x0-\x1f]/) { MAP[$&] }
|
48
47
|
string.gsub!(/(
|
49
48
|
(?:
|
50
49
|
[\xc2-\xdf][\x80-\xbf] |
|
@@ -64,7 +63,7 @@ module JSON
|
|
64
63
|
end
|
65
64
|
else
|
66
65
|
def utf8_to_json(string) # :nodoc:
|
67
|
-
string = string.gsub(/["
|
66
|
+
string = string.gsub(/["\\\x0-\x1f]/) { MAP[$&] }
|
68
67
|
string.gsub!(/(
|
69
68
|
(?:
|
70
69
|
[\xc2-\xdf][\x80-\xbf] |
|
data/lib/json/pure/parser.rb
CHANGED
@@ -188,7 +188,7 @@ module JSON
|
|
188
188
|
end
|
189
189
|
|
190
190
|
def parse_array
|
191
|
-
raise NestingError, "nesting of #@current_nesting is
|
191
|
+
raise NestingError, "nesting of #@current_nesting is too deep" if
|
192
192
|
@max_nesting.nonzero? && @current_nesting > @max_nesting
|
193
193
|
result = @array_class.new
|
194
194
|
delim = false
|
@@ -220,7 +220,7 @@ module JSON
|
|
220
220
|
end
|
221
221
|
|
222
222
|
def parse_object
|
223
|
-
raise NestingError, "nesting of #@current_nesting is
|
223
|
+
raise NestingError, "nesting of #@current_nesting is too deep" if
|
224
224
|
@max_nesting.nonzero? && @current_nesting > @max_nesting
|
225
225
|
result = @object_class.new
|
226
226
|
delim = false
|
data/lib/json/version.rb
CHANGED
data/tests/test_json.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: json
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.1.
|
4
|
+
version: 1.1.8
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Florian Frank
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2009-
|
12
|
+
date: 2009-08-31 00:00:00 +02:00
|
13
13
|
default_executable: edit_json.rb
|
14
14
|
dependencies: []
|
15
15
|
|
@@ -24,131 +24,147 @@ extensions:
|
|
24
24
|
extra_rdoc_files: []
|
25
25
|
|
26
26
|
files:
|
27
|
-
- RUBY
|
28
27
|
- CHANGES
|
29
|
-
-
|
30
|
-
- bin/prettify_json.rb
|
31
|
-
- VERSION
|
28
|
+
- COPYING
|
32
29
|
- GPL
|
33
|
-
- TODO
|
34
30
|
- README
|
35
|
-
-
|
36
|
-
-
|
31
|
+
- Rakefile
|
32
|
+
- TODO
|
33
|
+
- VERSION
|
34
|
+
- benchmarks
|
35
|
+
- benchmarks/data-p4-3GHz-ruby18
|
37
36
|
- benchmarks/data-p4-3GHz-ruby18/GeneratorBenchmarkComparison.log
|
38
|
-
- benchmarks/data-p4-3GHz-ruby18/ParserBenchmarkYAML#parser.dat
|
39
|
-
- benchmarks/data-p4-3GHz-ruby18/GeneratorBenchmarkExt#generator_safe.dat
|
40
|
-
- benchmarks/data-p4-3GHz-ruby18/ParserBenchmarkExt#parser.dat
|
41
|
-
- benchmarks/data-p4-3GHz-ruby18/GeneratorBenchmarkExt#generator_fast.dat
|
42
37
|
- benchmarks/data-p4-3GHz-ruby18/GeneratorBenchmarkExt#generator_fast-autocorrelation.dat
|
43
|
-
- benchmarks/data-p4-3GHz-ruby18/
|
44
|
-
- benchmarks/data-p4-3GHz-ruby18/
|
45
|
-
- benchmarks/data-p4-3GHz-ruby18/
|
38
|
+
- benchmarks/data-p4-3GHz-ruby18/GeneratorBenchmarkExt#generator_fast.dat
|
39
|
+
- benchmarks/data-p4-3GHz-ruby18/GeneratorBenchmarkExt#generator_pretty-autocorrelation.dat
|
40
|
+
- benchmarks/data-p4-3GHz-ruby18/GeneratorBenchmarkExt#generator_pretty.dat
|
41
|
+
- benchmarks/data-p4-3GHz-ruby18/GeneratorBenchmarkExt#generator_safe-autocorrelation.dat
|
42
|
+
- benchmarks/data-p4-3GHz-ruby18/GeneratorBenchmarkExt#generator_safe.dat
|
46
43
|
- benchmarks/data-p4-3GHz-ruby18/GeneratorBenchmarkExt.log
|
47
44
|
- benchmarks/data-p4-3GHz-ruby18/GeneratorBenchmarkPure#generator_fast-autocorrelation.dat
|
48
45
|
- benchmarks/data-p4-3GHz-ruby18/GeneratorBenchmarkPure#generator_fast.dat
|
49
|
-
- benchmarks/data-p4-3GHz-ruby18/ParserBenchmarkRails#parser.dat
|
50
46
|
- benchmarks/data-p4-3GHz-ruby18/GeneratorBenchmarkPure#generator_pretty-autocorrelation.dat
|
51
|
-
- benchmarks/data-p4-3GHz-ruby18/
|
52
|
-
- benchmarks/data-p4-3GHz-ruby18/
|
47
|
+
- benchmarks/data-p4-3GHz-ruby18/GeneratorBenchmarkPure#generator_pretty.dat
|
48
|
+
- benchmarks/data-p4-3GHz-ruby18/GeneratorBenchmarkPure#generator_safe-autocorrelation.dat
|
49
|
+
- benchmarks/data-p4-3GHz-ruby18/GeneratorBenchmarkPure#generator_safe.dat
|
50
|
+
- benchmarks/data-p4-3GHz-ruby18/GeneratorBenchmarkPure.log
|
51
|
+
- benchmarks/data-p4-3GHz-ruby18/GeneratorBenchmarkRails#generator-autocorrelation.dat
|
52
|
+
- benchmarks/data-p4-3GHz-ruby18/GeneratorBenchmarkRails#generator.dat
|
53
53
|
- benchmarks/data-p4-3GHz-ruby18/GeneratorBenchmarkRails.log
|
54
|
+
- benchmarks/data-p4-3GHz-ruby18/ParserBenchmarkComparison.log
|
55
|
+
- benchmarks/data-p4-3GHz-ruby18/ParserBenchmarkExt#parser-autocorrelation.dat
|
56
|
+
- benchmarks/data-p4-3GHz-ruby18/ParserBenchmarkExt#parser.dat
|
54
57
|
- benchmarks/data-p4-3GHz-ruby18/ParserBenchmarkExt.log
|
58
|
+
- benchmarks/data-p4-3GHz-ruby18/ParserBenchmarkPure#parser-autocorrelation.dat
|
59
|
+
- benchmarks/data-p4-3GHz-ruby18/ParserBenchmarkPure#parser.dat
|
60
|
+
- benchmarks/data-p4-3GHz-ruby18/ParserBenchmarkPure.log
|
61
|
+
- benchmarks/data-p4-3GHz-ruby18/ParserBenchmarkRails#parser-autocorrelation.dat
|
62
|
+
- benchmarks/data-p4-3GHz-ruby18/ParserBenchmarkRails#parser.dat
|
55
63
|
- benchmarks/data-p4-3GHz-ruby18/ParserBenchmarkRails.log
|
56
|
-
- benchmarks/data-p4-3GHz-ruby18/ParserBenchmarkComparison.log
|
57
|
-
- benchmarks/data-p4-3GHz-ruby18/GeneratorBenchmarkPure#generator_safe.dat
|
58
|
-
- benchmarks/data-p4-3GHz-ruby18/GeneratorBenchmarkRails#generator.dat
|
59
|
-
- benchmarks/data-p4-3GHz-ruby18/GeneratorBenchmarkExt#generator_safe-autocorrelation.dat
|
60
|
-
- benchmarks/data-p4-3GHz-ruby18/GeneratorBenchmarkPure#generator_pretty.dat
|
61
|
-
- benchmarks/data-p4-3GHz-ruby18/ParserBenchmarkYAML.log
|
62
64
|
- benchmarks/data-p4-3GHz-ruby18/ParserBenchmarkYAML#parser-autocorrelation.dat
|
63
|
-
- benchmarks/data-p4-3GHz-ruby18/
|
64
|
-
- benchmarks/data-p4-3GHz-ruby18/
|
65
|
-
- benchmarks/data
|
66
|
-
- benchmarks/data-p4-3GHz-ruby18/GeneratorBenchmarkPure#generator_safe-autocorrelation.dat
|
65
|
+
- benchmarks/data-p4-3GHz-ruby18/ParserBenchmarkYAML#parser.dat
|
66
|
+
- benchmarks/data-p4-3GHz-ruby18/ParserBenchmarkYAML.log
|
67
|
+
- benchmarks/data
|
67
68
|
- benchmarks/generator_benchmark.rb
|
69
|
+
- benchmarks/parser_benchmark.rb
|
70
|
+
- bin
|
71
|
+
- bin/edit_json.rb
|
72
|
+
- bin/prettify_json.rb
|
73
|
+
- data
|
74
|
+
- data/example.json
|
75
|
+
- data/index.html
|
76
|
+
- data/prototype.js
|
77
|
+
- diagrams
|
78
|
+
- doc-main.txt
|
79
|
+
- ext
|
80
|
+
- ext/json
|
81
|
+
- ext/json/ext
|
82
|
+
- ext/json/ext/generator
|
68
83
|
- ext/json/ext/generator/extconf.rb
|
69
|
-
- ext/json/ext/generator/unicode.c
|
70
84
|
- ext/json/ext/generator/generator.c
|
85
|
+
- ext/json/ext/generator/unicode.c
|
71
86
|
- ext/json/ext/generator/unicode.h
|
87
|
+
- ext/json/ext/parser
|
72
88
|
- ext/json/ext/parser/extconf.rb
|
89
|
+
- ext/json/ext/parser/parser.c
|
73
90
|
- ext/json/ext/parser/parser.rl
|
74
91
|
- ext/json/ext/parser/unicode.c
|
75
|
-
- ext/json/ext/parser/parser.c
|
76
92
|
- ext/json/ext/parser/unicode.h
|
77
|
-
-
|
78
|
-
-
|
79
|
-
- tools/server.rb
|
80
|
-
- doc-templates/main.txt
|
93
|
+
- install.rb
|
94
|
+
- lib
|
81
95
|
- lib/json.rb
|
82
|
-
- lib/json
|
96
|
+
- lib/json
|
97
|
+
- lib/json/Array.xpm
|
98
|
+
- lib/json/FalseClass.xpm
|
99
|
+
- lib/json/Hash.xpm
|
83
100
|
- lib/json/Key.xpm
|
84
|
-
- lib/json/
|
101
|
+
- lib/json/NilClass.xpm
|
85
102
|
- lib/json/Numeric.xpm
|
86
|
-
- lib/json/
|
87
|
-
- lib/json/
|
103
|
+
- lib/json/String.xpm
|
104
|
+
- lib/json/TrueClass.xpm
|
105
|
+
- lib/json/add
|
88
106
|
- lib/json/add/core.rb
|
107
|
+
- lib/json/add/rails.rb
|
89
108
|
- lib/json/common.rb
|
90
|
-
- lib/json/
|
91
|
-
- lib/json/
|
109
|
+
- lib/json/editor.rb
|
110
|
+
- lib/json/ext.rb
|
111
|
+
- lib/json/ext
|
112
|
+
- lib/json/json.xpm
|
113
|
+
- lib/json/pure.rb
|
114
|
+
- lib/json/pure
|
92
115
|
- lib/json/pure/generator.rb
|
93
116
|
- lib/json/pure/parser.rb
|
94
|
-
- lib/json/TrueClass.xpm
|
95
|
-
- lib/json/pure.rb
|
96
117
|
- lib/json/version.rb
|
97
|
-
-
|
98
|
-
-
|
99
|
-
- lib/json/NilClass.xpm
|
100
|
-
- data/example.json
|
101
|
-
- data/index.html
|
102
|
-
- data/prototype.js
|
103
|
-
- tests/test_json_addition.rb
|
104
|
-
- tests/fixtures/pass16.json
|
105
|
-
- tests/fixtures/fail4.json
|
118
|
+
- tests
|
119
|
+
- tests/fixtures
|
106
120
|
- tests/fixtures/fail1.json
|
107
|
-
- tests/fixtures/
|
108
|
-
- tests/fixtures/
|
109
|
-
- tests/fixtures/fail19.json
|
110
|
-
- tests/fixtures/pass2.json
|
111
|
-
- tests/fixtures/pass26.json
|
112
|
-
- tests/fixtures/pass1.json
|
113
|
-
- tests/fixtures/fail3.json
|
114
|
-
- tests/fixtures/fail20.json
|
115
|
-
- tests/fixtures/pass3.json
|
116
|
-
- tests/fixtures/pass15.json
|
121
|
+
- tests/fixtures/fail10.json
|
122
|
+
- tests/fixtures/fail11.json
|
117
123
|
- tests/fixtures/fail12.json
|
118
124
|
- tests/fixtures/fail13.json
|
125
|
+
- tests/fixtures/fail14.json
|
126
|
+
- tests/fixtures/fail18.json
|
127
|
+
- tests/fixtures/fail19.json
|
128
|
+
- tests/fixtures/fail2.json
|
129
|
+
- tests/fixtures/fail20.json
|
130
|
+
- tests/fixtures/fail21.json
|
119
131
|
- tests/fixtures/fail22.json
|
132
|
+
- tests/fixtures/fail23.json
|
120
133
|
- tests/fixtures/fail24.json
|
121
|
-
- tests/fixtures/
|
122
|
-
- tests/fixtures/
|
123
|
-
- tests/fixtures/
|
134
|
+
- tests/fixtures/fail25.json
|
135
|
+
- tests/fixtures/fail27.json
|
136
|
+
- tests/fixtures/fail28.json
|
137
|
+
- tests/fixtures/fail3.json
|
138
|
+
- tests/fixtures/fail4.json
|
139
|
+
- tests/fixtures/fail5.json
|
124
140
|
- tests/fixtures/fail6.json
|
125
|
-
- tests/fixtures/fail21.json
|
126
141
|
- tests/fixtures/fail7.json
|
142
|
+
- tests/fixtures/fail8.json
|
143
|
+
- tests/fixtures/fail9.json
|
144
|
+
- tests/fixtures/pass1.json
|
145
|
+
- tests/fixtures/pass15.json
|
146
|
+
- tests/fixtures/pass16.json
|
127
147
|
- tests/fixtures/pass17.json
|
128
|
-
- tests/fixtures/
|
129
|
-
- tests/fixtures/
|
130
|
-
- tests/fixtures/
|
131
|
-
- tests/fixtures/fail18.json
|
132
|
-
- tests/fixtures/fail27.json
|
133
|
-
- tests/fixtures/fail10.json
|
134
|
-
- tests/fixtures/fail23.json
|
135
|
-
- tests/test_json_rails.rb
|
148
|
+
- tests/fixtures/pass2.json
|
149
|
+
- tests/fixtures/pass26.json
|
150
|
+
- tests/fixtures/pass3.json
|
136
151
|
- tests/test_json.rb
|
152
|
+
- tests/test_json_addition.rb
|
153
|
+
- tests/test_json_fixtures.rb
|
137
154
|
- tests/test_json_generate.rb
|
155
|
+
- tests/test_json_rails.rb
|
138
156
|
- tests/test_json_unicode.rb
|
139
|
-
-
|
140
|
-
-
|
157
|
+
- tools
|
158
|
+
- tools/fuzz.rb
|
159
|
+
- tools/server.rb
|
141
160
|
has_rdoc: true
|
142
161
|
homepage: http://json.rubyforge.org
|
143
|
-
licenses: []
|
144
|
-
|
145
162
|
post_install_message:
|
146
163
|
rdoc_options:
|
147
164
|
- --title
|
148
165
|
- JSON -- A JSON implemention
|
149
166
|
- --main
|
150
|
-
-
|
151
|
-
- --line-numbers
|
167
|
+
- doc-main.txt
|
152
168
|
require_paths:
|
153
169
|
- ext/json/ext
|
154
170
|
- ext
|
@@ -168,14 +184,14 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
168
184
|
requirements: []
|
169
185
|
|
170
186
|
rubyforge_project: json
|
171
|
-
rubygems_version: 1.3.
|
187
|
+
rubygems_version: 1.3.1
|
172
188
|
signing_key:
|
173
|
-
specification_version:
|
189
|
+
specification_version: 2
|
174
190
|
summary: A JSON implementation as a Ruby extension
|
175
191
|
test_files:
|
176
|
-
- tests/test_json_addition.rb
|
177
|
-
- tests/test_json_rails.rb
|
178
192
|
- tests/test_json.rb
|
193
|
+
- tests/test_json_addition.rb
|
194
|
+
- tests/test_json_fixtures.rb
|
179
195
|
- tests/test_json_generate.rb
|
196
|
+
- tests/test_json_rails.rb
|
180
197
|
- tests/test_json_unicode.rb
|
181
|
-
- tests/test_json_fixtures.rb
|
data/doc-templates/main.txt
DELETED
@@ -1,283 +0,0 @@
|
|
1
|
-
# = json - JSON for Ruby
|
2
|
-
#
|
3
|
-
# == Description
|
4
|
-
#
|
5
|
-
# This is a implementation of the JSON specification according to RFC 4627
|
6
|
-
# (http://www.ietf.org/rfc/rfc4627.txt). Starting from version 1.0.0 on there
|
7
|
-
# will be two variants available:
|
8
|
-
#
|
9
|
-
# * A pure ruby variant, that relies on the iconv and the stringscan
|
10
|
-
# extensions, which are both part of the ruby standard library.
|
11
|
-
# * The quite a bit faster C extension variant, which is in parts implemented
|
12
|
-
# in C and comes with its own unicode conversion functions and a parser
|
13
|
-
# generated by the ragel state machine compiler
|
14
|
-
# (http://www.cs.queensu.ca/~thurston/ragel).
|
15
|
-
#
|
16
|
-
# Both variants of the JSON generator escape all non-ASCII an control
|
17
|
-
# characters with \uXXXX escape sequences, and support UTF-16 surrogate pairs
|
18
|
-
# in order to be able to generate the whole range of unicode code points. This
|
19
|
-
# means that generated JSON text is encoded as UTF-8 (because ASCII is a subset
|
20
|
-
# of UTF-8) and at the same time avoids decoding problems for receiving
|
21
|
-
# endpoints, that don't expect UTF-8 encoded texts. On the negative side this
|
22
|
-
# may lead to a bit longer strings than necessarry.
|
23
|
-
#
|
24
|
-
# All strings, that are to be encoded as JSON strings, should be UTF-8 byte
|
25
|
-
# sequences on the Ruby side. To encode raw binary strings, that aren't UTF-8
|
26
|
-
# encoded, please use the to_json_raw_object method of String (which produces
|
27
|
-
# an object, that contains a byte array) and decode the result on the receiving
|
28
|
-
# endpoint.
|
29
|
-
#
|
30
|
-
# == Author
|
31
|
-
#
|
32
|
-
# Florian Frank <mailto:flori@ping.de>
|
33
|
-
#
|
34
|
-
# == License
|
35
|
-
#
|
36
|
-
# This software is distributed under the same license as Ruby itself, see
|
37
|
-
# http://www.ruby-lang.org/en/LICENSE.txt.
|
38
|
-
#
|
39
|
-
# == Download
|
40
|
-
#
|
41
|
-
# The latest version of this library can be downloaded at
|
42
|
-
#
|
43
|
-
# * http://rubyforge.org/frs?group_id=953
|
44
|
-
#
|
45
|
-
# Online Documentation should be located at
|
46
|
-
#
|
47
|
-
# * http://json.rubyforge.org
|
48
|
-
#
|
49
|
-
# == Usage
|
50
|
-
#
|
51
|
-
# To use JSON you can
|
52
|
-
# require 'json'
|
53
|
-
# to load the installed variant (either the extension 'json' or the pure
|
54
|
-
# variant 'json_pure'). If you have installed the extension variant, you can
|
55
|
-
# pick either the extension variant or the pure variant by typing
|
56
|
-
# require 'json/ext'
|
57
|
-
# or
|
58
|
-
# require 'json/pure'
|
59
|
-
#
|
60
|
-
# You can choose to load a set of common additions to ruby core's objects if
|
61
|
-
# you
|
62
|
-
# require 'json/add/core'
|
63
|
-
#
|
64
|
-
# After requiring this you can, e. g., serialise/deserialise Ruby ranges:
|
65
|
-
#
|
66
|
-
# JSON JSON(1..10) # => 1..10
|
67
|
-
#
|
68
|
-
# To find out how to add JSON support to other or your own classes, read the
|
69
|
-
# Examples section below.
|
70
|
-
#
|
71
|
-
# To get the best compatibility to rails' JSON implementation, you can
|
72
|
-
# require 'json/add/rails'
|
73
|
-
#
|
74
|
-
# Both of the additions attempt to require 'json' (like above) first, if it has
|
75
|
-
# not been required yet.
|
76
|
-
#
|
77
|
-
# == Speed Comparisons
|
78
|
-
#
|
79
|
-
# I have created some benchmark results (see the benchmarks/data-p4-3Ghz
|
80
|
-
# subdir of the package) for the JSON-parser to estimate the speed up in the C
|
81
|
-
# extension:
|
82
|
-
#
|
83
|
-
# Comparing times (call_time_mean):
|
84
|
-
# 1 ParserBenchmarkExt#parser 900 repeats:
|
85
|
-
# 553.922304770 ( real) -> 21.500x
|
86
|
-
# 0.001805307
|
87
|
-
# 2 ParserBenchmarkYAML#parser 1000 repeats:
|
88
|
-
# 224.513358139 ( real) -> 8.714x
|
89
|
-
# 0.004454078
|
90
|
-
# 3 ParserBenchmarkPure#parser 1000 repeats:
|
91
|
-
# 26.755020642 ( real) -> 1.038x
|
92
|
-
# 0.037376163
|
93
|
-
# 4 ParserBenchmarkRails#parser 1000 repeats:
|
94
|
-
# 25.763381731 ( real) -> 1.000x
|
95
|
-
# 0.038814780
|
96
|
-
# calls/sec ( time) -> speed covers
|
97
|
-
# secs/call
|
98
|
-
#
|
99
|
-
# In the table above 1 is JSON::Ext::Parser, 2 is YAML.load with YAML
|
100
|
-
# compatbile JSON document, 3 is is JSON::Pure::Parser, and 4 is
|
101
|
-
# ActiveSupport::JSON.decode. The ActiveSupport JSON-decoder converts the
|
102
|
-
# input first to YAML and then uses the YAML-parser, the conversion seems to
|
103
|
-
# slow it down so much that it is only as fast as the JSON::Pure::Parser!
|
104
|
-
#
|
105
|
-
# If you look at the benchmark data you can see that this is mostly caused by
|
106
|
-
# the frequent high outliers - the median of the Rails-parser runs is still
|
107
|
-
# overall smaller than the median of the JSON::Pure::Parser runs:
|
108
|
-
#
|
109
|
-
# Comparing times (call_time_median):
|
110
|
-
# 1 ParserBenchmarkExt#parser 900 repeats:
|
111
|
-
# 800.592479481 ( real) -> 26.936x
|
112
|
-
# 0.001249075
|
113
|
-
# 2 ParserBenchmarkYAML#parser 1000 repeats:
|
114
|
-
# 271.002390644 ( real) -> 9.118x
|
115
|
-
# 0.003690004
|
116
|
-
# 3 ParserBenchmarkRails#parser 1000 repeats:
|
117
|
-
# 30.227910865 ( real) -> 1.017x
|
118
|
-
# 0.033082008
|
119
|
-
# 4 ParserBenchmarkPure#parser 1000 repeats:
|
120
|
-
# 29.722384421 ( real) -> 1.000x
|
121
|
-
# 0.033644676
|
122
|
-
# calls/sec ( time) -> speed covers
|
123
|
-
# secs/call
|
124
|
-
#
|
125
|
-
# I have benchmarked the JSON-Generator as well. This generated a few more
|
126
|
-
# values, because there are different modes that also influence the achieved
|
127
|
-
# speed:
|
128
|
-
#
|
129
|
-
# Comparing times (call_time_mean):
|
130
|
-
# 1 GeneratorBenchmarkExt#generator_fast 1000 repeats:
|
131
|
-
# 547.354332608 ( real) -> 15.090x
|
132
|
-
# 0.001826970
|
133
|
-
# 2 GeneratorBenchmarkExt#generator_safe 1000 repeats:
|
134
|
-
# 443.968212317 ( real) -> 12.240x
|
135
|
-
# 0.002252414
|
136
|
-
# 3 GeneratorBenchmarkExt#generator_pretty 900 repeats:
|
137
|
-
# 375.104545883 ( real) -> 10.341x
|
138
|
-
# 0.002665923
|
139
|
-
# 4 GeneratorBenchmarkPure#generator_fast 1000 repeats:
|
140
|
-
# 49.978706968 ( real) -> 1.378x
|
141
|
-
# 0.020008521
|
142
|
-
# 5 GeneratorBenchmarkRails#generator 1000 repeats:
|
143
|
-
# 38.531868759 ( real) -> 1.062x
|
144
|
-
# 0.025952543
|
145
|
-
# 6 GeneratorBenchmarkPure#generator_safe 1000 repeats:
|
146
|
-
# 36.927649925 ( real) -> 1.018x 7 (>=3859)
|
147
|
-
# 0.027079979
|
148
|
-
# 7 GeneratorBenchmarkPure#generator_pretty 1000 repeats:
|
149
|
-
# 36.272134441 ( real) -> 1.000x 6 (>=3859)
|
150
|
-
# 0.027569373
|
151
|
-
# calls/sec ( time) -> speed covers
|
152
|
-
# secs/call
|
153
|
-
#
|
154
|
-
# In the table above 1-3 are JSON::Ext::Generator methods. 4, 6, and 7 are
|
155
|
-
# JSON::Pure::Generator methods and 5 is the Rails JSON generator. It is now a
|
156
|
-
# bit faster than the generator_safe and generator_pretty methods of the pure
|
157
|
-
# variant but slower than the others.
|
158
|
-
#
|
159
|
-
# To achieve the fastest JSON text output, you can use the fast_generate
|
160
|
-
# method. Beware, that this will disable the checking for circular Ruby data
|
161
|
-
# structures, which may cause JSON to go into an infinite loop.
|
162
|
-
#
|
163
|
-
# Here are the median comparisons for completeness' sake:
|
164
|
-
#
|
165
|
-
# Comparing times (call_time_median):
|
166
|
-
# 1 GeneratorBenchmarkExt#generator_fast 1000 repeats:
|
167
|
-
# 708.258020939 ( real) -> 16.547x
|
168
|
-
# 0.001411915
|
169
|
-
# 2 GeneratorBenchmarkExt#generator_safe 1000 repeats:
|
170
|
-
# 569.105020353 ( real) -> 13.296x
|
171
|
-
# 0.001757145
|
172
|
-
# 3 GeneratorBenchmarkExt#generator_pretty 900 repeats:
|
173
|
-
# 482.825371244 ( real) -> 11.280x
|
174
|
-
# 0.002071142
|
175
|
-
# 4 GeneratorBenchmarkPure#generator_fast 1000 repeats:
|
176
|
-
# 62.717626652 ( real) -> 1.465x
|
177
|
-
# 0.015944481
|
178
|
-
# 5 GeneratorBenchmarkRails#generator 1000 repeats:
|
179
|
-
# 43.965681162 ( real) -> 1.027x
|
180
|
-
# 0.022745013
|
181
|
-
# 6 GeneratorBenchmarkPure#generator_safe 1000 repeats:
|
182
|
-
# 43.929073409 ( real) -> 1.026x 7 (>=3859)
|
183
|
-
# 0.022763968
|
184
|
-
# 7 GeneratorBenchmarkPure#generator_pretty 1000 repeats:
|
185
|
-
# 42.802514491 ( real) -> 1.000x 6 (>=3859)
|
186
|
-
# 0.023363113
|
187
|
-
# calls/sec ( time) -> speed covers
|
188
|
-
# secs/call
|
189
|
-
#
|
190
|
-
# == Examples
|
191
|
-
#
|
192
|
-
# To create a JSON text from a ruby data structure, you can call JSON.generate
|
193
|
-
# like that:
|
194
|
-
#
|
195
|
-
# json = JSON.generate [1, 2, {"a"=>3.141}, false, true, nil, 4..10]
|
196
|
-
# # => "[1,2,{\"a\":3.141},false,true,null,\"4..10\"]"
|
197
|
-
#
|
198
|
-
# To create a valid JSON text you have to make sure, that the output is
|
199
|
-
# embedded in either a JSON array [] or a JSON object {}. The easiest way to do
|
200
|
-
# this, is by putting your values in a Ruby Array or Hash instance.
|
201
|
-
#
|
202
|
-
# To get back a ruby data structure from a JSON text, you have to call
|
203
|
-
# JSON.parse on it:
|
204
|
-
#
|
205
|
-
# JSON.parse json
|
206
|
-
# # => [1, 2, {"a"=>3.141}, false, true, nil, "4..10"]
|
207
|
-
#
|
208
|
-
# Note, that the range from the original data structure is a simple
|
209
|
-
# string now. The reason for this is, that JSON doesn't support ranges
|
210
|
-
# or arbitrary classes. In this case the json library falls back to call
|
211
|
-
# Object#to_json, which is the same as #to_s.to_json.
|
212
|
-
#
|
213
|
-
# It's possible to add JSON support serialization to arbitrary classes by
|
214
|
-
# simply implementing a more specialized version of the #to_json method, that
|
215
|
-
# should return a JSON object (a hash converted to JSON with #to_json) like
|
216
|
-
# this (don't forget the *a for all the arguments):
|
217
|
-
#
|
218
|
-
# class Range
|
219
|
-
# def to_json(*a)
|
220
|
-
# {
|
221
|
-
# 'json_class' => self.class.name, # = 'Range'
|
222
|
-
# 'data' => [ first, last, exclude_end? ]
|
223
|
-
# }.to_json(*a)
|
224
|
-
# end
|
225
|
-
# end
|
226
|
-
#
|
227
|
-
# The hash key 'json_class' is the class, that will be asked to deserialise the
|
228
|
-
# JSON representation later. In this case it's 'Range', but any namespace of
|
229
|
-
# the form 'A::B' or '::A::B' will do. All other keys are arbitrary and can be
|
230
|
-
# used to store the necessary data to configure the object to be deserialised.
|
231
|
-
#
|
232
|
-
# If a the key 'json_class' is found in a JSON object, the JSON parser checks
|
233
|
-
# if the given class responds to the json_create class method. If so, it is
|
234
|
-
# called with the JSON object converted to a Ruby hash. So a range can
|
235
|
-
# be deserialised by implementing Range.json_create like this:
|
236
|
-
#
|
237
|
-
# class Range
|
238
|
-
# def self.json_create(o)
|
239
|
-
# new(*o['data'])
|
240
|
-
# end
|
241
|
-
# end
|
242
|
-
#
|
243
|
-
# Now it possible to serialise/deserialise ranges as well:
|
244
|
-
#
|
245
|
-
# json = JSON.generate [1, 2, {"a"=>3.141}, false, true, nil, 4..10]
|
246
|
-
# # => "[1,2,{\"a\":3.141},false,true,null,{\"json_class\":\"Range\",\"data\":[4,10,false]}]"
|
247
|
-
# JSON.parse json
|
248
|
-
# # => [1, 2, {"a"=>3.141}, false, true, nil, 4..10]
|
249
|
-
#
|
250
|
-
# JSON.generate always creates the shortest possible string representation of a
|
251
|
-
# ruby data structure in one line. This good for data storage or network
|
252
|
-
# protocols, but not so good for humans to read. Fortunately there's also
|
253
|
-
# JSON.pretty_generate (or JSON.pretty_generate) that creates a more
|
254
|
-
# readable output:
|
255
|
-
#
|
256
|
-
# puts JSON.pretty_generate([1, 2, {"a"=>3.141}, false, true, nil, 4..10])
|
257
|
-
# [
|
258
|
-
# 1,
|
259
|
-
# 2,
|
260
|
-
# {
|
261
|
-
# "a": 3.141
|
262
|
-
# },
|
263
|
-
# false,
|
264
|
-
# true,
|
265
|
-
# null,
|
266
|
-
# {
|
267
|
-
# "json_class": "Range",
|
268
|
-
# "data": [
|
269
|
-
# 4,
|
270
|
-
# 10,
|
271
|
-
# false
|
272
|
-
# ]
|
273
|
-
# }
|
274
|
-
# ]
|
275
|
-
#
|
276
|
-
# There are also the methods Kernel#j for generate, and Kernel#jj for
|
277
|
-
# pretty_generate output to the console, that work analogous to Core Ruby's p
|
278
|
-
# and the pp library's pp methods.
|
279
|
-
#
|
280
|
-
# The script tools/server.rb contains a small example if you want to test, how
|
281
|
-
# receiving a JSON object from a webrick server in your browser with the
|
282
|
-
# javasript prototype library (http://www.prototypejs.org) works.
|
283
|
-
#
|