json 1.4.6 → 1.5.0
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 +6 -0
- data/COPYING-json-jruby +57 -0
- data/README-json-jruby.markdown +33 -0
- data/Rakefile +224 -119
- data/VERSION +1 -1
- data/benchmarks/generator2_benchmark.rb +1 -1
- data/benchmarks/generator_benchmark.rb +1 -1
- data/ext/json/ext/generator/generator.c +20 -20
- data/ext/json/ext/generator/generator.h +7 -7
- data/ext/json/ext/parser/extconf.rb +1 -0
- data/ext/json/ext/parser/parser.c +122 -88
- data/ext/json/ext/parser/parser.h +7 -0
- data/ext/json/ext/parser/parser.rl +54 -20
- data/java/lib/bytelist-1.0.6.jar +0 -0
- data/java/lib/jcodings.jar +0 -0
- data/java/src/json/ext/ByteListTranscoder.java +167 -0
- data/java/src/json/ext/Generator.java +441 -0
- data/java/src/json/ext/GeneratorMethods.java +231 -0
- data/java/src/json/ext/GeneratorService.java +42 -0
- data/java/src/json/ext/GeneratorState.java +473 -0
- data/java/src/json/ext/OptionsReader.java +119 -0
- data/java/src/json/ext/Parser.java +2295 -0
- data/java/src/json/ext/Parser.rl +825 -0
- data/java/src/json/ext/ParserService.java +34 -0
- data/java/src/json/ext/RuntimeInfo.java +119 -0
- data/java/src/json/ext/StringDecoder.java +166 -0
- data/java/src/json/ext/StringEncoder.java +106 -0
- data/java/src/json/ext/Utils.java +89 -0
- data/json-java.gemspec +20 -0
- data/lib/json/add/core.rb +1 -2
- data/lib/json/add/rails.rb +4 -54
- data/lib/json/common.rb +36 -8
- data/lib/json/editor.rb +1 -3
- data/lib/json/ext.rb +2 -2
- data/lib/json/pure.rb +2 -64
- data/lib/json/pure/generator.rb +10 -8
- data/lib/json/pure/parser.rb +23 -12
- data/lib/json/version.rb +1 -1
- data/tests/setup_variant.rb +11 -0
- data/tests/test_json.rb +1 -5
- data/tests/test_json_addition.rb +14 -9
- data/tests/test_json_encoding.rb +9 -12
- data/tests/test_json_fixtures.rb +9 -8
- data/tests/test_json_generate.rb +3 -5
- data/tests/test_json_string_matching.rb +40 -0
- data/tests/test_json_unicode.rb +1 -5
- metadata +51 -13
- data/tests/test_json_rails.rb +0 -144
data/json-java.gemspec
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
#! /usr/bin/env jruby
|
2
|
+
require "rubygems"
|
3
|
+
|
4
|
+
spec = Gem::Specification.new do |s|
|
5
|
+
s.name = "json"
|
6
|
+
s.version = File.read("VERSION").chomp
|
7
|
+
s.summary = "JSON implementation for JRuby"
|
8
|
+
s.description = "A JSON implementation as a JRuby extension."
|
9
|
+
s.author = "Daniel Luz"
|
10
|
+
s.email = "dev+ruby@mernen.com"
|
11
|
+
s.homepage = "http://json-jruby.rubyforge.org/"
|
12
|
+
s.platform = 'java'
|
13
|
+
s.rubyforge_project = "json-jruby"
|
14
|
+
|
15
|
+
s.files = Dir["{docs,lib,tests}/**/*"]
|
16
|
+
end
|
17
|
+
|
18
|
+
if $0 == __FILE__
|
19
|
+
Gem::Builder.new(spec).build
|
20
|
+
end
|
data/lib/json/add/core.rb
CHANGED
@@ -1,8 +1,7 @@
|
|
1
1
|
# This file contains implementations of ruby core's custom objects for
|
2
2
|
# serialisation/deserialisation.
|
3
3
|
|
4
|
-
unless
|
5
|
-
::JSON::JSON_LOADED
|
4
|
+
unless defined?(::JSON::JSON_LOADED) and ::JSON::JSON_LOADED
|
6
5
|
require 'json'
|
7
6
|
end
|
8
7
|
require 'date'
|
data/lib/json/add/rails.rb
CHANGED
@@ -1,58 +1,8 @@
|
|
1
|
-
# This file
|
2
|
-
# serialisation/deserialisation.
|
1
|
+
# This file used to implementations of rails custom objects for
|
2
|
+
# serialisation/deserialisation and is obsoleted now.
|
3
3
|
|
4
|
-
unless
|
5
|
-
::JSON::JSON_LOADED
|
4
|
+
unless defined?(::JSON::JSON_LOADED) and ::JSON::JSON_LOADED
|
6
5
|
require 'json'
|
7
6
|
end
|
8
7
|
|
9
|
-
|
10
|
-
def self.json_create(object)
|
11
|
-
obj = new
|
12
|
-
for key, value in object
|
13
|
-
next if key == JSON.create_id
|
14
|
-
instance_variable_set "@#{key}", value
|
15
|
-
end
|
16
|
-
obj
|
17
|
-
end
|
18
|
-
|
19
|
-
def to_json(*a)
|
20
|
-
result = {
|
21
|
-
JSON.create_id => self.class.name
|
22
|
-
}
|
23
|
-
instance_variables.inject(result) do |r, name|
|
24
|
-
r[name[1..-1]] = instance_variable_get name
|
25
|
-
r
|
26
|
-
end
|
27
|
-
result.to_json(*a)
|
28
|
-
end
|
29
|
-
end
|
30
|
-
|
31
|
-
class Symbol
|
32
|
-
def to_json(*a)
|
33
|
-
to_s.to_json(*a)
|
34
|
-
end
|
35
|
-
end
|
36
|
-
|
37
|
-
module Enumerable
|
38
|
-
def to_json(*a)
|
39
|
-
to_a.to_json(*a)
|
40
|
-
end
|
41
|
-
end
|
42
|
-
|
43
|
-
# class Regexp
|
44
|
-
# def to_json(*)
|
45
|
-
# inspect
|
46
|
-
# end
|
47
|
-
# end
|
48
|
-
#
|
49
|
-
# The above rails definition has some problems:
|
50
|
-
#
|
51
|
-
# 1. { 'foo' => /bar/ }.to_json # => "{foo: /bar/}"
|
52
|
-
# This isn't valid JSON, because the regular expression syntax is not
|
53
|
-
# defined in RFC 4627. (And unquoted strings are disallowed there, too.)
|
54
|
-
# Though it is valid Javascript.
|
55
|
-
#
|
56
|
-
# 2. { 'foo' => /bar/mix }.to_json # => "{foo: /bar/mix}"
|
57
|
-
# This isn't even valid Javascript.
|
58
|
-
|
8
|
+
$DEBUG and warn "required json/add/rails which is obsolete now!"
|
data/lib/json/common.rb
CHANGED
@@ -1,5 +1,4 @@
|
|
1
1
|
require 'json/version'
|
2
|
-
require 'iconv'
|
3
2
|
|
4
3
|
module JSON
|
5
4
|
class << self
|
@@ -24,7 +23,7 @@ module JSON
|
|
24
23
|
# Set the JSON parser class _parser_ to be used by JSON.
|
25
24
|
def parser=(parser) # :nodoc:
|
26
25
|
@parser = parser
|
27
|
-
remove_const :Parser if
|
26
|
+
remove_const :Parser if JSON.const_defined_in?(self, :Parser)
|
28
27
|
const_set :Parser, parser
|
29
28
|
end
|
30
29
|
|
@@ -35,13 +34,13 @@ module JSON
|
|
35
34
|
def deep_const_get(path) # :nodoc:
|
36
35
|
path.to_s.split(/::/).inject(Object) do |p, c|
|
37
36
|
case
|
38
|
-
when c.empty?
|
39
|
-
when
|
37
|
+
when c.empty? then p
|
38
|
+
when JSON.const_defined_in?(p, c) then p.const_get(c)
|
40
39
|
else
|
41
40
|
begin
|
42
41
|
p.const_missing(c)
|
43
|
-
rescue NameError
|
44
|
-
raise ArgumentError, "can't
|
42
|
+
rescue NameError => e
|
43
|
+
raise ArgumentError, "can't get const #{path}: #{e}"
|
45
44
|
end
|
46
45
|
end
|
47
46
|
end
|
@@ -49,6 +48,7 @@ module JSON
|
|
49
48
|
|
50
49
|
# Set the module _generator_ to be used by JSON.
|
51
50
|
def generator=(generator) # :nodoc:
|
51
|
+
old, $VERBOSE = $VERBOSE, nil
|
52
52
|
@generator = generator
|
53
53
|
generator_methods = generator::GeneratorMethods
|
54
54
|
for const in generator_methods.constants
|
@@ -77,6 +77,8 @@ module JSON
|
|
77
77
|
:object_nl => "\n",
|
78
78
|
:array_nl => "\n"
|
79
79
|
)
|
80
|
+
ensure
|
81
|
+
$VERBOSE = old
|
80
82
|
end
|
81
83
|
|
82
84
|
# Returns the JSON generator modul, that is used by JSON. This might be
|
@@ -338,9 +340,35 @@ module JSON
|
|
338
340
|
raise ArgumentError, "exceed depth limit"
|
339
341
|
end
|
340
342
|
|
343
|
+
# Swap consecutive bytes of _string_ in place.
|
344
|
+
def self.swap!(string) # :nodoc:
|
345
|
+
0.upto(string.size / 2) do |i|
|
346
|
+
break unless string[2 * i + 1]
|
347
|
+
string[2 * i], string[2 * i + 1] = string[2 * i + 1], string[2 * i]
|
348
|
+
end
|
349
|
+
string
|
350
|
+
end
|
351
|
+
|
341
352
|
# Shortuct for iconv.
|
342
|
-
|
343
|
-
|
353
|
+
if ::String.method_defined?(:encode)
|
354
|
+
def self.iconv(to, from, string)
|
355
|
+
string.encode(to, from)
|
356
|
+
end
|
357
|
+
else
|
358
|
+
require 'iconv'
|
359
|
+
def self.iconv(to, from, string)
|
360
|
+
Iconv.iconv(to, from, string).first
|
361
|
+
end
|
362
|
+
end
|
363
|
+
|
364
|
+
if ::Object.method(:const_defined?).arity == 1
|
365
|
+
def self.const_defined_in?(modul, constant)
|
366
|
+
modul.const_defined?(constant)
|
367
|
+
end
|
368
|
+
else
|
369
|
+
def self.const_defined_in?(modul, constant)
|
370
|
+
modul.const_defined?(constant, false)
|
371
|
+
end
|
344
372
|
end
|
345
373
|
end
|
346
374
|
|
data/lib/json/editor.rb
CHANGED
@@ -2,7 +2,6 @@
|
|
2
2
|
# requires ruby-gtk to be installed.
|
3
3
|
|
4
4
|
require 'gtk2'
|
5
|
-
require 'iconv'
|
6
5
|
require 'json'
|
7
6
|
require 'rbconfig'
|
8
7
|
require 'open-uri'
|
@@ -1272,8 +1271,7 @@ module JSON
|
|
1272
1271
|
def parse_json(json)
|
1273
1272
|
check_pretty_printed(json)
|
1274
1273
|
if @encoding && !/^utf8$/i.match(@encoding)
|
1275
|
-
|
1276
|
-
json = iconverter.iconv(json)
|
1274
|
+
json = JSON.iconv 'utf-8', @encoding, json
|
1277
1275
|
end
|
1278
1276
|
JSON::parse(json, :max_nesting => false, :create_additions => false)
|
1279
1277
|
end
|
data/lib/json/ext.rb
CHANGED
@@ -6,10 +6,10 @@ module JSON
|
|
6
6
|
module Ext
|
7
7
|
require 'json/ext/parser'
|
8
8
|
require 'json/ext/generator'
|
9
|
-
$DEBUG and warn "Using
|
9
|
+
$DEBUG and warn "Using Ext extension for JSON."
|
10
10
|
JSON.parser = Parser
|
11
11
|
JSON.generator = Generator
|
12
12
|
end
|
13
13
|
|
14
|
-
JSON_LOADED = true
|
14
|
+
JSON_LOADED = true unless defined?(::JSON::JSON_LOADED)
|
15
15
|
end
|
data/lib/json/pure.rb
CHANGED
@@ -3,75 +3,13 @@ require 'json/pure/parser'
|
|
3
3
|
require 'json/pure/generator'
|
4
4
|
|
5
5
|
module JSON
|
6
|
-
begin
|
7
|
-
require 'iconv'
|
8
|
-
# An iconv instance to convert from UTF8 to UTF16 Big Endian.
|
9
|
-
UTF16toUTF8 = Iconv.new('utf-8', 'utf-16be') # :nodoc:
|
10
|
-
# An iconv instance to convert from UTF16 Big Endian to UTF8.
|
11
|
-
UTF8toUTF16 = Iconv.new('utf-16be', 'utf-8') # :nodoc:
|
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"
|
16
|
-
rescue Errno::EINVAL, Iconv::InvalidEncoding
|
17
|
-
# Iconv doesn't support big endian utf-16. Let's try to hack this manually
|
18
|
-
# into the converters.
|
19
|
-
begin
|
20
|
-
old_verbose, $VERBSOSE = $VERBOSE, nil
|
21
|
-
# An iconv instance to convert from UTF8 to UTF16 Big Endian.
|
22
|
-
UTF16toUTF8 = Iconv.new('utf-8', 'utf-16') # :nodoc:
|
23
|
-
# An iconv instance to convert from UTF16 Big Endian to UTF8.
|
24
|
-
UTF8toUTF16 = Iconv.new('utf-16', 'utf-8') # :nodoc:
|
25
|
-
UTF8toUTF16.iconv('no bom')
|
26
|
-
if UTF8toUTF16.iconv("\xe2\x82\xac") == "\xac\x20"
|
27
|
-
swapper = Class.new do
|
28
|
-
def initialize(iconv) # :nodoc:
|
29
|
-
@iconv = iconv
|
30
|
-
end
|
31
|
-
|
32
|
-
def iconv(string) # :nodoc:
|
33
|
-
result = @iconv.iconv(string)
|
34
|
-
JSON.swap!(result)
|
35
|
-
end
|
36
|
-
end
|
37
|
-
UTF8toUTF16 = swapper.new(UTF8toUTF16) # :nodoc:
|
38
|
-
end
|
39
|
-
if UTF16toUTF8.iconv("\xac\x20") == "\xe2\x82\xac"
|
40
|
-
swapper = Class.new do
|
41
|
-
def initialize(iconv) # :nodoc:
|
42
|
-
@iconv = iconv
|
43
|
-
end
|
44
|
-
|
45
|
-
def iconv(string) # :nodoc:
|
46
|
-
string = JSON.swap!(string.dup)
|
47
|
-
@iconv.iconv(string)
|
48
|
-
end
|
49
|
-
end
|
50
|
-
UTF16toUTF8 = swapper.new(UTF16toUTF8) # :nodoc:
|
51
|
-
end
|
52
|
-
rescue Errno::EINVAL, Iconv::InvalidEncoding
|
53
|
-
raise MissingUnicodeSupport, "iconv doesn't seem to support UTF-8/UTF-16 conversions"
|
54
|
-
ensure
|
55
|
-
$VERBOSE = old_verbose
|
56
|
-
end
|
57
|
-
end
|
58
|
-
|
59
|
-
# Swap consecutive bytes of _string_ in place.
|
60
|
-
def self.swap!(string) # :nodoc:
|
61
|
-
0.upto(string.size / 2) do |i|
|
62
|
-
break unless string[2 * i + 1]
|
63
|
-
string[2 * i], string[2 * i + 1] = string[2 * i + 1], string[2 * i]
|
64
|
-
end
|
65
|
-
string
|
66
|
-
end
|
67
|
-
|
68
6
|
# This module holds all the modules/classes that implement JSON's
|
69
7
|
# functionality in pure ruby.
|
70
8
|
module Pure
|
71
|
-
$DEBUG and warn "Using
|
9
|
+
$DEBUG and warn "Using Pure library for JSON."
|
72
10
|
JSON.parser = Parser
|
73
11
|
JSON.generator = Generator
|
74
12
|
end
|
75
13
|
|
76
|
-
JSON_LOADED = true
|
14
|
+
JSON_LOADED = true unless defined?(::JSON::JSON_LOADED)
|
77
15
|
end
|
data/lib/json/pure/generator.rb
CHANGED
@@ -62,12 +62,12 @@ module JSON
|
|
62
62
|
[\x80-\xc1\xf5-\xff] # invalid
|
63
63
|
)/nx) { |c|
|
64
64
|
c.size == 1 and raise GeneratorError, "invalid utf8 byte: '#{c}'"
|
65
|
-
s = JSON
|
65
|
+
s = JSON.iconv('utf-16be', 'utf-8', c).unpack('H*')[0]
|
66
66
|
s.gsub!(/.{4}/n, '\\\\u\&')
|
67
67
|
}
|
68
68
|
string.force_encoding(::Encoding::UTF_8)
|
69
69
|
string
|
70
|
-
rescue
|
70
|
+
rescue => e
|
71
71
|
raise GeneratorError, "Caught #{e.class}: #{e}"
|
72
72
|
end
|
73
73
|
else
|
@@ -86,11 +86,11 @@ module JSON
|
|
86
86
|
[\x80-\xc1\xf5-\xff] # invalid
|
87
87
|
)/nx) { |c|
|
88
88
|
c.size == 1 and raise GeneratorError, "invalid utf8 byte: '#{c}'"
|
89
|
-
s = JSON
|
89
|
+
s = JSON.iconv('utf-16be', 'utf-8', c).unpack('H*')[0]
|
90
90
|
s.gsub!(/.{4}/n, '\\\\u\&')
|
91
91
|
}
|
92
92
|
string
|
93
|
-
rescue
|
93
|
+
rescue => e
|
94
94
|
raise GeneratorError, "Caught #{e.class}: #{e}"
|
95
95
|
end
|
96
96
|
end
|
@@ -106,11 +106,13 @@ module JSON
|
|
106
106
|
# an unconfigured instance. If _opts_ is a State object, it is just
|
107
107
|
# returned.
|
108
108
|
def self.from_state(opts)
|
109
|
-
case
|
110
|
-
when self
|
109
|
+
case
|
110
|
+
when self === opts
|
111
111
|
opts
|
112
|
-
when
|
113
|
-
new(opts)
|
112
|
+
when opts.respond_to?(:to_hash)
|
113
|
+
new(opts.to_hash)
|
114
|
+
when opts.respond_to?(:to_h)
|
115
|
+
new(opts.to_h)
|
114
116
|
else
|
115
117
|
SAFE_STATE_PROTOTYPE.dup
|
116
118
|
end
|
data/lib/json/pure/parser.rb
CHANGED
@@ -113,13 +113,13 @@ module JSON
|
|
113
113
|
else
|
114
114
|
@max_nesting = 0
|
115
115
|
end
|
116
|
-
@allow_nan
|
117
|
-
@symbolize_names
|
118
|
-
|
119
|
-
|
120
|
-
@
|
121
|
-
@
|
122
|
-
@
|
116
|
+
@allow_nan = !!opts[:allow_nan]
|
117
|
+
@symbolize_names = !!opts[:symbolize_names]
|
118
|
+
@create_additions = opts.key?(:create_additions) ? !!opts[:create_additions] : true
|
119
|
+
@create_id = opts[:create_id] || JSON.create_id
|
120
|
+
@object_class = opts[:object_class] || Hash
|
121
|
+
@array_class = opts[:array_class] || Array
|
122
|
+
@match_string = opts[:match_string]
|
123
123
|
end
|
124
124
|
|
125
125
|
alias source string
|
@@ -165,6 +165,11 @@ module JSON
|
|
165
165
|
?u => nil,
|
166
166
|
})
|
167
167
|
|
168
|
+
EMPTY_8BIT_STRING = ''
|
169
|
+
if ::String.method_defined?(:encode)
|
170
|
+
EMPTY_8BIT_STRING.force_encoding Encoding::ASCII_8BIT
|
171
|
+
end
|
172
|
+
|
168
173
|
def parse_string
|
169
174
|
if scan(STRING)
|
170
175
|
return '' if self[1].empty?
|
@@ -172,24 +177,30 @@ module JSON
|
|
172
177
|
if u = UNESCAPE_MAP[$&[1]]
|
173
178
|
u
|
174
179
|
else # \uXXXX
|
175
|
-
bytes =
|
180
|
+
bytes = EMPTY_8BIT_STRING.dup
|
176
181
|
i = 0
|
177
182
|
while c[6 * i] == ?\\ && c[6 * i + 1] == ?u
|
178
183
|
bytes << c[6 * i + 2, 2].to_i(16) << c[6 * i + 4, 2].to_i(16)
|
179
184
|
i += 1
|
180
185
|
end
|
181
|
-
JSON
|
186
|
+
JSON.iconv('utf-8', 'utf-16be', bytes)
|
182
187
|
end
|
183
188
|
end
|
184
189
|
if string.respond_to?(:force_encoding)
|
185
190
|
string.force_encoding(::Encoding::UTF_8)
|
186
191
|
end
|
192
|
+
if @create_additions and @match_string
|
193
|
+
for (regexp, klass) in @match_string
|
194
|
+
klass.json_creatable? or next
|
195
|
+
string =~ regexp and return klass.json_create(string)
|
196
|
+
end
|
197
|
+
end
|
187
198
|
string
|
188
199
|
else
|
189
200
|
UNPARSED
|
190
201
|
end
|
191
|
-
rescue
|
192
|
-
raise
|
202
|
+
rescue => e
|
203
|
+
raise ParserError, "Caught #{e.class} at '#{peek(20)}': #{e}"
|
193
204
|
end
|
194
205
|
|
195
206
|
def parse_value
|
@@ -290,7 +301,7 @@ module JSON
|
|
290
301
|
if delim
|
291
302
|
raise ParserError, "expected next name, value pair in object at '#{peek(20)}'!"
|
292
303
|
end
|
293
|
-
if @
|
304
|
+
if @create_additions and klassname = result[@create_id]
|
294
305
|
klass = JSON.deep_const_get klassname
|
295
306
|
break unless klass and klass.json_creatable?
|
296
307
|
result = klass.json_create(result)
|
data/lib/json/version.rb
CHANGED
data/tests/test_json.rb
CHANGED
@@ -2,11 +2,7 @@
|
|
2
2
|
# -*- coding: utf-8 -*-
|
3
3
|
|
4
4
|
require 'test/unit'
|
5
|
-
|
6
|
-
when 'pure' then require 'json/pure'
|
7
|
-
when 'ext' then require 'json/ext'
|
8
|
-
else require 'json'
|
9
|
-
end
|
5
|
+
require File.join(File.dirname(__FILE__), 'setup_variant')
|
10
6
|
require 'stringio'
|
11
7
|
|
12
8
|
unless Array.method_defined?(:permutation)
|