ovaltine 1.0.2 → 1.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,443 @@
1
+ module JSON
2
+ MAP = {
3
+ "\x0" => '\u0000',
4
+ "\x1" => '\u0001',
5
+ "\x2" => '\u0002',
6
+ "\x3" => '\u0003',
7
+ "\x4" => '\u0004',
8
+ "\x5" => '\u0005',
9
+ "\x6" => '\u0006',
10
+ "\x7" => '\u0007',
11
+ "\b" => '\b',
12
+ "\t" => '\t',
13
+ "\n" => '\n',
14
+ "\xb" => '\u000b',
15
+ "\f" => '\f',
16
+ "\r" => '\r',
17
+ "\xe" => '\u000e',
18
+ "\xf" => '\u000f',
19
+ "\x10" => '\u0010',
20
+ "\x11" => '\u0011',
21
+ "\x12" => '\u0012',
22
+ "\x13" => '\u0013',
23
+ "\x14" => '\u0014',
24
+ "\x15" => '\u0015',
25
+ "\x16" => '\u0016',
26
+ "\x17" => '\u0017',
27
+ "\x18" => '\u0018',
28
+ "\x19" => '\u0019',
29
+ "\x1a" => '\u001a',
30
+ "\x1b" => '\u001b',
31
+ "\x1c" => '\u001c',
32
+ "\x1d" => '\u001d',
33
+ "\x1e" => '\u001e',
34
+ "\x1f" => '\u001f',
35
+ '"' => '\"',
36
+ '\\' => '\\\\',
37
+ } # :nodoc:
38
+
39
+ if defined?(::Encoding)
40
+ def utf8_to_json(string) # :nodoc:
41
+ string = string.dup
42
+ string.force_encoding(::Encoding::ASCII_8BIT)
43
+ string.gsub!(/["\\\x0-\x1f]/) { MAP[$&] }
44
+ string.force_encoding(::Encoding::UTF_8)
45
+ string
46
+ end
47
+
48
+ def utf8_to_json_ascii(string) # :nodoc:
49
+ string = string.dup
50
+ string.force_encoding(::Encoding::ASCII_8BIT)
51
+ string.gsub!(/["\\\x0-\x1f]/n) { MAP[$&] }
52
+ string.gsub!(/(
53
+ (?:
54
+ [\xc2-\xdf][\x80-\xbf] |
55
+ [\xe0-\xef][\x80-\xbf]{2} |
56
+ [\xf0-\xf4][\x80-\xbf]{3}
57
+ )+ |
58
+ [\x80-\xc1\xf5-\xff] # invalid
59
+ )/nx) { |c|
60
+ c.size == 1 and raise GeneratorError, "invalid utf8 byte: '#{c}'"
61
+ s = JSON.iconv('utf-16be', 'utf-8', c).unpack('H*')[0]
62
+ s.force_encoding(::Encoding::ASCII_8BIT)
63
+ s.gsub!(/.{4}/n, '\\\\u\&')
64
+ s.force_encoding(::Encoding::UTF_8)
65
+ }
66
+ string.force_encoding(::Encoding::UTF_8)
67
+ string
68
+ rescue => e
69
+ raise GeneratorError.wrap(e)
70
+ end
71
+
72
+ def valid_utf8?(string)
73
+ encoding = string.encoding
74
+ (encoding == Encoding::UTF_8 || encoding == Encoding::ASCII) &&
75
+ string.valid_encoding?
76
+ end
77
+ module_function :valid_utf8?
78
+ else
79
+ def utf8_to_json(string) # :nodoc:
80
+ string.gsub(/["\\\x0-\x1f]/n) { MAP[$&] }
81
+ end
82
+
83
+ def utf8_to_json_ascii(string) # :nodoc:
84
+ string = string.gsub(/["\\\x0-\x1f]/) { MAP[$&] }
85
+ string.gsub!(/(
86
+ (?:
87
+ [\xc2-\xdf][\x80-\xbf] |
88
+ [\xe0-\xef][\x80-\xbf]{2} |
89
+ [\xf0-\xf4][\x80-\xbf]{3}
90
+ )+ |
91
+ [\x80-\xc1\xf5-\xff] # invalid
92
+ )/nx) { |c|
93
+ c.size == 1 and raise GeneratorError, "invalid utf8 byte: '#{c}'"
94
+ s = JSON.iconv('utf-16be', 'utf-8', c).unpack('H*')[0]
95
+ s.gsub!(/.{4}/n, '\\\\u\&')
96
+ }
97
+ string
98
+ rescue => e
99
+ raise GeneratorError.wrap(e)
100
+ end
101
+
102
+ def valid_utf8?(string)
103
+ string =~
104
+ /\A( [\x09\x0a\x0d\x20-\x7e] # ASCII
105
+ | [\xc2-\xdf][\x80-\xbf] # non-overlong 2-byte
106
+ | \xe0[\xa0-\xbf][\x80-\xbf] # excluding overlongs
107
+ | [\xe1-\xec\xee\xef][\x80-\xbf]{2} # straight 3-byte
108
+ | \xed[\x80-\x9f][\x80-\xbf] # excluding surrogates
109
+ | \xf0[\x90-\xbf][\x80-\xbf]{2} # planes 1-3
110
+ | [\xf1-\xf3][\x80-\xbf]{3} # planes 4-15
111
+ | \xf4[\x80-\x8f][\x80-\xbf]{2} # plane 16
112
+ )*\z/nx
113
+ end
114
+ end
115
+ module_function :utf8_to_json, :utf8_to_json_ascii, :valid_utf8?
116
+
117
+
118
+ module Pure
119
+ module Generator
120
+ class State
121
+
122
+ def self.from_state(opts)
123
+ case
124
+ when self === opts
125
+ opts
126
+ when opts.respond_to?(:to_hash)
127
+ new(opts.to_hash)
128
+ when opts.respond_to?(:to_h)
129
+ new(opts.to_h)
130
+ else
131
+ new
132
+ end
133
+ end
134
+
135
+ def initialize(opts = {})
136
+ @indent = ''
137
+ @space = ''
138
+ @space_before = ''
139
+ @object_nl = ''
140
+ @array_nl = ''
141
+ @allow_nan = false
142
+ @ascii_only = false
143
+ @quirks_mode = false
144
+ @buffer_initial_length = 1024
145
+
146
+ configure opts
147
+ end
148
+
149
+ attr_accessor :indent, :space, :space_before, :object_nl, :array_nl,
150
+ :max_nesting, :quirks_mode, :buffer_initial_length, :depth
151
+
152
+ def buffer_initial_length=(length)
153
+ if length > 0
154
+ @buffer_initial_length = length
155
+ end
156
+ end
157
+
158
+ def check_max_nesting # :nodoc:
159
+ return if @max_nesting.zero?
160
+ current_nesting = depth + 1
161
+ current_nesting > @max_nesting and
162
+ raise NestingError, "nesting of #{current_nesting} is too deep"
163
+ end
164
+
165
+ def check_circular?
166
+ !@max_nesting.zero?
167
+ end
168
+
169
+ def allow_nan?
170
+ @allow_nan
171
+ end
172
+
173
+ def ascii_only?
174
+ @ascii_only
175
+ end
176
+
177
+ def quirks_mode?
178
+ @quirks_mode
179
+ end
180
+
181
+ def configure(opts)
182
+ if opts.respond_to?(:to_hash)
183
+ opts = opts.to_hash
184
+ elsif opts.respond_to?(:to_h)
185
+ opts = opts.to_h
186
+ else
187
+ raise TypeError, "can't convert #{opts.class} into Hash"
188
+ end
189
+ for key, value in opts
190
+ instance_variable_set "@#{key}", value
191
+ end
192
+ @indent = opts[:indent] if opts.key?(:indent)
193
+ @space = opts[:space] if opts.key?(:space)
194
+ @space_before = opts[:space_before] if opts.key?(:space_before)
195
+ @object_nl = opts[:object_nl] if opts.key?(:object_nl)
196
+ @array_nl = opts[:array_nl] if opts.key?(:array_nl)
197
+ @allow_nan = !!opts[:allow_nan] if opts.key?(:allow_nan)
198
+ @ascii_only = opts[:ascii_only] if opts.key?(:ascii_only)
199
+ @depth = opts[:depth] || 0
200
+ @quirks_mode = opts[:quirks_mode] if opts.key?(:quirks_mode)
201
+ @buffer_initial_length ||= opts[:buffer_initial_length]
202
+
203
+ if !opts.key?(:max_nesting) # defaults to 100
204
+ @max_nesting = 100
205
+ elsif opts[:max_nesting]
206
+ @max_nesting = opts[:max_nesting]
207
+ else
208
+ @max_nesting = 0
209
+ end
210
+ self
211
+ end
212
+ alias merge configure
213
+
214
+ def to_h
215
+ result = {}
216
+ for iv in instance_variables
217
+ iv = iv.to_s[1..-1]
218
+ result[iv.to_sym] = self[iv]
219
+ end
220
+ result
221
+ end
222
+
223
+ alias to_hash to_h
224
+
225
+ def generate(obj)
226
+ result = obj.to_json(self)
227
+ JSON.valid_utf8?(result) or raise GeneratorError,
228
+ "source sequence #{result.inspect} is illegal/malformed utf-8"
229
+ unless @quirks_mode
230
+ unless result =~ /\A\s*\[/ && result =~ /\]\s*\Z/ ||
231
+ result =~ /\A\s*\{/ && result =~ /\}\s*\Z/
232
+ then
233
+ raise GeneratorError, "only generation of JSON objects or arrays allowed"
234
+ end
235
+ end
236
+ result
237
+ end
238
+
239
+ def [](name)
240
+ if respond_to?(name)
241
+ __send__(name)
242
+ else
243
+ instance_variable_get("@#{name}")
244
+ end
245
+ end
246
+
247
+ def []=(name, value)
248
+ if respond_to?(name_writer = "#{name}=")
249
+ __send__ name_writer, value
250
+ else
251
+ instance_variable_set "@#{name}", value
252
+ end
253
+ end
254
+ end
255
+
256
+ module GeneratorMethods
257
+ module Object
258
+ def to_json(*) to_s.to_json end
259
+ end
260
+
261
+ module Hash
262
+ def to_json(state = nil, *)
263
+ state = State.from_state(state)
264
+ state.check_max_nesting
265
+ json_transform(state)
266
+ end
267
+
268
+ private
269
+
270
+ def json_shift(state)
271
+ state.object_nl.empty? or return ''
272
+ state.indent * state.depth
273
+ end
274
+
275
+ def json_transform(state)
276
+ delim = ','
277
+ delim << state.object_nl
278
+ result = '{'
279
+ result << state.object_nl
280
+ depth = state.depth += 1
281
+ first = true
282
+ indent = !state.object_nl.empty?
283
+ each { |key,value|
284
+ result << delim unless first
285
+ result << state.indent * depth if indent
286
+ result << key.to_s.to_json(state)
287
+ result << state.space_before
288
+ result << ':'
289
+ result << state.space
290
+ result << value.to_json(state)
291
+ first = false
292
+ }
293
+ depth = state.depth -= 1
294
+ result << state.object_nl
295
+ result << state.indent * depth if indent
296
+ result << '}'
297
+ result
298
+ end
299
+ end
300
+
301
+ module Array
302
+ def to_json(state = nil, *)
303
+ state = State.from_state(state)
304
+ state.check_max_nesting
305
+ json_transform(state)
306
+ end
307
+
308
+ private
309
+
310
+ def json_transform(state)
311
+ delim = ','
312
+ delim << state.array_nl
313
+ result = '['
314
+ result << state.array_nl
315
+ depth = state.depth += 1
316
+ first = true
317
+ indent = !state.array_nl.empty?
318
+ each { |value|
319
+ result << delim unless first
320
+ result << state.indent * depth if indent
321
+ result << value.to_json(state)
322
+ first = false
323
+ }
324
+ depth = state.depth -= 1
325
+ result << state.array_nl
326
+ result << state.indent * depth if indent
327
+ result << ']'
328
+ end
329
+ end
330
+
331
+ module Integer
332
+ def to_json(*) to_s end
333
+ end
334
+
335
+ module Float
336
+ def to_json(state = nil, *)
337
+ state = State.from_state(state)
338
+ case
339
+ when infinite?
340
+ if state.allow_nan?
341
+ to_s
342
+ else
343
+ raise GeneratorError, "#{self} not allowed in JSON"
344
+ end
345
+ when nan?
346
+ if state.allow_nan?
347
+ to_s
348
+ else
349
+ raise GeneratorError, "#{self} not allowed in JSON"
350
+ end
351
+ else
352
+ to_s
353
+ end
354
+ end
355
+ end
356
+
357
+ module String
358
+ if defined?(::Encoding)
359
+ def to_json(state = nil, *args)
360
+ state = State.from_state(state)
361
+ if encoding == ::Encoding::UTF_8
362
+ string = self
363
+ else
364
+ string = encode(::Encoding::UTF_8)
365
+ end
366
+ if state.ascii_only?
367
+ '"' << JSON.utf8_to_json_ascii(string) << '"'
368
+ else
369
+ '"' << JSON.utf8_to_json(string) << '"'
370
+ end
371
+ end
372
+ else
373
+ def to_json(state = nil, *args)
374
+ state = State.from_state(state)
375
+ if state.ascii_only?
376
+ '"' << JSON.utf8_to_json_ascii(self) << '"'
377
+ else
378
+ '"' << JSON.utf8_to_json(self) << '"'
379
+ end
380
+ end
381
+ end
382
+
383
+ module Extend
384
+ def json_create(o)
385
+ o['raw'].pack('C*')
386
+ end
387
+ end
388
+
389
+ def self.included(modul)
390
+ modul.extend Extend
391
+ end
392
+
393
+ def to_json_raw_object
394
+ {
395
+ JSON.create_id => self.class.name,
396
+ 'raw' => self.unpack('C*'),
397
+ }
398
+ end
399
+
400
+ def to_json_raw(*args)
401
+ to_json_raw_object.to_json(*args)
402
+ end
403
+ end
404
+
405
+ module TrueClass
406
+ def to_json(*) 'true' end
407
+ end
408
+
409
+ module FalseClass
410
+ def to_json(*) 'false' end
411
+ end
412
+
413
+ module NilClass
414
+ def to_json(*) 'null' end
415
+ end
416
+ end
417
+ end
418
+ end
419
+ end
420
+
421
+ class NilClass
422
+ include JSON::Pure::Generator::GeneratorMethods::NilClass
423
+ end
424
+
425
+ class Hash
426
+ include JSON::Pure::Generator::GeneratorMethods::Hash
427
+ end
428
+
429
+ class Array
430
+ include JSON::Pure::Generator::GeneratorMethods::Array
431
+ end
432
+
433
+ class String
434
+ include JSON::Pure::Generator::GeneratorMethods::String
435
+ end
436
+
437
+ class Integer
438
+ include JSON::Pure::Generator::GeneratorMethods::Integer
439
+ end
440
+
441
+ class Float
442
+ include JSON::Pure::Generator::GeneratorMethods::Float
443
+ end