@@ -239,6 +239,8 @@ def configure(opts)
239
239
opts . each do |key , value |
240
240
instance_variable_set "@#{ key } " , value
241
241
end
242
+
243
+ # NOTE: If adding new instance variables here, check whether #generate should check them for #generate_json
242
244
@indent = opts [ :indent ] if opts . key? ( :indent )
243
245
@space = opts [ :space ] if opts . key? ( :space )
244
246
@space_before = opts [ :space_before ] if opts . key? ( :space_before )
@@ -288,12 +290,70 @@ def to_h
288
290
# created this method raises a
289
291
# GeneratorError exception.
290
292
def generate ( obj )
291
- result = obj . to_json ( self )
293
+ if @indent . empty? and @space . empty? and @space_before . empty? and @object_nl . empty? and @array_nl . empty? and
294
+ !@ascii_only and !@script_safe and @max_nesting == 0 and !@strict
295
+ result = generate_json ( obj , '' )
296
+ else
297
+ result = obj . to_json ( self )
298
+ end
292
299
JSON . valid_utf8? ( result ) or raise GeneratorError ,
293
300
"source sequence #{ result . inspect } is illegal/malformed utf-8"
294
301
result
295
302
end
296
303
304
+ # Handles @allow_nan, @buffer_initial_length, other ivars must be the default value (see above)
305
+ private def generate_json ( obj , buf )
306
+ case obj
307
+ when Hash
308
+ buf << '{' . freeze
309
+ first = true
310
+ obj . each_pair do |k , v |
311
+ buf << ',' . freeze unless first
312
+ fast_serialize_string ( k . to_s , buf )
313
+ buf << ':' . freeze
314
+ generate_json ( v , buf )
315
+ first = false
316
+ end
317
+ buf << '}' . freeze
318
+ when Array
319
+ buf << '[' . freeze
320
+ first = true
321
+ obj . each do |e |
322
+ buf << ',' . freeze unless first
323
+ generate_json ( e , buf )
324
+ first = false
325
+ end
326
+ buf << ']' . freeze
327
+ when String
328
+ fast_serialize_string ( obj , buf )
329
+ when Integer
330
+ buf << obj . to_s
331
+ else
332
+ # Note: Float is handled this way since Float#to_s is slow anyway
333
+ buf << obj . to_json ( self )
334
+ end
335
+ end
336
+
337
+ # Assumes !@ascii_only, !@script_safe
338
+ if Regexp . method_defined? ( :match? )
339
+ private def fast_serialize_string ( string , buf ) # :nodoc:
340
+ buf << '"' . freeze
341
+ string = string . encode ( ::Encoding ::UTF_8 ) unless string . encoding == ::Encoding ::UTF_8
342
+
343
+ if /["\\ \x0 -\x1f ]/n . match? ( string )
344
+ buf << string . gsub ( /["\\ \x0 -\x1f ]/n , MAP )
345
+ else
346
+ buf << string
347
+ end
348
+ buf << '"' . freeze
349
+ end
350
+ else
351
+ # Ruby 2.3 compatibility
352
+ private def fast_serialize_string ( string , buf ) # :nodoc:
353
+ buf << string . to_json ( self )
354
+ end
355
+ end
356
+
297
357
# Return the value returned by method +name+.
298
358
def []( name )
299
359
if respond_to? ( name )
0 commit comments