piko-lite-mod 0.0.1

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.

Potentially problematic release.


This version of piko-lite-mod might be problematic. Click here for more details.

Files changed (42) hide show
  1. checksums.yaml +7 -0
  2. data/json-2.21.1/BSDL +22 -0
  3. data/json-2.21.1/CHANGES.md +810 -0
  4. data/json-2.21.1/COPYING +56 -0
  5. data/json-2.21.1/LEGAL +20 -0
  6. data/json-2.21.1/README.md +308 -0
  7. data/json-2.21.1/ext/json/ext/fbuffer/fbuffer.h +259 -0
  8. data/json-2.21.1/ext/json/ext/generator/extconf.rb +19 -0
  9. data/json-2.21.1/ext/json/ext/generator/generator.c +2066 -0
  10. data/json-2.21.1/ext/json/ext/json.h +183 -0
  11. data/json-2.21.1/ext/json/ext/parser/extconf.rb +37 -0
  12. data/json-2.21.1/ext/json/ext/parser/parser.c +2917 -0
  13. data/json-2.21.1/ext/json/ext/simd/conf.rb +24 -0
  14. data/json-2.21.1/ext/json/ext/simd/simd.h +208 -0
  15. data/json-2.21.1/ext/json/ext/vendor/fast_float_parser.h +814 -0
  16. data/json-2.21.1/ext/json/ext/vendor/fpconv.c +480 -0
  17. data/json-2.21.1/ext/json/ext/vendor/jeaiii-ltoa.h +267 -0
  18. data/json-2.21.1/json.gemspec +62 -0
  19. data/json-2.21.1/lib/json/add/bigdecimal.rb +58 -0
  20. data/json-2.21.1/lib/json/add/complex.rb +51 -0
  21. data/json-2.21.1/lib/json/add/core.rb +13 -0
  22. data/json-2.21.1/lib/json/add/date.rb +54 -0
  23. data/json-2.21.1/lib/json/add/date_time.rb +67 -0
  24. data/json-2.21.1/lib/json/add/exception.rb +49 -0
  25. data/json-2.21.1/lib/json/add/ostruct.rb +54 -0
  26. data/json-2.21.1/lib/json/add/range.rb +54 -0
  27. data/json-2.21.1/lib/json/add/rational.rb +49 -0
  28. data/json-2.21.1/lib/json/add/regexp.rb +48 -0
  29. data/json-2.21.1/lib/json/add/set.rb +48 -0
  30. data/json-2.21.1/lib/json/add/string.rb +35 -0
  31. data/json-2.21.1/lib/json/add/struct.rb +52 -0
  32. data/json-2.21.1/lib/json/add/symbol.rb +52 -0
  33. data/json-2.21.1/lib/json/add/time.rb +52 -0
  34. data/json-2.21.1/lib/json/common.rb +1182 -0
  35. data/json-2.21.1/lib/json/ext/generator/state.rb +104 -0
  36. data/json-2.21.1/lib/json/ext.rb +71 -0
  37. data/json-2.21.1/lib/json/generic_object.rb +67 -0
  38. data/json-2.21.1/lib/json/truffle_ruby/generator.rb +790 -0
  39. data/json-2.21.1/lib/json/version.rb +5 -0
  40. data/json-2.21.1/lib/json.rb +841 -0
  41. data/piko-lite-mod.gemspec +11 -0
  42. metadata +80 -0
