scout 5.1.2 → 5.1.3
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +5 -0
- data/lib/scout.rb +1 -1
- data/lib/scout/server.rb +4 -1
- data/vendor/json_pure/CHANGES +43 -0
- data/vendor/json_pure/{RUBY → COPYING} +1 -1
- data/vendor/json_pure/GPL +7 -7
- data/vendor/json_pure/README +319 -39
- data/vendor/json_pure/Rakefile +69 -47
- data/vendor/json_pure/VERSION +1 -1
- data/vendor/json_pure/benchmarks/generator2_benchmark.rb +222 -0
- data/vendor/json_pure/benchmarks/generator_benchmark.rb +64 -5
- data/vendor/json_pure/benchmarks/ohai.json +1216 -0
- data/vendor/json_pure/benchmarks/ohai.ruby +1 -0
- data/vendor/json_pure/benchmarks/parser2_benchmark.rb +251 -0
- data/vendor/json_pure/benchmarks/parser_benchmark.rb +67 -5
- data/vendor/json_pure/ext/json/ext/generator/extconf.rb +9 -4
- data/vendor/json_pure/ext/json/ext/generator/generator.c +831 -409
- data/vendor/json_pure/ext/json/ext/generator/generator.h +170 -0
- data/vendor/json_pure/ext/json/ext/parser/extconf.rb +8 -4
- data/vendor/json_pure/ext/json/ext/parser/parser.c +292 -186
- data/vendor/json_pure/ext/json/ext/parser/parser.h +71 -0
- data/vendor/json_pure/ext/json/ext/parser/parser.rl +218 -112
- data/vendor/json_pure/lib/json/add/core.rb +20 -7
- data/vendor/json_pure/lib/json/add/rails.rb +2 -2
- data/vendor/json_pure/lib/json/common.rb +85 -42
- data/vendor/json_pure/lib/json/pure.rb +3 -3
- data/vendor/json_pure/lib/json/pure/generator.rb +112 -90
- data/vendor/json_pure/lib/json/pure/parser.rb +42 -4
- data/vendor/json_pure/lib/json/version.rb +1 -1
- data/vendor/json_pure/tests/test_json.rb +46 -18
- data/vendor/json_pure/tests/test_json_addition.rb +4 -6
- data/vendor/json_pure/tests/test_json_encoding.rb +68 -0
- data/vendor/json_pure/tests/test_json_generate.rb +30 -14
- data/vendor/json_pure/tests/test_json_rails.rb +5 -7
- data/vendor/json_pure/tests/test_json_unicode.rb +20 -6
- metadata +26 -15
- data/vendor/json_pure/doc-templates/main.txt +0 -283
- data/vendor/json_pure/ext/json/ext/generator/unicode.c +0 -182
- data/vendor/json_pure/ext/json/ext/generator/unicode.h +0 -53
- data/vendor/json_pure/ext/json/ext/parser/unicode.c +0 -154
- data/vendor/json_pure/ext/json/ext/parser/unicode.h +0 -58
@@ -7,6 +7,19 @@ unless Object.const_defined?(:JSON) and ::JSON.const_defined?(:JSON_LOADED) and
|
|
7
7
|
end
|
8
8
|
require 'date'
|
9
9
|
|
10
|
+
class Symbol
|
11
|
+
def to_json(*a)
|
12
|
+
{
|
13
|
+
JSON.create_id => self.class.name,
|
14
|
+
's' => to_s,
|
15
|
+
}.to_json(*a)
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.json_create(o)
|
19
|
+
o['s'].to_sym
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
10
23
|
class Time
|
11
24
|
def self.json_create(object)
|
12
25
|
if usec = object.delete('u') # used to be tv_usec -> tv_nsec
|
@@ -21,7 +34,7 @@ class Time
|
|
21
34
|
|
22
35
|
def to_json(*args)
|
23
36
|
{
|
24
|
-
|
37
|
+
JSON.create_id => self.class.name,
|
25
38
|
's' => tv_sec,
|
26
39
|
'n' => respond_to?(:tv_nsec) ? tv_nsec : tv_usec * 1000
|
27
40
|
}.to_json(*args)
|
@@ -37,7 +50,7 @@ class Date
|
|
37
50
|
|
38
51
|
def to_json(*args)
|
39
52
|
{
|
40
|
-
|
53
|
+
JSON.create_id => self.class.name,
|
41
54
|
'y' => year,
|
42
55
|
'm' => month,
|
43
56
|
'd' => day,
|
@@ -63,7 +76,7 @@ class DateTime
|
|
63
76
|
|
64
77
|
def to_json(*args)
|
65
78
|
{
|
66
|
-
|
79
|
+
JSON.create_id => self.class.name,
|
67
80
|
'y' => year,
|
68
81
|
'm' => month,
|
69
82
|
'd' => day,
|
@@ -83,7 +96,7 @@ class Range
|
|
83
96
|
|
84
97
|
def to_json(*args)
|
85
98
|
{
|
86
|
-
|
99
|
+
JSON.create_id => self.class.name,
|
87
100
|
'a' => [ first, last, exclude_end? ]
|
88
101
|
}.to_json(*args)
|
89
102
|
end
|
@@ -98,7 +111,7 @@ class Struct
|
|
98
111
|
klass = self.class.name
|
99
112
|
klass.to_s.empty? and raise JSON::JSONError, "Only named structs are supported!"
|
100
113
|
{
|
101
|
-
|
114
|
+
JSON.create_id => klass,
|
102
115
|
'v' => values,
|
103
116
|
}.to_json(*args)
|
104
117
|
end
|
@@ -113,7 +126,7 @@ class Exception
|
|
113
126
|
|
114
127
|
def to_json(*args)
|
115
128
|
{
|
116
|
-
|
129
|
+
JSON.create_id => self.class.name,
|
117
130
|
'm' => message,
|
118
131
|
'b' => backtrace,
|
119
132
|
}.to_json(*args)
|
@@ -127,7 +140,7 @@ class Regexp
|
|
127
140
|
|
128
141
|
def to_json(*)
|
129
142
|
{
|
130
|
-
|
143
|
+
JSON.create_id => self.class.name,
|
131
144
|
'o' => options,
|
132
145
|
's' => source,
|
133
146
|
}.to_json
|
@@ -10,7 +10,7 @@ class Object
|
|
10
10
|
def self.json_create(object)
|
11
11
|
obj = new
|
12
12
|
for key, value in object
|
13
|
-
next if key ==
|
13
|
+
next if key == JSON.create_id
|
14
14
|
instance_variable_set "@#{key}", value
|
15
15
|
end
|
16
16
|
obj
|
@@ -18,7 +18,7 @@ class Object
|
|
18
18
|
|
19
19
|
def to_json(*a)
|
20
20
|
result = {
|
21
|
-
|
21
|
+
JSON.create_id => self.class.name
|
22
22
|
}
|
23
23
|
instance_variables.inject(result) do |r, name|
|
24
24
|
r[name[1..-1]] = instance_variable_get name
|
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'json/version'
|
2
|
+
require 'iconv'
|
2
3
|
|
3
4
|
module JSON
|
4
5
|
class << self
|
@@ -32,12 +33,16 @@ module JSON
|
|
32
33
|
# level (absolute namespace path?). If there doesn't exist a constant at
|
33
34
|
# the given path, an ArgumentError is raised.
|
34
35
|
def deep_const_get(path) # :nodoc:
|
35
|
-
path
|
36
|
-
path.split(/::/).inject(Object) do |p, c|
|
36
|
+
path.to_s.split(/::/).inject(Object) do |p, c|
|
37
37
|
case
|
38
38
|
when c.empty? then p
|
39
39
|
when p.const_defined?(c) then p.const_get(c)
|
40
|
-
else
|
40
|
+
else
|
41
|
+
begin
|
42
|
+
p.const_missing(c)
|
43
|
+
rescue NameError
|
44
|
+
raise ArgumentError, "can't find const #{path}"
|
45
|
+
end
|
41
46
|
end
|
42
47
|
end
|
43
48
|
end
|
@@ -58,6 +63,20 @@ module JSON
|
|
58
63
|
end
|
59
64
|
self.state = generator::State
|
60
65
|
const_set :State, self.state
|
66
|
+
const_set :SAFE_STATE_PROTOTYPE, State.new.freeze
|
67
|
+
const_set :FAST_STATE_PROTOTYPE, State.new(
|
68
|
+
:indent => '',
|
69
|
+
:space => '',
|
70
|
+
:object_nl => "",
|
71
|
+
:array_nl => "",
|
72
|
+
:max_nesting => false
|
73
|
+
).freeze
|
74
|
+
const_set :PRETTY_STATE_PROTOTYPE, State.new(
|
75
|
+
:indent => ' ',
|
76
|
+
:space => ' ',
|
77
|
+
:object_nl => "\n",
|
78
|
+
:array_nl => "\n"
|
79
|
+
).freeze
|
61
80
|
end
|
62
81
|
|
63
82
|
# Returns the JSON generator modul, that is used by JSON. This might be
|
@@ -74,7 +93,7 @@ module JSON
|
|
74
93
|
end
|
75
94
|
self.create_id = 'json_class'
|
76
95
|
|
77
|
-
NaN =
|
96
|
+
NaN = 0.0/0
|
78
97
|
|
79
98
|
Infinity = 1.0/0
|
80
99
|
|
@@ -90,22 +109,22 @@ module JSON
|
|
90
109
|
# deep.
|
91
110
|
class NestingError < ParserError; end
|
92
111
|
|
112
|
+
# :stopdoc:
|
113
|
+
class CircularDatastructure < NestingError; end
|
114
|
+
# :startdoc:
|
115
|
+
|
93
116
|
# This exception is raised, if a generator or unparser error occurs.
|
94
117
|
class GeneratorError < JSONError; end
|
95
118
|
# For backwards compatibility
|
96
119
|
UnparserError = GeneratorError
|
97
120
|
|
98
|
-
# If a circular data structure is encountered while unparsing
|
99
|
-
# this exception is raised.
|
100
|
-
class CircularDatastructure < GeneratorError; end
|
101
|
-
|
102
121
|
# This exception is raised, if the required unicode support is missing on the
|
103
122
|
# system. Usually this means, that the iconv library is not installed.
|
104
123
|
class MissingUnicodeSupport < JSONError; end
|
105
124
|
|
106
125
|
module_function
|
107
126
|
|
108
|
-
# Parse the JSON
|
127
|
+
# Parse the JSON document _source_ into a Ruby data structure and return it.
|
109
128
|
#
|
110
129
|
# _opts_ can have the following
|
111
130
|
# keys:
|
@@ -115,16 +134,21 @@ module JSON
|
|
115
134
|
# * *allow_nan*: If set to true, allow NaN, Infinity and -Infinity in
|
116
135
|
# defiance of RFC 4627 to be parsed by the Parser. This option defaults
|
117
136
|
# to false.
|
137
|
+
# * *symbolize_names*: If set to true, returns symbols for the names
|
138
|
+
# (keys) in a JSON object. Otherwise strings are returned, which is also
|
139
|
+
# the default.
|
118
140
|
# * *create_additions*: If set to false, the Parser doesn't create
|
119
141
|
# additions even if a matchin class and create_id was found. This option
|
120
142
|
# defaults to true.
|
143
|
+
# * *object_class*: Defaults to Hash
|
144
|
+
# * *array_class*: Defaults to Array
|
121
145
|
def parse(source, opts = {})
|
122
|
-
|
146
|
+
Parser.new(source, opts).parse
|
123
147
|
end
|
124
148
|
|
125
|
-
# Parse the JSON
|
149
|
+
# Parse the JSON document _source_ into a Ruby data structure and return it.
|
126
150
|
# The bang version of the parse method, defaults to the more dangerous values
|
127
|
-
# for the _opts_ hash, so be sure only to parse trusted _source_
|
151
|
+
# for the _opts_ hash, so be sure only to parse trusted _source_ documents.
|
128
152
|
#
|
129
153
|
# _opts_ can have the following keys:
|
130
154
|
# * *max_nesting*: The maximum depth of nesting allowed in the parsed data
|
@@ -139,15 +163,14 @@ module JSON
|
|
139
163
|
# defaults to true.
|
140
164
|
def parse!(source, opts = {})
|
141
165
|
opts = {
|
142
|
-
:max_nesting
|
143
|
-
:allow_nan
|
166
|
+
:max_nesting => false,
|
167
|
+
:allow_nan => true
|
144
168
|
}.update(opts)
|
145
|
-
|
169
|
+
Parser.new(source, opts).parse
|
146
170
|
end
|
147
171
|
|
148
|
-
#
|
149
|
-
#
|
150
|
-
# * a JSON::State object,
|
172
|
+
# Generate a JSON document from the Ruby data structure _obj_ and return
|
173
|
+
# it. _state_ is * a JSON::State object,
|
151
174
|
# * or a Hash like object (responding to to_hash),
|
152
175
|
# * an object convertible into a hash by a to_h method,
|
153
176
|
# that is used as or to configure a State object.
|
@@ -162,8 +185,6 @@ module JSON
|
|
162
185
|
# * *space_before*: a string that is put before a : pair delimiter (default: ''),
|
163
186
|
# * *object_nl*: a string that is put at the end of a JSON object (default: ''),
|
164
187
|
# * *array_nl*: a string that is put at the end of a JSON array (default: ''),
|
165
|
-
# * *check_circular*: true if checking for circular data structures
|
166
|
-
# should be done (the default), false otherwise.
|
167
188
|
# * *allow_nan*: true if NaN, Infinity, and -Infinity should be
|
168
189
|
# generated, otherwise an exception is thrown, if these values are
|
169
190
|
# encountered. This options defaults to false.
|
@@ -174,13 +195,21 @@ module JSON
|
|
174
195
|
# See also the fast_generate for the fastest creation method with the least
|
175
196
|
# amount of sanity checks, and the pretty_generate method for some
|
176
197
|
# defaults for a pretty output.
|
177
|
-
def generate(obj,
|
178
|
-
if
|
179
|
-
|
198
|
+
def generate(obj, opts = nil)
|
199
|
+
if opts
|
200
|
+
if opts.respond_to? :to_hash
|
201
|
+
opts = opts.to_hash
|
202
|
+
elsif opts.respond_to? :to_h
|
203
|
+
opts = opts.to_h
|
204
|
+
else
|
205
|
+
raise TypeError, "can't convert #{opts.class} into Hash"
|
206
|
+
end
|
207
|
+
state = SAFE_STATE_PROTOTYPE.dup
|
208
|
+
state = state.configure(opts)
|
180
209
|
else
|
181
|
-
state =
|
210
|
+
state = SAFE_STATE_PROTOTYPE
|
182
211
|
end
|
183
|
-
|
212
|
+
state.generate(obj)
|
184
213
|
end
|
185
214
|
|
186
215
|
# :stopdoc:
|
@@ -190,14 +219,26 @@ module JSON
|
|
190
219
|
module_function :unparse
|
191
220
|
# :startdoc:
|
192
221
|
|
193
|
-
#
|
194
|
-
#
|
195
|
-
# also generates NaN, Infinity, and, -Infinity float values.
|
222
|
+
# Generate a JSON document from the Ruby data structure _obj_ and return it.
|
223
|
+
# This method disables the checks for circles in Ruby objects.
|
196
224
|
#
|
197
225
|
# *WARNING*: Be careful not to pass any Ruby data structures with circles as
|
198
226
|
# _obj_ argument, because this will cause JSON to go into an infinite loop.
|
199
|
-
def fast_generate(obj)
|
200
|
-
|
227
|
+
def fast_generate(obj, opts = nil)
|
228
|
+
if opts
|
229
|
+
if opts.respond_to? :to_hash
|
230
|
+
opts = opts.to_hash
|
231
|
+
elsif opts.respond_to? :to_h
|
232
|
+
opts = opts.to_h
|
233
|
+
else
|
234
|
+
raise TypeError, "can't convert #{opts.class} into Hash"
|
235
|
+
end
|
236
|
+
state = FAST_STATE_PROTOTYPE.dup
|
237
|
+
state.configure(opts)
|
238
|
+
else
|
239
|
+
state = FAST_STATE_PROTOTYPE
|
240
|
+
end
|
241
|
+
state.generate(obj)
|
201
242
|
end
|
202
243
|
|
203
244
|
# :stopdoc:
|
@@ -206,19 +247,13 @@ module JSON
|
|
206
247
|
module_function :fast_unparse
|
207
248
|
# :startdoc:
|
208
249
|
|
209
|
-
#
|
210
|
-
# returned
|
250
|
+
# Generate a JSON document from the Ruby data structure _obj_ and return it.
|
251
|
+
# The returned document is a prettier form of the document returned by
|
252
|
+
# #unparse.
|
211
253
|
#
|
212
254
|
# The _opts_ argument can be used to configure the generator, see the
|
213
255
|
# generate method for a more detailed explanation.
|
214
256
|
def pretty_generate(obj, opts = nil)
|
215
|
-
state = JSON.state.new(
|
216
|
-
:indent => ' ',
|
217
|
-
:space => ' ',
|
218
|
-
:object_nl => "\n",
|
219
|
-
:array_nl => "\n",
|
220
|
-
:check_circular => true
|
221
|
-
)
|
222
257
|
if opts
|
223
258
|
if opts.respond_to? :to_hash
|
224
259
|
opts = opts.to_hash
|
@@ -227,9 +262,12 @@ module JSON
|
|
227
262
|
else
|
228
263
|
raise TypeError, "can't convert #{opts.class} into Hash"
|
229
264
|
end
|
265
|
+
state = PRETTY_STATE_PROTOTYPE.dup
|
230
266
|
state.configure(opts)
|
267
|
+
else
|
268
|
+
state = PRETTY_STATE_PROTOTYPE
|
231
269
|
end
|
232
|
-
|
270
|
+
state.generate(obj)
|
233
271
|
end
|
234
272
|
|
235
273
|
# :stopdoc:
|
@@ -270,8 +308,6 @@ module JSON
|
|
270
308
|
proc.call result
|
271
309
|
end
|
272
310
|
end
|
273
|
-
private :recurse_proc
|
274
|
-
module_function :recurse_proc
|
275
311
|
|
276
312
|
alias restore load
|
277
313
|
module_function :restore
|
@@ -307,9 +343,16 @@ module JSON
|
|
307
343
|
rescue JSON::NestingError
|
308
344
|
raise ArgumentError, "exceed depth limit"
|
309
345
|
end
|
346
|
+
|
347
|
+
# Shortuct for iconv.
|
348
|
+
def self.iconv(to, from, string)
|
349
|
+
Iconv.iconv(to, from, string).first
|
350
|
+
end
|
310
351
|
end
|
311
352
|
|
312
353
|
module ::Kernel
|
354
|
+
private
|
355
|
+
|
313
356
|
# Outputs _objs_ to STDOUT as JSON strings in the shortest form, that is in
|
314
357
|
# one line.
|
315
358
|
def j(*objs)
|
@@ -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.
|
@@ -34,17 +34,25 @@ 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
|
41
40
|
# UTF16 big endian characters as \u????, and return it.
|
42
|
-
if
|
41
|
+
if defined?(::Encoding)
|
43
42
|
def utf8_to_json(string) # :nodoc:
|
44
43
|
string = string.dup
|
45
44
|
string << '' # XXX workaround: avoid buffer sharing
|
46
|
-
string.force_encoding(Encoding::ASCII_8BIT)
|
47
|
-
string.gsub!(/["
|
45
|
+
string.force_encoding(::Encoding::ASCII_8BIT)
|
46
|
+
string.gsub!(/["\\\x0-\x1f]/) { MAP[$&] }
|
47
|
+
string.force_encoding(::Encoding::UTF_8)
|
48
|
+
string
|
49
|
+
end
|
50
|
+
|
51
|
+
def utf8_to_json_ascii(string) # :nodoc:
|
52
|
+
string = string.dup
|
53
|
+
string << '' # XXX workaround: avoid buffer sharing
|
54
|
+
string.force_encoding(::Encoding::ASCII_8BIT)
|
55
|
+
string.gsub!(/["\\\x0-\x1f]/) { MAP[$&] }
|
48
56
|
string.gsub!(/(
|
49
57
|
(?:
|
50
58
|
[\xc2-\xdf][\x80-\xbf] |
|
@@ -57,14 +65,18 @@ module JSON
|
|
57
65
|
s = JSON::UTF8toUTF16.iconv(c).unpack('H*')[0]
|
58
66
|
s.gsub!(/.{4}/n, '\\\\u\&')
|
59
67
|
}
|
60
|
-
string.force_encoding(Encoding::UTF_8)
|
68
|
+
string.force_encoding(::Encoding::UTF_8)
|
61
69
|
string
|
62
70
|
rescue Iconv::Failure => e
|
63
71
|
raise GeneratorError, "Caught #{e.class}: #{e}"
|
64
72
|
end
|
65
73
|
else
|
66
74
|
def utf8_to_json(string) # :nodoc:
|
67
|
-
string
|
75
|
+
string.gsub(/["\\\x0-\x1f]/) { MAP[$&] }
|
76
|
+
end
|
77
|
+
|
78
|
+
def utf8_to_json_ascii(string) # :nodoc:
|
79
|
+
string = string.gsub(/["\\\x0-\x1f]/) { MAP[$&] }
|
68
80
|
string.gsub!(/(
|
69
81
|
(?:
|
70
82
|
[\xc2-\xdf][\x80-\xbf] |
|
@@ -82,7 +94,7 @@ module JSON
|
|
82
94
|
raise GeneratorError, "Caught #{e.class}: #{e}"
|
83
95
|
end
|
84
96
|
end
|
85
|
-
module_function :utf8_to_json
|
97
|
+
module_function :utf8_to_json, :utf8_to_json_ascii
|
86
98
|
|
87
99
|
module Pure
|
88
100
|
module Generator
|
@@ -100,7 +112,7 @@ module JSON
|
|
100
112
|
when Hash
|
101
113
|
new(opts)
|
102
114
|
else
|
103
|
-
|
115
|
+
SAFE_STATE_PROTOTYPE
|
104
116
|
end
|
105
117
|
end
|
106
118
|
|
@@ -113,22 +125,20 @@ module JSON
|
|
113
125
|
# * *space_before*: a string that is put before a : pair delimiter (default: ''),
|
114
126
|
# * *object_nl*: a string that is put at the end of a JSON object (default: ''),
|
115
127
|
# * *array_nl*: a string that is put at the end of a JSON array (default: ''),
|
116
|
-
# * *check_circular*:
|
117
|
-
#
|
118
|
-
#
|
119
|
-
# should be done, false (the default) otherwise.
|
128
|
+
# * *check_circular*: is deprecated now, use the :max_nesting option instead,
|
129
|
+
# * *max_nesting*: sets the maximum level of data structure nesting in
|
130
|
+
# the generated JSON, max_nesting = 0 if no maximum should be checked.
|
120
131
|
# * *allow_nan*: true if NaN, Infinity, and -Infinity should be
|
121
132
|
# generated, otherwise an exception is thrown, if these values are
|
122
133
|
# encountered. This options defaults to false.
|
123
134
|
def initialize(opts = {})
|
124
|
-
@seen = {}
|
125
135
|
@indent = ''
|
126
136
|
@space = ''
|
127
137
|
@space_before = ''
|
128
138
|
@object_nl = ''
|
129
139
|
@array_nl = ''
|
130
|
-
@check_circular = true
|
131
140
|
@allow_nan = false
|
141
|
+
@ascii_only = false
|
132
142
|
configure opts
|
133
143
|
end
|
134
144
|
|
@@ -160,10 +170,10 @@ module JSON
|
|
160
170
|
raise NestingError, "nesting of #{current_nesting} is too deep"
|
161
171
|
end
|
162
172
|
|
163
|
-
# Returns true, if circular data structures
|
173
|
+
# Returns true, if circular data structures are checked,
|
164
174
|
# otherwise returns false.
|
165
175
|
def check_circular?
|
166
|
-
|
176
|
+
!@max_nesting.zero?
|
167
177
|
end
|
168
178
|
|
169
179
|
# Returns true if NaN, Infinity, and -Infinity should be considered as
|
@@ -172,21 +182,8 @@ module JSON
|
|
172
182
|
@allow_nan
|
173
183
|
end
|
174
184
|
|
175
|
-
|
176
|
-
|
177
|
-
def seen?(object)
|
178
|
-
@seen.key?(object.__id__)
|
179
|
-
end
|
180
|
-
|
181
|
-
# Remember _object_, to find out if it was already encountered (if a
|
182
|
-
# cyclic data structure is if a cyclic data structure is rendered).
|
183
|
-
def remember(object)
|
184
|
-
@seen[object.__id__] = true
|
185
|
-
end
|
186
|
-
|
187
|
-
# Forget _object_ for this generating run.
|
188
|
-
def forget(object)
|
189
|
-
@seen.delete object.__id__
|
185
|
+
def ascii_only?
|
186
|
+
@ascii_only
|
190
187
|
end
|
191
188
|
|
192
189
|
# Configure this State instance with the Hash _opts_, and return
|
@@ -197,8 +194,8 @@ module JSON
|
|
197
194
|
@space_before = opts[:space_before] if opts.key?(:space_before)
|
198
195
|
@object_nl = opts[:object_nl] if opts.key?(:object_nl)
|
199
196
|
@array_nl = opts[:array_nl] if opts.key?(:array_nl)
|
200
|
-
@check_circular = !!opts[:check_circular] if opts.key?(:check_circular)
|
201
197
|
@allow_nan = !!opts[:allow_nan] if opts.key?(:allow_nan)
|
198
|
+
@ascii_only = opts[:ascii_only] if opts.key?(:ascii_only)
|
202
199
|
if !opts.key?(:max_nesting) # defaults to 19
|
203
200
|
@max_nesting = 19
|
204
201
|
elsif opts[:max_nesting]
|
@@ -213,11 +210,27 @@ module JSON
|
|
213
210
|
# passed to the configure method.
|
214
211
|
def to_h
|
215
212
|
result = {}
|
216
|
-
for iv in %w[indent space space_before object_nl array_nl
|
213
|
+
for iv in %w[indent space space_before object_nl array_nl allow_nan max_nesting]
|
217
214
|
result[iv.intern] = instance_variable_get("@#{iv}")
|
218
215
|
end
|
219
216
|
result
|
220
217
|
end
|
218
|
+
|
219
|
+
# Generates a valid JSON document from object +obj+ and returns the
|
220
|
+
# result. If no valid JSON document can be created this method raises a
|
221
|
+
# GeneratorError exception.
|
222
|
+
def generate(obj)
|
223
|
+
result = obj.to_json(self)
|
224
|
+
if result !~ /\A\s*(?:\[.*\]|\{.*\})\s*\Z/m
|
225
|
+
raise GeneratorError, "only generation of JSON objects or arrays allowed"
|
226
|
+
end
|
227
|
+
result
|
228
|
+
end
|
229
|
+
|
230
|
+
# Return the value returned by method +name+.
|
231
|
+
def [](name)
|
232
|
+
__send__ name
|
233
|
+
end
|
221
234
|
end
|
222
235
|
|
223
236
|
module GeneratorMethods
|
@@ -236,27 +249,14 @@ module JSON
|
|
236
249
|
# _depth_ is used to find out nesting depth, to indent accordingly.
|
237
250
|
def to_json(state = nil, depth = 0, *)
|
238
251
|
if state
|
239
|
-
state =
|
252
|
+
state = State.from_state(state)
|
240
253
|
state.check_max_nesting(depth)
|
241
|
-
json_check_circular(state) { json_transform(state, depth) }
|
242
|
-
else
|
243
|
-
json_transform(state, depth)
|
244
254
|
end
|
255
|
+
json_transform(state, depth)
|
245
256
|
end
|
246
257
|
|
247
258
|
private
|
248
259
|
|
249
|
-
def json_check_circular(state)
|
250
|
-
if state and state.check_circular?
|
251
|
-
state.seen?(self) and raise JSON::CircularDatastructure,
|
252
|
-
"circular data structures not supported!"
|
253
|
-
state.remember self
|
254
|
-
end
|
255
|
-
yield
|
256
|
-
ensure
|
257
|
-
state and state.forget self
|
258
|
-
end
|
259
|
-
|
260
260
|
def json_shift(state, depth)
|
261
261
|
state and not state.object_nl.empty? or return ''
|
262
262
|
state.indent * depth
|
@@ -268,16 +268,22 @@ module JSON
|
|
268
268
|
delim << state.object_nl
|
269
269
|
result = '{'
|
270
270
|
result << state.object_nl
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
|
271
|
+
depth += 1
|
272
|
+
first = true
|
273
|
+
indent = state && !state.object_nl.empty?
|
274
|
+
each { |key,value|
|
275
|
+
result << delim unless first
|
276
|
+
result << state.indent * depth if indent
|
277
|
+
result << key.to_s.to_json(state, depth)
|
278
|
+
result << state.space_before
|
279
|
+
result << ':'
|
280
|
+
result << state.space
|
281
|
+
result << value.to_json(state, depth)
|
282
|
+
first = false
|
283
|
+
}
|
284
|
+
depth -= 1
|
279
285
|
result << state.object_nl
|
280
|
-
result <<
|
286
|
+
result << state.indent * depth if indent if indent
|
281
287
|
result << '}'
|
282
288
|
else
|
283
289
|
result = '{'
|
@@ -298,43 +304,32 @@ module JSON
|
|
298
304
|
# _depth_ is used to find out nesting depth, to indent accordingly.
|
299
305
|
def to_json(state = nil, depth = 0, *)
|
300
306
|
if state
|
301
|
-
state =
|
307
|
+
state = State.from_state(state)
|
302
308
|
state.check_max_nesting(depth)
|
303
|
-
json_check_circular(state) { json_transform(state, depth) }
|
304
|
-
else
|
305
|
-
json_transform(state, depth)
|
306
309
|
end
|
310
|
+
json_transform(state, depth)
|
307
311
|
end
|
308
312
|
|
309
313
|
private
|
310
314
|
|
311
|
-
def json_check_circular(state)
|
312
|
-
if state and state.check_circular?
|
313
|
-
state.seen?(self) and raise JSON::CircularDatastructure,
|
314
|
-
"circular data structures not supported!"
|
315
|
-
state.remember self
|
316
|
-
end
|
317
|
-
yield
|
318
|
-
ensure
|
319
|
-
state and state.forget self
|
320
|
-
end
|
321
|
-
|
322
|
-
def json_shift(state, depth)
|
323
|
-
state and not state.array_nl.empty? or return ''
|
324
|
-
state.indent * depth
|
325
|
-
end
|
326
|
-
|
327
315
|
def json_transform(state, depth)
|
328
316
|
delim = ','
|
329
317
|
if state
|
330
318
|
delim << state.array_nl
|
331
319
|
result = '['
|
332
320
|
result << state.array_nl
|
333
|
-
|
334
|
-
|
335
|
-
|
321
|
+
depth += 1
|
322
|
+
first = true
|
323
|
+
indent = state && !state.array_nl.empty?
|
324
|
+
each { |value|
|
325
|
+
result << delim unless first
|
326
|
+
result << state.indent * depth if indent
|
327
|
+
result << value.to_json(state, depth)
|
328
|
+
first = false
|
329
|
+
}
|
330
|
+
depth -= 1
|
336
331
|
result << state.array_nl
|
337
|
-
result <<
|
332
|
+
result << state.indent * depth if indent
|
338
333
|
result << ']'
|
339
334
|
else
|
340
335
|
'[' << map { |value| value.to_json }.join(delim) << ']'
|
@@ -352,13 +347,13 @@ module JSON
|
|
352
347
|
def to_json(state = nil, *)
|
353
348
|
case
|
354
349
|
when infinite?
|
355
|
-
if
|
350
|
+
if state && state.allow_nan?
|
356
351
|
to_s
|
357
352
|
else
|
358
353
|
raise GeneratorError, "#{self} not allowed in JSON"
|
359
354
|
end
|
360
355
|
when nan?
|
361
|
-
if
|
356
|
+
if state && state.allow_nan?
|
362
357
|
to_s
|
363
358
|
else
|
364
359
|
raise GeneratorError, "#{self} not allowed in JSON"
|
@@ -370,18 +365,45 @@ module JSON
|
|
370
365
|
end
|
371
366
|
|
372
367
|
module String
|
373
|
-
|
374
|
-
|
375
|
-
|
376
|
-
|
377
|
-
|
368
|
+
if defined?(::Encoding)
|
369
|
+
# This string should be encoded with UTF-8 A call to this method
|
370
|
+
# returns a JSON string encoded with UTF16 big endian characters as
|
371
|
+
# \u????.
|
372
|
+
def to_json(*args)
|
373
|
+
state, = *args
|
374
|
+
state ||= State.from_state(state)
|
375
|
+
if encoding == ::Encoding::UTF_8
|
376
|
+
string = self
|
377
|
+
else
|
378
|
+
string = encode(::Encoding::UTF_8)
|
379
|
+
end
|
380
|
+
if state.ascii_only?
|
381
|
+
'"' << JSON.utf8_to_json_ascii(string) << '"'
|
382
|
+
else
|
383
|
+
'"' << JSON.utf8_to_json(string) << '"'
|
384
|
+
end
|
385
|
+
end
|
386
|
+
else
|
387
|
+
# This string should be encoded with UTF-8 A call to this method
|
388
|
+
# returns a JSON string encoded with UTF16 big endian characters as
|
389
|
+
# \u????.
|
390
|
+
def to_json(*args)
|
391
|
+
state, = *args
|
392
|
+
state ||= State.from_state(state)
|
393
|
+
if state.ascii_only?
|
394
|
+
'"' << JSON.utf8_to_json_ascii(self) << '"'
|
395
|
+
else
|
396
|
+
'"' << JSON.utf8_to_json(self) << '"'
|
397
|
+
end
|
398
|
+
end
|
378
399
|
end
|
379
400
|
|
380
401
|
# Module that holds the extinding methods if, the String module is
|
381
402
|
# included.
|
382
403
|
module Extend
|
383
|
-
# Raw Strings are JSON Objects (the raw bytes are stored in an
|
384
|
-
# key "raw"). The Ruby String can be created by this
|
404
|
+
# Raw Strings are JSON Objects (the raw bytes are stored in an
|
405
|
+
# array for the key "raw"). The Ruby String can be created by this
|
406
|
+
# module method.
|
385
407
|
def json_create(o)
|
386
408
|
o['raw'].pack('C*')
|
387
409
|
end
|