json 2.7.2 → 2.9.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,337 +0,0 @@
1
- #frozen_string_literal: false
2
- require 'strscan'
3
-
4
- module JSON
5
- module Pure
6
- # This class implements the JSON parser that is used to parse a JSON string
7
- # into a Ruby data structure.
8
- class Parser < StringScanner
9
- STRING = /" ((?:[^\x0-\x1f"\\] |
10
- # escaped special characters:
11
- \\["\\\/bfnrt] |
12
- \\u[0-9a-fA-F]{4} |
13
- # match all but escaped special characters:
14
- \\[\x20-\x21\x23-\x2e\x30-\x5b\x5d-\x61\x63-\x65\x67-\x6d\x6f-\x71\x73\x75-\xff])*)
15
- "/nx
16
- INTEGER = /(-?0|-?[1-9]\d*)/
17
- FLOAT = /(-?
18
- (?:0|[1-9]\d*)
19
- (?:
20
- \.\d+(?i:e[+-]?\d+) |
21
- \.\d+ |
22
- (?i:e[+-]?\d+)
23
- )
24
- )/x
25
- NAN = /NaN/
26
- INFINITY = /Infinity/
27
- MINUS_INFINITY = /-Infinity/
28
- OBJECT_OPEN = /\{/
29
- OBJECT_CLOSE = /\}/
30
- ARRAY_OPEN = /\[/
31
- ARRAY_CLOSE = /\]/
32
- PAIR_DELIMITER = /:/
33
- COLLECTION_DELIMITER = /,/
34
- TRUE = /true/
35
- FALSE = /false/
36
- NULL = /null/
37
- IGNORE = %r(
38
- (?:
39
- //[^\n\r]*[\n\r]| # line comments
40
- /\* # c-style comments
41
- (?:
42
- [^*/]| # normal chars
43
- /[^*]| # slashes that do not start a nested comment
44
- \*[^/]| # asterisks that do not end this comment
45
- /(?=\*/) # single slash before this comment's end
46
- )*
47
- \*/ # the End of this comment
48
- |[ \t\r\n]+ # whitespaces: space, horizontal tab, lf, cr
49
- )+
50
- )mx
51
-
52
- UNPARSED = Object.new.freeze
53
-
54
- # Creates a new JSON::Pure::Parser instance for the string _source_.
55
- #
56
- # It will be configured by the _opts_ hash. _opts_ can have the following
57
- # keys:
58
- # * *max_nesting*: The maximum depth of nesting allowed in the parsed data
59
- # structures. Disable depth checking with :max_nesting => false|nil|0,
60
- # it defaults to 100.
61
- # * *allow_nan*: If set to true, allow NaN, Infinity and -Infinity in
62
- # defiance of RFC 7159 to be parsed by the Parser. This option defaults
63
- # to false.
64
- # * *freeze*: If set to true, all parsed objects will be frozen. Parsed
65
- # string will be deduplicated if possible.
66
- # * *symbolize_names*: If set to true, returns symbols for the names
67
- # (keys) in a JSON object. Otherwise strings are returned, which is
68
- # also the default. It's not possible to use this option in
69
- # conjunction with the *create_additions* option.
70
- # * *create_additions*: If set to true, the Parser creates
71
- # additions when a matching class and create_id are found. This
72
- # option defaults to false.
73
- # * *object_class*: Defaults to Hash
74
- # * *array_class*: Defaults to Array
75
- # * *decimal_class*: Specifies which class to use instead of the default
76
- # (Float) when parsing decimal numbers. This class must accept a single
77
- # string argument in its constructor.
78
- def initialize(source, opts = {})
79
- opts ||= {}
80
- source = convert_encoding source
81
- super source
82
- if !opts.key?(:max_nesting) # defaults to 100
83
- @max_nesting = 100
84
- elsif opts[:max_nesting]
85
- @max_nesting = opts[:max_nesting]
86
- else
87
- @max_nesting = 0
88
- end
89
- @allow_nan = !!opts[:allow_nan]
90
- @symbolize_names = !!opts[:symbolize_names]
91
- @freeze = !!opts[:freeze]
92
- if opts.key?(:create_additions)
93
- @create_additions = !!opts[:create_additions]
94
- else
95
- @create_additions = false
96
- end
97
- @symbolize_names && @create_additions and raise ArgumentError,
98
- 'options :symbolize_names and :create_additions cannot be used '\
99
- 'in conjunction'
100
- @create_id = @create_additions ? JSON.create_id : nil
101
- @object_class = opts[:object_class] || Hash
102
- @array_class = opts[:array_class] || Array
103
- @decimal_class = opts[:decimal_class]
104
- @match_string = opts[:match_string]
105
- end
106
-
107
- alias source string
108
-
109
- def reset
110
- super
111
- @current_nesting = 0
112
- end
113
-
114
- # Parses the current JSON string _source_ and returns the
115
- # complete data structure as a result.
116
- def parse
117
- reset
118
- obj = nil
119
- while !eos? && skip(IGNORE) do end
120
- if eos?
121
- raise ParserError, "source is not valid JSON!"
122
- else
123
- obj = parse_value
124
- UNPARSED.equal?(obj) and raise ParserError,
125
- "source is not valid JSON!"
126
- obj.freeze if @freeze
127
- end
128
- while !eos? && skip(IGNORE) do end
129
- eos? or raise ParserError, "source is not valid JSON!"
130
- obj
131
- end
132
-
133
- private
134
-
135
- def convert_encoding(source)
136
- if source.respond_to?(:to_str)
137
- source = source.to_str
138
- else
139
- raise TypeError,
140
- "#{source.inspect} is not like a string"
141
- end
142
- if source.encoding != ::Encoding::ASCII_8BIT
143
- source = source.encode(::Encoding::UTF_8)
144
- source.force_encoding(::Encoding::ASCII_8BIT)
145
- end
146
- source
147
- end
148
-
149
- # Unescape characters in strings.
150
- UNESCAPE_MAP = Hash.new { |h, k| h[k] = k.chr }
151
- UNESCAPE_MAP.update({
152
- ?" => '"',
153
- ?\\ => '\\',
154
- ?/ => '/',
155
- ?b => "\b",
156
- ?f => "\f",
157
- ?n => "\n",
158
- ?r => "\r",
159
- ?t => "\t",
160
- ?u => nil,
161
- })
162
-
163
- EMPTY_8BIT_STRING = ''
164
- if ::String.method_defined?(:encode)
165
- EMPTY_8BIT_STRING.force_encoding Encoding::ASCII_8BIT
166
- end
167
-
168
- STR_UMINUS = ''.respond_to?(:-@)
169
- def parse_string
170
- if scan(STRING)
171
- return '' if self[1].empty?
172
- string = self[1].gsub(%r((?:\\[\\bfnrt"/]|(?:\\u(?:[A-Fa-f\d]{4}))+|\\[\x20-\xff]))n) do |c|
173
- if u = UNESCAPE_MAP[$&[1]]
174
- u
175
- else # \uXXXX
176
- bytes = EMPTY_8BIT_STRING.dup
177
- i = 0
178
- while c[6 * i] == ?\\ && c[6 * i + 1] == ?u
179
- bytes << c[6 * i + 2, 2].to_i(16) << c[6 * i + 4, 2].to_i(16)
180
- i += 1
181
- end
182
- JSON.iconv('utf-8', 'utf-16be', bytes).force_encoding(::Encoding::ASCII_8BIT)
183
- end
184
- end
185
- if string.respond_to?(:force_encoding)
186
- string.force_encoding(::Encoding::UTF_8)
187
- end
188
-
189
- if @freeze
190
- if STR_UMINUS
191
- string = -string
192
- else
193
- string.freeze
194
- end
195
- end
196
-
197
- if @create_additions and @match_string
198
- for (regexp, klass) in @match_string
199
- klass.json_creatable? or next
200
- string =~ regexp and return klass.json_create(string)
201
- end
202
- end
203
- string
204
- else
205
- UNPARSED
206
- end
207
- rescue => e
208
- raise ParserError, "Caught #{e.class} at '#{peek(20)}': #{e}"
209
- end
210
-
211
- def parse_value
212
- case
213
- when scan(FLOAT)
214
- if @decimal_class then
215
- if @decimal_class == BigDecimal then
216
- BigDecimal(self[1])
217
- else
218
- @decimal_class.new(self[1]) || Float(self[1])
219
- end
220
- else
221
- Float(self[1])
222
- end
223
- when scan(INTEGER)
224
- Integer(self[1])
225
- when scan(TRUE)
226
- true
227
- when scan(FALSE)
228
- false
229
- when scan(NULL)
230
- nil
231
- when !UNPARSED.equal?(string = parse_string)
232
- string
233
- when scan(ARRAY_OPEN)
234
- @current_nesting += 1
235
- ary = parse_array
236
- @current_nesting -= 1
237
- ary
238
- when scan(OBJECT_OPEN)
239
- @current_nesting += 1
240
- obj = parse_object
241
- @current_nesting -= 1
242
- obj
243
- when @allow_nan && scan(NAN)
244
- NaN
245
- when @allow_nan && scan(INFINITY)
246
- Infinity
247
- when @allow_nan && scan(MINUS_INFINITY)
248
- MinusInfinity
249
- else
250
- UNPARSED
251
- end
252
- end
253
-
254
- def parse_array
255
- raise NestingError, "nesting of #@current_nesting is too deep" if
256
- @max_nesting.nonzero? && @current_nesting > @max_nesting
257
- result = @array_class.new
258
- delim = false
259
- loop do
260
- case
261
- when eos?
262
- raise ParserError, "unexpected end of string while parsing array"
263
- when !UNPARSED.equal?(value = parse_value)
264
- delim = false
265
- result << value
266
- skip(IGNORE)
267
- if scan(COLLECTION_DELIMITER)
268
- delim = true
269
- elsif match?(ARRAY_CLOSE)
270
- ;
271
- else
272
- raise ParserError, "expected ',' or ']' in array at '#{peek(20)}'!"
273
- end
274
- when scan(ARRAY_CLOSE)
275
- if delim
276
- raise ParserError, "expected next element in array at '#{peek(20)}'!"
277
- end
278
- break
279
- when skip(IGNORE)
280
- ;
281
- else
282
- raise ParserError, "unexpected token in array at '#{peek(20)}'!"
283
- end
284
- end
285
- result
286
- end
287
-
288
- def parse_object
289
- raise NestingError, "nesting of #@current_nesting is too deep" if
290
- @max_nesting.nonzero? && @current_nesting > @max_nesting
291
- result = @object_class.new
292
- delim = false
293
- loop do
294
- case
295
- when eos?
296
- raise ParserError, "unexpected end of string while parsing object"
297
- when !UNPARSED.equal?(string = parse_string)
298
- skip(IGNORE)
299
- unless scan(PAIR_DELIMITER)
300
- raise ParserError, "expected ':' in object at '#{peek(20)}'!"
301
- end
302
- skip(IGNORE)
303
- unless UNPARSED.equal?(value = parse_value)
304
- result[@symbolize_names ? string.to_sym : string] = value
305
- delim = false
306
- skip(IGNORE)
307
- if scan(COLLECTION_DELIMITER)
308
- delim = true
309
- elsif match?(OBJECT_CLOSE)
310
- ;
311
- else
312
- raise ParserError, "expected ',' or '}' in object at '#{peek(20)}'!"
313
- end
314
- else
315
- raise ParserError, "expected value in object at '#{peek(20)}'!"
316
- end
317
- when scan(OBJECT_CLOSE)
318
- if delim
319
- raise ParserError, "expected next name, value pair in object at '#{peek(20)}'!"
320
- end
321
- if @create_additions and klassname = result[@create_id]
322
- klass = JSON.deep_const_get klassname
323
- break unless klass and klass.json_creatable?
324
- result = klass.json_create(result)
325
- end
326
- break
327
- when skip(IGNORE)
328
- ;
329
- else
330
- raise ParserError, "unexpected token in object at '#{peek(20)}'!"
331
- end
332
- end
333
- result
334
- end
335
- end
336
- end
337
- end
data/lib/json/pure.rb DELETED
@@ -1,15 +0,0 @@
1
- require 'json/common'
2
-
3
- module JSON
4
- # This module holds all the modules/classes that implement JSON's
5
- # functionality in pure ruby.
6
- module Pure
7
- require 'json/pure/parser'
8
- require 'json/pure/generator'
9
- $DEBUG and warn "Using Pure library for JSON."
10
- JSON.parser = Parser
11
- JSON.generator = Generator
12
- end
13
-
14
- JSON_LOADED = true unless defined?(::JSON::JSON_LOADED)
15
- end
File without changes