taps 0.3.18 → 0.3.19.pre1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,356 @@
1
+ == Description
2
+
3
+ This is a implementation of the JSON specification according to RFC 4627
4
+ http://www.ietf.org/rfc/rfc4627.txt . Starting from version 1.0.0 on there
5
+ will be two variants available:
6
+
7
+ * A pure ruby variant, that relies on the iconv and the stringscan
8
+ extensions, which are both part of the ruby standard library.
9
+ * The quite a bit faster C extension variant, which is in parts implemented
10
+ in C and comes with its own unicode conversion functions and a parser
11
+ generated by the ragel state machine compiler
12
+ http://www.cs.queensu.ca/~thurston/ragel .
13
+
14
+ Both variants of the JSON generator generate UTF-8 character sequences by
15
+ default. If an :ascii_only option with a true value is given, they escape all
16
+ non-ASCII and control characters with \uXXXX escape sequences, and support
17
+ UTF-16 surrogate pairs in order to be able to generate the whole range of
18
+ unicode code points.
19
+
20
+ All strings, that are to be encoded as JSON strings, should be UTF-8 byte
21
+ sequences on the Ruby side. To encode raw binary strings, that aren't UTF-8
22
+ encoded, please use the to_json_raw_object method of String (which produces
23
+ an object, that contains a byte array) and decode the result on the receiving
24
+ endpoint.
25
+
26
+ The JSON parsers can parse UTF-8, UTF-16BE, UTF-16LE, UTF-32BE, and UTF-32LE
27
+ JSON documents under Ruby 1.8. Under Ruby 1.9 they take advantage of Ruby's
28
+ M17n features and can parse all documents which have the correct
29
+ String#encoding set. If a document string has ASCII-8BIT as an encoding the
30
+ parser attempts to figure out which of the UTF encodings from above it is and
31
+ trys to parse it.
32
+
33
+ == Installation
34
+
35
+ It's recommended to use the extension variant of JSON, because it's faster than
36
+ the pure ruby variant. If you cannot build it on your system, you can settle
37
+ for the latter.
38
+
39
+ Just type into the command line as root:
40
+
41
+ # rake install
42
+
43
+ The above command will build the extensions and install them on your system.
44
+
45
+ # rake install_pure
46
+
47
+ or
48
+
49
+ # ruby install.rb
50
+
51
+ will just install the pure ruby implementation of JSON.
52
+
53
+ If you use Rubygems you can type
54
+
55
+ # gem install json
56
+
57
+ instead, to install the newest JSON version.
58
+
59
+ There is also a pure ruby json only variant of the gem, that can be installed
60
+ with:
61
+
62
+ # gem install json_pure
63
+
64
+ == Compiling the extensions yourself
65
+
66
+ If you want to build the extensions yourself you need rake:
67
+
68
+ You can get it from rubyforge:
69
+ http://rubyforge.org/projects/rake
70
+
71
+ or just type
72
+
73
+ # gem install rake
74
+
75
+ for the installation via rubygems.
76
+
77
+ If you want to create the parser.c file from its parser.rl file or draw nice
78
+ graphviz images of the state machines, you need ragel from: http://www.cs.queensu.ca/~thurston/ragel
79
+
80
+
81
+ == Usage
82
+
83
+ To use JSON you can
84
+ require 'json'
85
+ to load the installed variant (either the extension 'json' or the pure
86
+ variant 'json_pure'). If you have installed the extension variant, you can
87
+ pick either the extension variant or the pure variant by typing
88
+ require 'json/ext'
89
+ or
90
+ require 'json/pure'
91
+
92
+ Now you can parse a JSON document into a ruby data structure by calling
93
+
94
+ JSON.parse(document)
95
+
96
+ If you want to generate a JSON document from a ruby data structure call
97
+ JSON.generate(data)
98
+
99
+ You can also use the pretty_generate method (which formats the output more
100
+ verbosely and nicely) or fast_generate (which doesn't do any of the security
101
+ checks generate performs, e. g. nesting deepness checks).
102
+
103
+ To create a valid JSON document you have to make sure, that the output is
104
+ embedded in either a JSON array [] or a JSON object {}. The easiest way to do
105
+ this, is by putting your values in a Ruby Array or Hash instance.
106
+
107
+ There are also the JSON and JSON[] methods which use parse on a String or
108
+ generate a JSON document from an array or hash:
109
+
110
+ document = JSON 'test' => 23 # => "{\"test\":23}"
111
+ document = JSON['test'] => 23 # => "{\"test\":23}"
112
+
113
+ and
114
+
115
+ data = JSON '{"test":23}' # => {"test"=>23}
116
+ data = JSON['{"test":23}'] # => {"test"=>23}
117
+
118
+ You can choose to load a set of common additions to ruby core's objects if
119
+ you
120
+ require 'json/add/core'
121
+
122
+ After requiring this you can, e. g., serialise/deserialise Ruby ranges:
123
+
124
+ JSON JSON(1..10) # => 1..10
125
+
126
+ To find out how to add JSON support to other or your own classes, read the
127
+ section "More Examples" below.
128
+
129
+ To get the best compatibility to rails' JSON implementation, you can
130
+ require 'json/add/rails'
131
+
132
+ Both of the additions attempt to require 'json' (like above) first, if it has
133
+ not been required yet.
134
+
135
+ == More Examples
136
+
137
+ To create a JSON document from a ruby data structure, you can call
138
+ JSON.generate like that:
139
+
140
+ json = JSON.generate [1, 2, {"a"=>3.141}, false, true, nil, 4..10]
141
+ # => "[1,2,{\"a\":3.141},false,true,null,\"4..10\"]"
142
+
143
+ To get back a ruby data structure from a JSON document, you have to call
144
+ JSON.parse on it:
145
+
146
+ JSON.parse json
147
+ # => [1, 2, {"a"=>3.141}, false, true, nil, "4..10"]
148
+
149
+ Note, that the range from the original data structure is a simple
150
+ string now. The reason for this is, that JSON doesn't support ranges
151
+ or arbitrary classes. In this case the json library falls back to call
152
+ Object#to_json, which is the same as #to_s.to_json.
153
+
154
+ It's possible to add JSON support serialization to arbitrary classes by
155
+ simply implementing a more specialized version of the #to_json method, that
156
+ should return a JSON object (a hash converted to JSON with #to_json) like
157
+ this (don't forget the *a for all the arguments):
158
+
159
+ class Range
160
+ def to_json(*a)
161
+ {
162
+ 'json_class' => self.class.name, # = 'Range'
163
+ 'data' => [ first, last, exclude_end? ]
164
+ }.to_json(*a)
165
+ end
166
+ end
167
+
168
+ The hash key 'json_class' is the class, that will be asked to deserialise the
169
+ JSON representation later. In this case it's 'Range', but any namespace of
170
+ the form 'A::B' or '::A::B' will do. All other keys are arbitrary and can be
171
+ used to store the necessary data to configure the object to be deserialised.
172
+
173
+ If a the key 'json_class' is found in a JSON object, the JSON parser checks
174
+ if the given class responds to the json_create class method. If so, it is
175
+ called with the JSON object converted to a Ruby hash. So a range can
176
+ be deserialised by implementing Range.json_create like this:
177
+
178
+ class Range
179
+ def self.json_create(o)
180
+ new(*o['data'])
181
+ end
182
+ end
183
+
184
+ Now it possible to serialise/deserialise ranges as well:
185
+
186
+ json = JSON.generate [1, 2, {"a"=>3.141}, false, true, nil, 4..10]
187
+ # => "[1,2,{\"a\":3.141},false,true,null,{\"json_class\":\"Range\",\"data\":[4,10,false]}]"
188
+ JSON.parse json
189
+ # => [1, 2, {"a"=>3.141}, false, true, nil, 4..10]
190
+
191
+ JSON.generate always creates the shortest possible string representation of a
192
+ ruby data structure in one line. This is good for data storage or network
193
+ protocols, but not so good for humans to read. Fortunately there's also
194
+ JSON.pretty_generate (or JSON.pretty_generate) that creates a more readable
195
+ output:
196
+
197
+ puts JSON.pretty_generate([1, 2, {"a"=>3.141}, false, true, nil, 4..10])
198
+ [
199
+ 1,
200
+ 2,
201
+ {
202
+ "a": 3.141
203
+ },
204
+ false,
205
+ true,
206
+ null,
207
+ {
208
+ "json_class": "Range",
209
+ "data": [
210
+ 4,
211
+ 10,
212
+ false
213
+ ]
214
+ }
215
+ ]
216
+
217
+ There are also the methods Kernel#j for generate, and Kernel#jj for
218
+ pretty_generate output to the console, that work analogous to Core Ruby's p and
219
+ the pp library's pp methods.
220
+
221
+ The script tools/server.rb contains a small example if you want to test, how
222
+ receiving a JSON object from a webrick server in your browser with the
223
+ javasript prototype library http://www.prototypejs.org works.
224
+
225
+ == Speed Comparisons
226
+
227
+ I have created some benchmark results (see the benchmarks/data-p4-3Ghz
228
+ subdir of the package) for the JSON-parser to estimate the speed up in the C
229
+ extension:
230
+
231
+ Comparing times (call_time_mean):
232
+ 1 ParserBenchmarkExt#parser 900 repeats:
233
+ 553.922304770 ( real) -> 21.500x
234
+ 0.001805307
235
+ 2 ParserBenchmarkYAML#parser 1000 repeats:
236
+ 224.513358139 ( real) -> 8.714x
237
+ 0.004454078
238
+ 3 ParserBenchmarkPure#parser 1000 repeats:
239
+ 26.755020642 ( real) -> 1.038x
240
+ 0.037376163
241
+ 4 ParserBenchmarkRails#parser 1000 repeats:
242
+ 25.763381731 ( real) -> 1.000x
243
+ 0.038814780
244
+ calls/sec ( time) -> speed covers
245
+ secs/call
246
+
247
+ In the table above 1 is JSON::Ext::Parser, 2 is YAML.load with YAML
248
+ compatbile JSON document, 3 is is JSON::Pure::Parser, and 4 is
249
+ ActiveSupport::JSON.decode. The ActiveSupport JSON-decoder converts the
250
+ input first to YAML and then uses the YAML-parser, the conversion seems to
251
+ slow it down so much that it is only as fast as the JSON::Pure::Parser!
252
+
253
+ If you look at the benchmark data you can see that this is mostly caused by
254
+ the frequent high outliers - the median of the Rails-parser runs is still
255
+ overall smaller than the median of the JSON::Pure::Parser runs:
256
+
257
+ Comparing times (call_time_median):
258
+ 1 ParserBenchmarkExt#parser 900 repeats:
259
+ 800.592479481 ( real) -> 26.936x
260
+ 0.001249075
261
+ 2 ParserBenchmarkYAML#parser 1000 repeats:
262
+ 271.002390644 ( real) -> 9.118x
263
+ 0.003690004
264
+ 3 ParserBenchmarkRails#parser 1000 repeats:
265
+ 30.227910865 ( real) -> 1.017x
266
+ 0.033082008
267
+ 4 ParserBenchmarkPure#parser 1000 repeats:
268
+ 29.722384421 ( real) -> 1.000x
269
+ 0.033644676
270
+ calls/sec ( time) -> speed covers
271
+ secs/call
272
+
273
+ I have benchmarked the JSON-Generator as well. This generated a few more
274
+ values, because there are different modes that also influence the achieved
275
+ speed:
276
+
277
+ Comparing times (call_time_mean):
278
+ 1 GeneratorBenchmarkExt#generator_fast 1000 repeats:
279
+ 547.354332608 ( real) -> 15.090x
280
+ 0.001826970
281
+ 2 GeneratorBenchmarkExt#generator_safe 1000 repeats:
282
+ 443.968212317 ( real) -> 12.240x
283
+ 0.002252414
284
+ 3 GeneratorBenchmarkExt#generator_pretty 900 repeats:
285
+ 375.104545883 ( real) -> 10.341x
286
+ 0.002665923
287
+ 4 GeneratorBenchmarkPure#generator_fast 1000 repeats:
288
+ 49.978706968 ( real) -> 1.378x
289
+ 0.020008521
290
+ 5 GeneratorBenchmarkRails#generator 1000 repeats:
291
+ 38.531868759 ( real) -> 1.062x
292
+ 0.025952543
293
+ 6 GeneratorBenchmarkPure#generator_safe 1000 repeats:
294
+ 36.927649925 ( real) -> 1.018x 7 (>=3859)
295
+ 0.027079979
296
+ 7 GeneratorBenchmarkPure#generator_pretty 1000 repeats:
297
+ 36.272134441 ( real) -> 1.000x 6 (>=3859)
298
+ 0.027569373
299
+ calls/sec ( time) -> speed covers
300
+ secs/call
301
+
302
+ In the table above 1-3 are JSON::Ext::Generator methods. 4, 6, and 7 are
303
+ JSON::Pure::Generator methods and 5 is the Rails JSON generator. It is now a
304
+ bit faster than the generator_safe and generator_pretty methods of the pure
305
+ variant but slower than the others.
306
+
307
+ To achieve the fastest JSON document output, you can use the fast_generate
308
+ method. Beware, that this will disable the checking for circular Ruby data
309
+ structures, which may cause JSON to go into an infinite loop.
310
+
311
+ Here are the median comparisons for completeness' sake:
312
+
313
+ Comparing times (call_time_median):
314
+ 1 GeneratorBenchmarkExt#generator_fast 1000 repeats:
315
+ 708.258020939 ( real) -> 16.547x
316
+ 0.001411915
317
+ 2 GeneratorBenchmarkExt#generator_safe 1000 repeats:
318
+ 569.105020353 ( real) -> 13.296x
319
+ 0.001757145
320
+ 3 GeneratorBenchmarkExt#generator_pretty 900 repeats:
321
+ 482.825371244 ( real) -> 11.280x
322
+ 0.002071142
323
+ 4 GeneratorBenchmarkPure#generator_fast 1000 repeats:
324
+ 62.717626652 ( real) -> 1.465x
325
+ 0.015944481
326
+ 5 GeneratorBenchmarkRails#generator 1000 repeats:
327
+ 43.965681162 ( real) -> 1.027x
328
+ 0.022745013
329
+ 6 GeneratorBenchmarkPure#generator_safe 1000 repeats:
330
+ 43.929073409 ( real) -> 1.026x 7 (>=3859)
331
+ 0.022763968
332
+ 7 GeneratorBenchmarkPure#generator_pretty 1000 repeats:
333
+ 42.802514491 ( real) -> 1.000x 6 (>=3859)
334
+ 0.023363113
335
+ calls/sec ( time) -> speed covers
336
+ secs/call
337
+
338
+ == Author
339
+
340
+ Florian Frank <mailto:flori@ping.de>
341
+
342
+ == License
343
+
344
+ Ruby License, see the COPYING file included in the source distribution. The
345
+ Ruby License includes the GNU General Public License (GPL), Version 2, so see
346
+ the file GPL as well.
347
+
348
+ == Download
349
+
350
+ The latest version of this library can be downloaded at
351
+
352
+ * http://rubyforge.org/frs?group_id=953
353
+
354
+ Online Documentation should be located at
355
+
356
+ * http://json.rubyforge.org
@@ -0,0 +1,33 @@
1
+ JSON-JRuby
2
+ ==========
3
+
4
+ JSON-JRuby is a port of Florian Frank's native
5
+ [`json` library](http://json.rubyforge.org/) to JRuby.
6
+ It aims to be a perfect drop-in replacement for `json_pure`.
7
+
8
+
9
+ Development version
10
+ ===================
11
+
12
+ The latest version is available from the
13
+ [Git repository](http://github.com/mernen/json-jruby/tree):
14
+
15
+ git clone git://github.com/mernen/json-jruby.git
16
+
17
+
18
+ Compiling
19
+ =========
20
+
21
+ You'll need JRuby version 1.2 or greater to build JSON-JRuby.
22
+ Its path must be set on the `jruby.dir` property of
23
+ `nbproject/project.properties` (defaults to `../jruby`).
24
+
25
+ Additionally, you'll need [Ant](http://ant.apache.org/), and
26
+ [Ragel](http://www.cs.queensu.ca/~thurston/ragel/) 6.4 or greater.
27
+
28
+ Then, from the folder where the sources are located, type:
29
+
30
+ ant clean jar
31
+
32
+ to clean any leftovers from previous builds and generate the `.jar` files.
33
+ To generate a RubyGem, specify the `gem` action rather than `jar`.
@@ -0,0 +1,401 @@
1
+ begin
2
+ require 'rake/gempackagetask'
3
+ rescue LoadError
4
+ end
5
+
6
+ begin
7
+ require 'rake/extensiontask'
8
+ rescue LoadError
9
+ warn "WARNING: rake-compiler is not installed. You will not be able to build the json gem until you install it."
10
+ end
11
+
12
+ require 'rbconfig'
13
+ include Config
14
+
15
+ require 'rake/clean'
16
+ CLOBBER.include Dir['benchmarks/data/*.{dat,log}']
17
+ CLEAN.include FileList['diagrams/*.*'], 'doc', 'coverage', 'tmp',
18
+ FileList["ext/**/{Makefile,mkmf.log}"], 'build', 'dist', FileList['**/*.rbc'],
19
+ FileList["{ext,lib}/**/*.{so,bundle,#{CONFIG['DLEXT']},o,obj,pdb,lib,manifest,exp,def,jar,class}"],
20
+ FileList['java/src/**/*.class']
21
+
22
+ MAKE = ENV['MAKE'] || %w[gmake make].find { |c| system(c, '-v') }
23
+ PKG_NAME = 'json'
24
+ PKG_TITLE = 'JSON Implementation for Ruby'
25
+ PKG_VERSION = File.read('VERSION').chomp
26
+ PKG_FILES = FileList["**/*"].exclude(/CVS|pkg|tmp|coverage|Makefile|\.nfs\.|\.iml\Z/).exclude(/\.(so|bundle|o|class|#{CONFIG['DLEXT']})$/)
27
+
28
+ EXT_ROOT_DIR = 'ext/json/ext'
29
+ EXT_PARSER_DIR = "#{EXT_ROOT_DIR}/parser"
30
+ EXT_PARSER_DL = "#{EXT_PARSER_DIR}/parser.#{CONFIG['DLEXT']}"
31
+ RAGEL_PATH = "#{EXT_PARSER_DIR}/parser.rl"
32
+ EXT_PARSER_SRC = "#{EXT_PARSER_DIR}/parser.c"
33
+ PKG_FILES << EXT_PARSER_SRC
34
+ EXT_GENERATOR_DIR = "#{EXT_ROOT_DIR}/generator"
35
+ EXT_GENERATOR_DL = "#{EXT_GENERATOR_DIR}/generator.#{CONFIG['DLEXT']}"
36
+ EXT_GENERATOR_SRC = "#{EXT_GENERATOR_DIR}/generator.c"
37
+
38
+ JAVA_DIR = "java/src/json/ext"
39
+ JAVA_RAGEL_PATH = "#{JAVA_DIR}/Parser.rl"
40
+ JAVA_PARSER_SRC = "#{JAVA_DIR}/Parser.java"
41
+ JAVA_SOURCES = FileList["#{JAVA_DIR}/*.java"]
42
+ JAVA_CLASSES = []
43
+ JRUBY_PARSER_JAR = File.expand_path("lib/json/ext/parser.jar")
44
+ JRUBY_GENERATOR_JAR = File.expand_path("lib/json/ext/generator.jar")
45
+
46
+ RAGEL_CODEGEN = %w[rlcodegen rlgen-cd ragel].find { |c| system(c, '-v') }
47
+ RAGEL_DOTGEN = %w[rlgen-dot rlgen-cd ragel].find { |c| system(c, '-v') }
48
+
49
+ def myruby(*args, &block)
50
+ @myruby ||= File.join(CONFIG['bindir'], CONFIG['ruby_install_name'])
51
+ options = (Hash === args.last) ? args.pop : {}
52
+ if args.length > 1 then
53
+ sh(*([@myruby] + args + [options]), &block)
54
+ else
55
+ sh("#{@myruby} #{args.first}", options, &block)
56
+ end
57
+ end
58
+
59
+ desc "Installing library (pure)"
60
+ task :install_pure => :version do
61
+ myruby 'install.rb'
62
+ end
63
+
64
+ task :install_ext_really do
65
+ sitearchdir = CONFIG["sitearchdir"]
66
+ cd 'ext' do
67
+ for file in Dir["json/ext/*.#{CONFIG['DLEXT']}"]
68
+ d = File.join(sitearchdir, file)
69
+ mkdir_p File.dirname(d)
70
+ install(file, d)
71
+ end
72
+ end
73
+ end
74
+
75
+ desc "Installing library (extension)"
76
+ task :install_ext => [ :compile_ext, :install_pure, :install_ext_really ]
77
+
78
+ desc "Installing library (extension)"
79
+ if RUBY_PLATFORM =~ /java/
80
+ task :install => :install_pure
81
+ else
82
+ task :install => :install_ext
83
+ end
84
+
85
+ if defined?(Gem) and defined?(Rake::GemPackageTask)
86
+ spec_pure = Gem::Specification.new do |s|
87
+ s.name = 'json_pure'
88
+ s.version = PKG_VERSION
89
+ s.summary = PKG_TITLE
90
+ s.description = "This is a JSON implementation in pure Ruby."
91
+
92
+ s.files = PKG_FILES
93
+
94
+ s.require_path = 'lib'
95
+
96
+ s.bindir = "bin"
97
+ s.executables = [ "edit_json.rb", "prettify_json.rb" ]
98
+ s.default_executable = "edit_json.rb"
99
+
100
+ s.has_rdoc = true
101
+ s.extra_rdoc_files << 'README'
102
+ s.rdoc_options <<
103
+ '--title' << 'JSON implemention for ruby' << '--main' << 'README'
104
+ s.test_files.concat Dir['./tests/test_*.rb']
105
+
106
+ s.author = "Florian Frank"
107
+ s.email = "flori@ping.de"
108
+ s.homepage = "http://flori.github.com/#{PKG_NAME}"
109
+ s.rubyforge_project = "json"
110
+ end
111
+
112
+ Rake::GemPackageTask.new(spec_pure) do |pkg|
113
+ pkg.need_tar = true
114
+ pkg.package_files = PKG_FILES
115
+ end
116
+ end
117
+
118
+ if defined?(Gem) and defined?(Rake::GemPackageTask) and defined?(Rake::ExtensionTask)
119
+ spec_ext = Gem::Specification.new do |s|
120
+ s.name = 'json'
121
+ s.version = PKG_VERSION
122
+ s.summary = PKG_TITLE
123
+ s.description = "This is a JSON implementation as a Ruby extension in C."
124
+
125
+ s.files = PKG_FILES
126
+
127
+ s.extensions = FileList['ext/**/extconf.rb']
128
+
129
+ s.require_path = EXT_ROOT_DIR
130
+ s.require_paths << 'ext'
131
+ s.require_paths << 'lib'
132
+
133
+ s.bindir = "bin"
134
+ s.executables = [ "edit_json.rb", "prettify_json.rb" ]
135
+ s.default_executable = "edit_json.rb"
136
+
137
+ s.has_rdoc = true
138
+ s.extra_rdoc_files << 'README'
139
+ s.rdoc_options <<
140
+ '--title' << 'JSON implemention for Ruby' << '--main' << 'README'
141
+ s.test_files.concat Dir['./tests/test_*.rb']
142
+
143
+ s.author = "Florian Frank"
144
+ s.email = "flori@ping.de"
145
+ s.homepage = "http://flori.github.com/#{PKG_NAME}"
146
+ s.rubyforge_project = "json"
147
+ end
148
+
149
+ Rake::GemPackageTask.new(spec_ext) do |pkg|
150
+ pkg.need_tar = true
151
+ pkg.package_files = PKG_FILES
152
+ end
153
+
154
+ Rake::ExtensionTask.new do |ext|
155
+ ext.name = 'parser'
156
+ ext.gem_spec = spec_ext
157
+ ext.cross_compile = true
158
+ ext.cross_platform = %w[i386-mswin32 i386-mingw32]
159
+ ext.ext_dir = 'ext/json/ext/parser'
160
+ ext.lib_dir = 'lib/json/ext'
161
+ end
162
+
163
+ Rake::ExtensionTask.new do |ext|
164
+ ext.name = 'generator'
165
+ ext.gem_spec = spec_ext
166
+ ext.cross_compile = true
167
+ ext.cross_platform = %w[i386-mswin32 i386-mingw32]
168
+ ext.ext_dir = 'ext/json/ext/generator'
169
+ ext.lib_dir = 'lib/json/ext'
170
+ end
171
+ end
172
+
173
+ desc m = "Writing version information for #{PKG_VERSION}"
174
+ task :version do
175
+ puts m
176
+ File.open(File.join('lib', 'json', 'version.rb'), 'w') do |v|
177
+ v.puts <<EOT
178
+ module JSON
179
+ # JSON version
180
+ VERSION = '#{PKG_VERSION}'
181
+ VERSION_ARRAY = VERSION.split(/\\./).map { |x| x.to_i } # :nodoc:
182
+ VERSION_MAJOR = VERSION_ARRAY[0] # :nodoc:
183
+ VERSION_MINOR = VERSION_ARRAY[1] # :nodoc:
184
+ VERSION_BUILD = VERSION_ARRAY[2] # :nodoc:
185
+ end
186
+ EOT
187
+ end
188
+ end
189
+
190
+ desc "Testing library (pure ruby)"
191
+ task :test_pure => :clean do
192
+ ENV['JSON'] = 'pure'
193
+ ENV['RUBYOPT'] = "-Ilib #{ENV['RUBYOPT']}"
194
+ myruby '-S', 'testrb', *Dir['./tests/test_*.rb']
195
+ end
196
+
197
+ desc "Testing library (pure ruby and extension)"
198
+ task :test => [ :test_pure, :test_ext ]
199
+
200
+
201
+ if defined?(RUBY_ENGINE) and RUBY_ENGINE == 'jruby'
202
+ file JAVA_PARSER_SRC => JAVA_RAGEL_PATH do
203
+ cd JAVA_DIR do
204
+ if RAGEL_CODEGEN == 'ragel'
205
+ sh "ragel Parser.rl -J -o Parser.java"
206
+ else
207
+ sh "ragel -x Parser.rl | #{RAGEL_CODEGEN} -J"
208
+ end
209
+ end
210
+ end
211
+
212
+ desc "Generate parser for java with ragel"
213
+ task :ragel => JAVA_PARSER_SRC
214
+
215
+ desc "Delete the ragel generated Java source"
216
+ task :ragel_clean do
217
+ rm_rf JAVA_PARSER_SRC
218
+ end
219
+
220
+ JRUBY_JAR = File.join(Config::CONFIG["libdir"], "jruby.jar")
221
+ if File.exist?(JRUBY_JAR)
222
+ JAVA_SOURCES.each do |src|
223
+ classpath = (Dir['java/lib/*.jar'] << 'java/src' << JRUBY_JAR) * ':'
224
+ obj = src.sub(/\.java\Z/, '.class')
225
+ file obj => src do
226
+ sh 'javac', '-classpath', classpath, '-source', '1.5', src
227
+ end
228
+ JAVA_CLASSES << obj
229
+ end
230
+ else
231
+ warn "WARNING: Cannot find jruby in path => Cannot build jruby extension!"
232
+ end
233
+
234
+ desc "Compiling jruby extension"
235
+ task :compile_ext => JAVA_CLASSES
236
+
237
+ desc "Package the jruby gem"
238
+ task :jruby_gem => :create_jar do
239
+ sh 'gem build json-java.gemspec'
240
+ mkdir_p 'pkg'
241
+ mv "json-#{PKG_VERSION}-java.gem", 'pkg'
242
+ end
243
+
244
+ desc "Testing library (jruby)"
245
+ task :test_ext => :create_jar do
246
+ ENV['JSON'] = 'ext'
247
+ myruby '-S', 'testrb', '-Ilib', *Dir['./tests/test_*.rb']
248
+ end
249
+
250
+ file JRUBY_PARSER_JAR => :compile_ext do
251
+ cd 'java/src' do
252
+ parser_classes = FileList[
253
+ "json/ext/ByteListTranscoder*.class",
254
+ "json/ext/OptionsReader*.class",
255
+ "json/ext/Parser*.class",
256
+ "json/ext/RuntimeInfo*.class",
257
+ "json/ext/StringDecoder*.class",
258
+ "json/ext/Utils*.class"
259
+ ]
260
+ sh 'jar', 'cf', File.basename(JRUBY_PARSER_JAR), *parser_classes
261
+ mv File.basename(JRUBY_PARSER_JAR), File.dirname(JRUBY_PARSER_JAR)
262
+ end
263
+ end
264
+
265
+ desc "Create parser jar"
266
+ task :create_parser_jar => JRUBY_PARSER_JAR
267
+
268
+ file JRUBY_GENERATOR_JAR => :compile_ext do
269
+ cd 'java/src' do
270
+ generator_classes = FileList[
271
+ "json/ext/ByteListTranscoder*.class",
272
+ "json/ext/OptionsReader*.class",
273
+ "json/ext/Generator*.class",
274
+ "json/ext/RuntimeInfo*.class",
275
+ "json/ext/StringEncoder*.class",
276
+ "json/ext/Utils*.class"
277
+ ]
278
+ sh 'jar', 'cf', File.basename(JRUBY_GENERATOR_JAR), *generator_classes
279
+ mv File.basename(JRUBY_GENERATOR_JAR), File.dirname(JRUBY_GENERATOR_JAR)
280
+ end
281
+ end
282
+
283
+ desc "Create generator jar"
284
+ task :create_generator_jar => JRUBY_GENERATOR_JAR
285
+
286
+ desc "Create parser and generator jars"
287
+ task :create_jar => [ :create_parser_jar, :create_generator_jar ]
288
+
289
+ desc "Build all gems and archives for a new release of the jruby extension."
290
+ task :release => [ :clean, :version, :jruby_gem ]
291
+ else
292
+ desc "Compiling extension"
293
+ task :compile_ext => [ EXT_PARSER_DL, EXT_GENERATOR_DL ]
294
+
295
+ file EXT_PARSER_DL => EXT_PARSER_SRC do
296
+ cd EXT_PARSER_DIR do
297
+ myruby 'extconf.rb'
298
+ sh MAKE
299
+ end
300
+ cp "#{EXT_PARSER_DIR}/parser.#{CONFIG['DLEXT']}", EXT_ROOT_DIR
301
+ end
302
+
303
+ file EXT_GENERATOR_DL => EXT_GENERATOR_SRC do
304
+ cd EXT_GENERATOR_DIR do
305
+ myruby 'extconf.rb'
306
+ sh MAKE
307
+ end
308
+ cp "#{EXT_GENERATOR_DIR}/generator.#{CONFIG['DLEXT']}", EXT_ROOT_DIR
309
+ end
310
+
311
+ desc "Testing library (extension)"
312
+ task :test_ext => :compile_ext do
313
+ ENV['JSON'] = 'ext'
314
+ ENV['RUBYOPT'] = "-Iext:lib #{ENV['RUBYOPT']}"
315
+ myruby '-S', 'testrb', *Dir['./tests/test_*.rb']
316
+ end
317
+
318
+ desc "Benchmarking parser"
319
+ task :benchmark_parser do
320
+ ENV['RUBYOPT'] = "-Ilib:ext #{ENV['RUBYOPT']}"
321
+ myruby 'benchmarks/parser_benchmark.rb'
322
+ myruby 'benchmarks/parser2_benchmark.rb'
323
+ end
324
+
325
+ desc "Benchmarking generator"
326
+ task :benchmark_generator do
327
+ ENV['RUBYOPT'] = "-Ilib:ext #{ENV['RUBYOPT']}"
328
+ myruby 'benchmarks/generator_benchmark.rb'
329
+ myruby 'benchmarks/generator2_benchmark.rb'
330
+ end
331
+
332
+ desc "Benchmarking library"
333
+ task :benchmark => [ :benchmark_parser, :benchmark_generator ]
334
+
335
+ desc "Create RDOC documentation"
336
+ task :doc => [ :version, EXT_PARSER_SRC ] do
337
+ sh "sdoc -o doc -t '#{PKG_TITLE}' -m README README lib/json.rb #{FileList['lib/json/**/*.rb']} #{EXT_PARSER_SRC} #{EXT_GENERATOR_SRC}"
338
+ end
339
+
340
+ desc "Generate parser with ragel"
341
+ task :ragel => EXT_PARSER_SRC
342
+
343
+ desc "Delete the ragel generated C source"
344
+ task :ragel_clean do
345
+ rm_rf EXT_PARSER_SRC
346
+ end
347
+
348
+ file EXT_PARSER_SRC => RAGEL_PATH do
349
+ cd EXT_PARSER_DIR do
350
+ if RAGEL_CODEGEN == 'ragel'
351
+ sh "ragel parser.rl -G2 -o parser.c"
352
+ else
353
+ sh "ragel -x parser.rl | #{RAGEL_CODEGEN} -G2"
354
+ end
355
+ end
356
+ end
357
+
358
+ desc "Generate diagrams of ragel parser (ps)"
359
+ task :ragel_dot_ps do
360
+ root = 'diagrams'
361
+ specs = []
362
+ File.new(RAGEL_PATH).grep(/^\s*machine\s*(\S+);\s*$/) { specs << $1 }
363
+ for s in specs
364
+ if RAGEL_DOTGEN == 'ragel'
365
+ sh "ragel #{RAGEL_PATH} -S#{s} -p -V | dot -Tps -o#{root}/#{s}.ps"
366
+ else
367
+ sh "ragel -x #{RAGEL_PATH} -S#{s} | #{RAGEL_DOTGEN} -p|dot -Tps -o#{root}/#{s}.ps"
368
+ end
369
+ end
370
+ end
371
+
372
+ desc "Generate diagrams of ragel parser (png)"
373
+ task :ragel_dot_png do
374
+ root = 'diagrams'
375
+ specs = []
376
+ File.new(RAGEL_PATH).grep(/^\s*machine\s*(\S+);\s*$/) { specs << $1 }
377
+ for s in specs
378
+ if RAGEL_DOTGEN == 'ragel'
379
+ sh "ragel #{RAGEL_PATH} -S#{s} -p -V | dot -Tpng -o#{root}/#{s}.png"
380
+ else
381
+ sh "ragel -x #{RAGEL_PATH} -S#{s} | #{RAGEL_DOTGEN} -p|dot -Tpng -o#{root}/#{s}.png"
382
+ end
383
+ end
384
+ end
385
+
386
+ desc "Generate diagrams of ragel parser"
387
+ task :ragel_dot => [ :ragel_dot_png, :ragel_dot_ps ]
388
+
389
+ task :environment do
390
+ ENV['RUBY_CC_VERSION'] = '1.8.7:1.9.2'
391
+ end
392
+
393
+ desc "Build all gems and archives for a new release of json and json_pure."
394
+ task :release => [ :clean, :version, :environment, :cross, :native, :gem, ] do
395
+ sh "#$0 clean native gem"
396
+ sh "#$0 clean package"
397
+ end
398
+ end
399
+
400
+ desc "Compile in the the source directory"
401
+ task :default => [ :version ]