@@ -0,0 +1,790 @@
1
+ # frozen_string_literal: true
2
+ module JSON
3
+ module TruffleRuby
4
+ module Generator
5
+ MAP = {
6
+ "\x0" => '\u0000',
7
+ "\x1" => '\u0001',
8
+ "\x2" => '\u0002',
9
+ "\x3" => '\u0003',
10
+ "\x4" => '\u0004',
11
+ "\x5" => '\u0005',
12
+ "\x6" => '\u0006',
13
+ "\x7" => '\u0007',
14
+ "\b" => '\b',
15
+ "\t" => '\t',
16
+ "\n" => '\n',
17
+ "\xb" => '\u000b',
18
+ "\f" => '\f',
19
+ "\r" => '\r',
20
+ "\xe" => '\u000e',
21
+ "\xf" => '\u000f',
22
+ "\x10" => '\u0010',
23
+ "\x11" => '\u0011',
24
+ "\x12" => '\u0012',
25
+ "\x13" => '\u0013',
26
+ "\x14" => '\u0014',
27
+ "\x15" => '\u0015',
28
+ "\x16" => '\u0016',
29
+ "\x17" => '\u0017',
30
+ "\x18" => '\u0018',
31
+ "\x19" => '\u0019',
32
+ "\x1a" => '\u001a',
33
+ "\x1b" => '\u001b',
34
+ "\x1c" => '\u001c',
35
+ "\x1d" => '\u001d',
36
+ "\x1e" => '\u001e',
37
+ "\x1f" => '\u001f',
38
+ '"' => '\"',
39
+ '\\' => '\\\\',
40
+ }.freeze # :nodoc:
41
+
42
+ SCRIPT_SAFE_MAP = MAP.merge(
43
+ '/' => '\\/',
44
+ "\u2028" => '\u2028',
45
+ "\u2029" => '\u2029',
46
+ ).freeze
47
+
48
+ SCRIPT_SAFE_ESCAPE_PATTERN = /[\/"\\\x0-\x1f\u2028-\u2029]/
49
+
50
+ def self.native_type?(value) # :nodoc:
51
+ (false == value || true == value || nil == value || String === value || Symbol === value || Array === value || Hash === value || Integer === value || Float === value || Fragment === value)
52
+ end
53
+
54
+ def self.native_key?(key) # :nodoc:
55
+ (Symbol === key || String === key)
56
+ end
57
+
58
+ def self.valid_encoding?(string) # :nodoc:
59
+ return false unless string.encoding == ::Encoding::UTF_8 || string.encoding == ::Encoding::US_ASCII
60
+ string.is_a?(Symbol) || string.valid_encoding?
61
+ end
62
+
63
+ # Convert a UTF8 encoded Ruby string _string_ to a JSON string, encoded with
64
+ # UTF16 big endian characters as \u????, and return it.
65
+ def self.utf8_to_json(string, script_safe = false) # :nodoc:
66
+ if script_safe
67
+ if SCRIPT_SAFE_ESCAPE_PATTERN.match?(string)
68
+ string.gsub(SCRIPT_SAFE_ESCAPE_PATTERN, SCRIPT_SAFE_MAP)
69
+ else
70
+ string
71
+ end
72
+ else
73
+ if /["\\\x0-\x1f]/.match?(string)
74
+ string.gsub(/["\\\x0-\x1f]/, MAP)
75
+ else
76
+ string
77
+ end
78
+ end
79
+ end
80
+
81
+ def self.utf8_to_json_ascii(original_string, script_safe = false) # :nodoc:
82
+ string = original_string.b
83
+ map = script_safe ? SCRIPT_SAFE_MAP : MAP
84
+ string.gsub!(/[\/"\\\x0-\x1f]/n) { 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.new("invalid utf8 byte: '#{c}'", original_string)
94
+ s = c.encode(::Encoding::UTF_16BE, ::Encoding::UTF_8).unpack('H*')[0]
95
+ s.force_encoding(::Encoding::BINARY)
96
+ s.gsub!(/.{4}/n, '\\\\u\&')
97
+ s.force_encoding(::Encoding::UTF_8)
98
+ }
99
+ string.force_encoding(::Encoding::UTF_8)
100
+ string
101
+ rescue => e
102
+ raise GeneratorError.new(e.message, original_string)
103
+ end
104
+
105
+ def self.valid_utf8?(string)
106
+ encoding = string.encoding
107
+ (encoding == Encoding::UTF_8 || encoding == Encoding::ASCII) &&
108
+ string.valid_encoding?
109
+ end
110
+
111
+ # This class is used to create State instances, that are use to hold data
112
+ # while generating a JSON text from a Ruby data structure.
113
+ class State
114
+ singleton_class.attr_accessor :default_sort_keys_proc # :nodoc:
115
+
116
+ def self.generate(obj, opts = nil, io = nil)
117
+ new(opts).generate(obj, io)
118
+ end
119
+
120
+ # Creates a State object from _opts_, which ought to be Hash to create
121
+ # a new State instance configured by _opts_, something else to create
122
+ # an unconfigured instance. If _opts_ is a State object, it is just
123
+ # returned.
124
+ def self.from_state(opts)
125
+ if opts
126
+ case
127
+ when self === opts
128
+ return opts
129
+ when opts.respond_to?(:to_hash)
130
+ return new(opts.to_hash)
131
+ when opts.respond_to?(:to_h)
132
+ return new(opts.to_h)
133
+ end
134
+ end
135
+ new
136
+ end
137
+
138
+ # Instantiates a new State object, configured by _opts_.
139
+ #
140
+ # _opts_ can have the following keys:
141
+ #
142
+ # * *indent*: a string used to indent levels (default: ''),
143
+ # * *space*: a string that is put after, a : or , delimiter (default: ''),
144
+ # * *space_before*: a string that is put before a : pair delimiter (default: ''),
145
+ # * *object_nl*: a string that is put at the end of a JSON object (default: ''),
146
+ # * *array_nl*: a string that is put at the end of a JSON array (default: ''),
147
+ # * *script_safe*: true if U+2028, U+2029 and forward slash (/) should be escaped
148
+ # as to make the JSON object safe to interpolate in a script tag (default: false).
149
+ # * *check_circular*: is deprecated now, use the :max_nesting option instead,
150
+ # * *max_nesting*: sets the maximum level of data structure nesting in
151
+ # the generated JSON, max_nesting = 0 if no maximum should be checked.
152
+ # * *allow_nan*: true if NaN, Infinity, and -Infinity should be
153
+ # generated, otherwise an exception is thrown, if these values are
154
+ # encountered. This options defaults to false.
155
+ def initialize(opts = nil)
156
+ @indent = ''
157
+ @space = ''
158
+ @space_before = ''
159
+ @object_nl = ''
160
+ @array_nl = ''
161
+ @allow_nan = false
162
+ @ascii_only = false
163
+ @as_json = false
164
+ @depth = 0
165
+ @buffer_initial_length = 1024
166
+ @script_safe = false
167
+ @strict = false
168
+ @max_nesting = 100
169
+ @sort_keys = false
170
+ configure(opts) if opts
171
+ end
172
+
173
+ # This string is used to indent levels in the JSON text.
174
+ attr_accessor :indent
175
+
176
+ # This string is used to insert a space between the tokens in a JSON
177
+ # string.
178
+ attr_accessor :space
179
+
180
+ # This string is used to insert a space before the ':' in JSON objects.
181
+ attr_accessor :space_before
182
+
183
+ # This string is put at the end of a line that holds a JSON object (or
184
+ # Hash).
185
+ attr_accessor :object_nl
186
+
187
+ # This string is put at the end of a line that holds a JSON array.
188
+ attr_accessor :array_nl
189
+
190
+ # This proc converts unsupported types into native JSON types.
191
+ attr_accessor :as_json
192
+
193
+ # This integer returns the maximum level of data structure nesting in
194
+ # the generated JSON, max_nesting = 0 if no maximum is checked.
195
+ attr_accessor :max_nesting
196
+
197
+ # If this attribute is set to true, forward slashes will be escaped in
198
+ # all json strings.
199
+ attr_accessor :script_safe
200
+
201
+ # If this attribute is set to true, attempting to serialize types not
202
+ # supported by the JSON spec will raise a JSON::GeneratorError
203
+ attr_accessor :strict
204
+
205
+ # Controls key sorting in the generated JSON. If set to +true+, object
206
+ # keys are sorted by key lexicographically. If set to a Proc, it
207
+ # receives the entire Hash and must return a Hash with its pairs in the
208
+ # desired order.
209
+ attr_reader :sort_keys
210
+
211
+ def sort_keys=(value) # :nodoc:
212
+ type_error = false
213
+ @sort_keys = case value
214
+ when Proc
215
+ value
216
+ when true
217
+ State.default_sort_keys_proc
218
+ when nil, false
219
+ false
220
+ else
221
+ type_error = true
222
+ false
223
+ end
224
+
225
+ if type_error
226
+ raise TypeError, "The `sort_keys` argument must be a boolean or a Proc"
227
+ end
228
+
229
+ @sort_keys
230
+ end
231
+
232
+ # :stopdoc:
233
+ attr_reader :buffer_initial_length
234
+
235
+ def buffer_initial_length=(length)
236
+ if length > 0
237
+ @buffer_initial_length = length
238
+ end
239
+ end
240
+ # :startdoc:
241
+
242
+ # This integer returns the current depth data structure nesting in the
243
+ # generated JSON.
244
+ attr_reader :depth
245
+
246
+ def depth=(depth)
247
+ if depth.negative?
248
+ raise ArgumentError, "depth must be >= 0 (got #{depth})"
249
+ end
250
+ @depth = depth
251
+ end
252
+
253
+ def check_max_nesting # :nodoc:
254
+ return if @max_nesting.zero?
255
+ current_nesting = depth + 1
256
+ current_nesting > @max_nesting and
257
+ raise NestingError, "nesting of #{current_nesting} is too deep. Did you try to serialize objects with circular references?"
258
+ end
259
+
260
+ # Returns true, if circular data structures are checked,
261
+ # otherwise returns false.
262
+ def check_circular?
263
+ !@max_nesting.zero?
264
+ end
265
+
266
+ # Returns true if NaN, Infinity, and -Infinity should be considered as
267
+ # valid JSON and output.
268
+ def allow_nan?
269
+ @allow_nan
270
+ end
271
+
272
+ # Returns true, if only ASCII characters should be generated. Otherwise
273
+ # returns false.
274
+ def ascii_only?
275
+ @ascii_only
276
+ end
277
+
278
+ # Returns true, if forward slashes are escaped. Otherwise returns false.
279
+ def script_safe?
280
+ @script_safe
281
+ end
282
+
283
+ # Returns true, if strict mode is enabled. Otherwise returns false.
284
+ # Strict mode only allow serializing JSON native types: Hash, Array,
285
+ # String, Integer, Float, true, false and nil.
286
+ def strict?
287
+ @strict
288
+ end
289
+
290
+ # Configure this State instance with the Hash _opts_, and return
291
+ # itself.
292
+ def configure(opts)
293
+ if opts.respond_to?(:to_hash)
294
+ opts = opts.to_hash
295
+ elsif opts.respond_to?(:to_h)
296
+ opts = opts.to_h
297
+ else
298
+ raise TypeError, "can't convert #{opts.class} into Hash"
299
+ end
300
+
301
+ if opts[:depth]&.negative?
302
+ raise ArgumentError, "depth must be >= 0 (got #{opts[:depth]})"
303
+ end
304
+
305
+ opts.each do |key, value|
306
+ instance_variable_set "@#{key}", value
307
+ end
308
+
309
+ # NOTE: If adding new instance variables here, check whether #generate should check them for #generate_json
310
+ @indent = opts[:indent] || '' if opts.key?(:indent)
311
+ @space = opts[:space] || '' if opts.key?(:space)
312
+ @space_before = opts[:space_before] || '' if opts.key?(:space_before)
313
+ @object_nl = opts[:object_nl] || '' if opts.key?(:object_nl)
314
+ @array_nl = opts[:array_nl] || '' if opts.key?(:array_nl)
315
+ @allow_nan = !!opts[:allow_nan] if opts.key?(:allow_nan)
316
+ @as_json = opts[:as_json].to_proc if opts[:as_json]
317
+ @ascii_only = opts[:ascii_only] if opts.key?(:ascii_only)
318
+ self.sort_keys = opts[:sort_keys] if opts.key?(:sort_keys)
319
+ @depth = opts[:depth] || 0
320
+ @buffer_initial_length ||= opts[:buffer_initial_length]
321
+
322
+ @script_safe = if opts.key?(:script_safe)
323
+ !!opts[:script_safe]
324
+ elsif opts.key?(:escape_slash)
325
+ !!opts[:escape_slash]
326
+ else
327
+ false
328
+ end
329
+
330
+ if opts.key?(:allow_duplicate_key)
331
+ @allow_duplicate_key = !!opts[:allow_duplicate_key]
332
+ else
333
+ @allow_duplicate_key = nil # nil is deprecation
334
+ end
335
+
336
+ @strict = !!opts[:strict] if opts.key?(:strict)
337
+
338
+ if !opts.key?(:max_nesting) # defaults to 100
339
+ @max_nesting = 100
340
+ elsif opts[:max_nesting]
341
+ unless opts[:max_nesting].is_a?(Integer)
342
+ raise TypeError, ":max_nesting must be an Integer, got: #{opts[:max_nesting].class}"
343
+ end
344
+ @max_nesting = opts[:max_nesting]
345
+ else
346
+ @max_nesting = 0
347
+ end
348
+ self
349
+ end
350
+ alias merge configure
351
+
352
+ def allow_duplicate_key? # :nodoc:
353
+ @allow_duplicate_key
354
+ end
355
+
356
+ # Returns the configuration instance variables as a hash, that can be
357
+ # passed to the configure method.
358
+ def to_h
359
+ result = {}
360
+ instance_variables.each do |iv|
361
+ key = iv.to_s[1..-1]
362
+ result[key.to_sym] = instance_variable_get(iv)
363
+ end
364
+
365
+ if result[:allow_duplicate_key].nil?
366
+ result.delete(:allow_duplicate_key)
367
+ end
368
+
369
+ result
370
+ end
371
+
372
+ alias to_hash to_h
373
+
374
+ # Generates a valid JSON document from object +obj+ and
375
+ # returns the result. If no valid JSON document can be
376
+ # created this method raises a
377
+ # GeneratorError exception.
378
+ def generate(obj, anIO = nil)
379
+ return dup.generate(obj, anIO) if frozen?
380
+
381
+ depth = @depth
382
+ if @indent.empty? and @space.empty? and @space_before.empty? and @object_nl.empty? and @array_nl.empty? and
383
+ !@ascii_only and !@script_safe and @max_nesting == 0 and (!@strict || Symbol === obj) and !@sort_keys
384
+ result = generate_json(obj, ''.dup)
385
+ else
386
+ if @sort_keys
387
+ obj = @sort_keys.call(obj)
388
+ end
389
+
390
+ result = obj.to_json(self)
391
+ end
392
+ JSON::TruffleRuby::Generator.valid_utf8?(result) or raise GeneratorError.new(
393
+ "source sequence #{result.inspect} is illegal/malformed utf-8",
394
+ obj
395
+ )
396
+ if anIO
397
+ anIO.write(result)
398
+ anIO
399
+ else
400
+ result
401
+ end
402
+ ensure
403
+ @depth = depth unless frozen?
404
+ end
405
+
406
+ # Handles @allow_nan, @buffer_initial_length, other ivars must be the default value (see above)
407
+ private def generate_json(obj, buf)
408
+ case obj
409
+ when Hash
410
+ buf << '{'
411
+ first = true
412
+ key_type = nil
413
+ obj.each_pair do |k,v|
414
+ if first
415
+ key_type = k.class
416
+ else
417
+ if key_type && !@allow_duplicate_key && key_type != k.class
418
+ key_type = nil # stop checking
419
+ JSON.send(:on_mixed_keys_hash, obj, !@allow_duplicate_key.nil?)
420
+ end
421
+ buf << ','
422
+ end
423
+
424
+ key_str = k.to_s
425
+ if key_str.class == String
426
+ fast_serialize_string(key_str, buf)
427
+ elsif key_str.is_a?(String)
428
+ generate_json(key_str, buf)
429
+ else
430
+ raise TypeError, "#{k.class}#to_s returns an instance of #{key_str.class}, expected a String"
431
+ end
432
+
433
+ buf << ':'
434
+ generate_json(v, buf)
435
+ first = false
436
+ end
437
+ buf << '}'
438
+ when Array
439
+ buf << '['
440
+ first = true
441
+ obj.each do |e|
442
+ buf << ',' unless first
443
+ generate_json(e, buf)
444
+ first = false
445
+ end
446
+ buf << ']'
447
+ when String
448
+ if obj.class == String
449
+ fast_serialize_string(obj, buf)
450
+ else
451
+ buf << obj.to_json(self)
452
+ end
453
+ when Integer
454
+ buf << obj.to_s
455
+ when Symbol
456
+ if @strict
457
+ fast_serialize_string(obj.name, buf)
458
+ else
459
+ buf << obj.to_json(self)
460
+ end
461
+ else
462
+ # Note: Float is handled this way since Float#to_s is slow anyway
463
+ buf << obj.to_json(self)
464
+ end
465
+ end
466
+
467
+ # Assumes !@ascii_only, !@script_safe
468
+ private def fast_serialize_string(string, buf) # :nodoc:
469
+ buf << '"'
470
+ unless string.encoding == ::Encoding::UTF_8
471
+ begin
472
+ string = string.encode(::Encoding::UTF_8)
473
+ rescue Encoding::UndefinedConversionError => error
474
+ raise GeneratorError.new(error.message, string)
475
+ end
476
+ end
477
+ raise GeneratorError.new("source sequence is illegal/malformed utf-8", string) unless string.valid_encoding?
478
+
479
+ if /["\\\x0-\x1f]/.match?(string)
480
+ buf << string.gsub(/["\\\x0-\x1f]/, MAP)
481
+ else
482
+ buf << string
483
+ end
484
+ buf << '"'
485
+ end
486
+
487
+ # Return the value returned by method +name+.
488
+ def [](name)
489
+ ::JSON.deprecation_warning("JSON::State#[] is deprecated and will be removed in json 3.0.0")
490
+
491
+ if respond_to?(name)
492
+ __send__(name)
493
+ else
494
+ instance_variable_get("@#{name}") if
495
+ instance_variables.include?("@#{name}".to_sym) # avoid warning
496
+ end
497
+ end
498
+
499
+ def []=(name, value)
500
+ ::JSON.deprecation_warning("JSON::State#[]= is deprecated and will be removed in json 3.0.0")
501
+
502
+ if respond_to?(name_writer = "#{name}=")
503
+ __send__ name_writer, value
504
+ else
505
+ instance_variable_set "@#{name}", value
506
+ end
507
+ end
508
+ end
509
+
510
+ module GeneratorMethods
511
+ module Object
512
+ # Converts this object to a string (calling #to_s), converts
513
+ # it to a JSON string, and returns the result. This is a fallback, if no
514
+ # special method #to_json was defined for some object.
515
+ def to_json(state = nil, *)
516
+ state = State.from_state(state) if state
517
+ if state&.strict?
518
+ value = self
519
+ if state.strict? && !Generator.native_type?(value)
520
+ if state.as_json
521
+ value = state.as_json.call(value, false)
522
+ unless Generator.native_type?(value)
523
+ raise GeneratorError.new("#{value.class} returned by #{state.as_json} not allowed in JSON", value)
524
+ end
525
+ value.to_json(state)
526
+ else
527
+ raise GeneratorError.new("#{value.class} not allowed in JSON", value)
528
+ end
529
+ end
530
+ else
531
+ to_s.to_json
532
+ end
533
+ end
534
+ end
535
+
536
+ module Hash
537
+ # Returns a JSON string containing a JSON object, that is unparsed from
538
+ # this Hash instance.
539
+ # _state_ is a JSON::State object, that can also be used to configure the
540
+ # produced JSON string output further.
541
+ # _depth_ is used to find out nesting depth, to indent accordingly.
542
+ def to_json(state = nil, *)
543
+ state = State.from_state(state)
544
+ depth = state.depth
545
+ state.check_max_nesting
546
+ json_transform(state)
547
+ ensure
548
+ state.depth = depth
549
+ end
550
+
551
+ private
552
+
553
+ def json_transform(state)
554
+ depth = state.depth += 1
555
+
556
+ if empty?
557
+ state.depth -= 1
558
+ return +'{}'
559
+ end
560
+
561
+ delim = ",#{state.object_nl}"
562
+ result = "{#{state.object_nl}"
563
+ first = true
564
+ key_type = nil
565
+ indent = !state.object_nl.empty?
566
+ each { |key, value|
567
+ if first
568
+ key_type = key.class
569
+ else
570
+ if key_type && !state.allow_duplicate_key? && key_type != key.class
571
+ key_type = nil # stop checking
572
+ JSON.send(:on_mixed_keys_hash, self, state.allow_duplicate_key? == false)
573
+ end
574
+ result << delim
575
+ end
576
+ result << state.indent * depth if indent
577
+
578
+ if state.strict?
579
+ if state.as_json && (!Generator.native_key?(key) || !Generator.valid_encoding?(key))
580
+ key = state.as_json.call(key, true)
581
+ end
582
+
583
+ unless Generator.native_key?(key)
584
+ raise GeneratorError.new("#{key.class} not allowed as object key in JSON", key)
585
+ end
586
+
587
+ unless Generator.valid_encoding?(key)
588
+ raise GeneratorError.new("source sequence is illegal/malformed utf-8", key)
589
+ end
590
+ end
591
+
592
+ key_str = key.to_s
593
+ if key_str.is_a?(String)
594
+ key_json = key_str.to_json(state)
595
+ else
596
+ raise TypeError, "#{key.class}#to_s returns an instance of #{key_str.class}, expected a String"
597
+ end
598
+
599
+ result = "#{result}#{key_json}#{state.space_before}:#{state.space}"
600
+ if state.strict? && !Generator.native_type?(value)
601
+ if state.as_json
602
+ value = state.as_json.call(value, false)
603
+ unless Generator.native_type?(value)
604
+ raise GeneratorError.new("#{value.class} returned by #{state.as_json} not allowed in JSON", value)
605
+ end
606
+ result << value.to_json(state)
607
+ state.depth = depth
608
+ else
609
+ raise GeneratorError.new("#{value.class} not allowed in JSON", value)
610
+ end
611
+ elsif value.respond_to?(:to_json)
612
+ result << value.to_json(state)
613
+ state.depth = depth
614
+ else
615
+ result << %{"#{String(value)}"}
616
+ end
617
+ first = false
618
+ }
619
+ depth -= 1
620
+ unless first
621
+ result << state.object_nl
622
+ result << state.indent * depth if indent
623
+ end
624
+ result << '}'
625
+ result
626
+ end
627
+ end
628
+
629
+ module Array
630
+ # Returns a JSON string containing a JSON array, that is unparsed from
631
+ # this Array instance.
632
+ # _state_ is a JSON::State object, that can also be used to configure the
633
+ # produced JSON string output further.
634
+ def to_json(state = nil, *)
635
+ state = State.from_state(state)
636
+ depth = state.depth
637
+ state.check_max_nesting
638
+ json_transform(state)
639
+ ensure
640
+ state.depth = depth
641
+ end
642
+
643
+ private
644
+
645
+ def json_transform(state)
646
+ depth = state.depth += 1
647
+
648
+ if empty?
649
+ state.depth -= 1
650
+ return +'[]'
651
+ end
652
+
653
+ result = '['.dup
654
+ if state.array_nl.empty?
655
+ delim = ","
656
+ else
657
+ result << state.array_nl
658
+ delim = ",#{state.array_nl}"
659
+ end
660
+
661
+ first = true
662
+ indent = !state.array_nl.empty?
663
+ each { |value|
664
+ result << delim unless first
665
+ result << state.indent * depth if indent
666
+ if state.strict? && !Generator.native_type?(value)
667
+ if state.as_json
668
+ value = state.as_json.call(value, false)
669
+ unless Generator.native_type?(value)
670
+ raise GeneratorError.new("#{value.class} returned by #{state.as_json} not allowed in JSON", value)
671
+ end
672
+ result << value.to_json(state)
673
+ else
674
+ raise GeneratorError.new("#{value.class} not allowed in JSON", value)
675
+ end
676
+ elsif value.respond_to?(:to_json)
677
+ result << value.to_json(state)
678
+ state.depth = depth
679
+ else
680
+ result << %{"#{String(value)}"}
681
+ end
682
+ first = false
683
+ }
684
+ depth -= 1
685
+ result << state.array_nl
686
+ result << state.indent * depth if indent
687
+ result << ']'
688
+ end
689
+ end
690
+
691
+ module Integer
692
+ # Returns a JSON string representation for this Integer number.
693
+ def to_json(*) to_s end
694
+ end
695
+
696
+ module Float
697
+ # Returns a JSON string representation for this Float number.
698
+ def to_json(state = nil, *args)
699
+ state = State.from_state(state)
700
+ if infinite? || nan?
701
+ if state.allow_nan?
702
+ to_s
703
+ elsif state.strict? && state.as_json
704
+ casted_value = state.as_json.call(self, false)
705
+
706
+ if casted_value.equal?(self)
707
+ raise GeneratorError.new("#{self} not allowed in JSON", self)
708
+ end
709
+ unless Generator.native_type?(casted_value)
710
+ raise GeneratorError.new("#{casted_value.class} returned by #{state.as_json} not allowed in JSON", casted_value)
711
+ end
712
+
713
+ state.check_max_nesting
714
+ state.depth += 1
715
+ result = casted_value.to_json(state, *args)
716
+ state.depth -= 1
717
+ result
718
+ else
719
+ raise GeneratorError.new("#{self} not allowed in JSON", self)
720
+ end
721
+ else
722
+ to_s
723
+ end
724
+ end
725
+ end
726
+
727
+ module Symbol
728
+ def to_json(state = nil, *args)
729
+ state = State.from_state(state)
730
+ if state.strict?
731
+ name.to_json(state, *args)
732
+ else
733
+ super
734
+ end
735
+ end
736
+ end
737
+
738
+ module String
739
+ # This string should be encoded with UTF-8 A call to this method
740
+ # returns a JSON string encoded with UTF16 big endian characters as
741
+ # \u????.
742
+ def to_json(state = nil, *args)
743
+ state = State.from_state(state)
744
+ string = self
745
+
746
+ if state.strict? && state.as_json
747
+ unless Generator.valid_encoding?(string)
748
+ string = state.as_json.call(string, false)
749
+ unless string.is_a?(::String)
750
+ return string.to_json(state, *args)
751
+ end
752
+ end
753
+ end
754
+
755
+ if string.encoding == ::Encoding::UTF_8
756
+ unless string.valid_encoding?
757
+ raise GeneratorError.new("source sequence is illegal/malformed utf-8", self)
758
+ end
759
+ else
760
+ string = string.encode(::Encoding::UTF_8)
761
+ end
762
+
763
+ if state.ascii_only?
764
+ %("#{JSON::TruffleRuby::Generator.utf8_to_json_ascii(string, state.script_safe)}")
765
+ else
766
+ %("#{JSON::TruffleRuby::Generator.utf8_to_json(string, state.script_safe)}")
767
+ end
768
+ rescue Encoding::UndefinedConversionError => error
769
+ raise ::JSON::GeneratorError.new(error.message, self)
770
+ end
771
+ end
772
+
773
+ module TrueClass
774
+ # Returns a JSON string for true: 'true'.
775
+ def to_json(*) +'true' end
776
+ end
777
+
778
+ module FalseClass
779
+ # Returns a JSON string for false: 'false'.
780
+ def to_json(*) +'false' end
781
+ end
782
+
783
+ module NilClass
784
+ # Returns a JSON string for nil: 'null'.
785
+ def to_json(*) +'null' end
786
+ end
787
+ end
788
+ end
789
+ end
790
+ end