fire_and_forget 0.2.0 → 0.3.0

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