scout 5.6.7 → 5.6.8.pre

Sign up to get free protection for your applications and to get access to all the features.
Files changed (125) hide show
  1. data/CHANGELOG.markdown +4 -0
  2. data/lib/scout/version.rb +1 -1
  3. data/vendor/json_pure/.gitignore +12 -0
  4. data/vendor/json_pure/.travis.yml +20 -0
  5. data/vendor/json_pure/CHANGES +120 -0
  6. data/vendor/json_pure/COPYING-json-jruby +57 -0
  7. data/vendor/json_pure/Gemfile +11 -0
  8. data/vendor/json_pure/README-json-jruby.markdown +33 -0
  9. data/vendor/json_pure/{README → README.rdoc} +7 -7
  10. data/vendor/json_pure/Rakefile +305 -185
  11. data/vendor/json_pure/VERSION +1 -1
  12. data/vendor/json_pure/diagrams/.keep +0 -0
  13. data/vendor/json_pure/ext/json/ext/fbuffer/fbuffer.h +181 -0
  14. data/vendor/json_pure/ext/json/ext/generator/depend +1 -0
  15. data/vendor/json_pure/ext/json/ext/generator/extconf.rb +4 -6
  16. data/vendor/json_pure/ext/json/ext/generator/generator.c +463 -369
  17. data/vendor/json_pure/ext/json/ext/generator/generator.h +44 -66
  18. data/vendor/json_pure/ext/json/ext/parser/depend +1 -0
  19. data/vendor/json_pure/ext/json/ext/parser/extconf.rb +3 -5
  20. data/vendor/json_pure/ext/json/ext/parser/parser.c +580 -311
  21. data/vendor/json_pure/ext/json/ext/parser/parser.h +14 -8
  22. data/vendor/json_pure/ext/json/ext/parser/parser.rl +242 -107
  23. data/vendor/json_pure/install.rb +8 -11
  24. data/vendor/json_pure/java/src/json/ext/ByteListTranscoder.java +167 -0
  25. data/vendor/json_pure/java/src/json/ext/Generator.java +444 -0
  26. data/vendor/json_pure/java/src/json/ext/GeneratorMethods.java +232 -0
  27. data/vendor/json_pure/java/src/json/ext/GeneratorService.java +43 -0
  28. data/vendor/json_pure/java/src/json/ext/GeneratorState.java +543 -0
  29. data/vendor/json_pure/java/src/json/ext/OptionsReader.java +114 -0
  30. data/vendor/json_pure/java/src/json/ext/Parser.java +2644 -0
  31. data/vendor/json_pure/java/src/json/ext/Parser.rl +968 -0
  32. data/vendor/json_pure/java/src/json/ext/ParserService.java +35 -0
  33. data/vendor/json_pure/java/src/json/ext/RuntimeInfo.java +121 -0
  34. data/vendor/json_pure/java/src/json/ext/StringDecoder.java +167 -0
  35. data/vendor/json_pure/java/src/json/ext/StringEncoder.java +106 -0
  36. data/vendor/json_pure/java/src/json/ext/Utils.java +89 -0
  37. data/vendor/json_pure/json-java.gemspec +23 -0
  38. data/vendor/json_pure/json.gemspec +37 -0
  39. data/vendor/json_pure/json_pure.gemspec +39 -0
  40. data/vendor/json_pure/lib/json.rb +52 -0
  41. data/vendor/json_pure/lib/json/add/bigdecimal.rb +28 -0
  42. data/vendor/json_pure/lib/json/add/complex.rb +22 -0
  43. data/vendor/json_pure/lib/json/add/core.rb +9 -146
  44. data/vendor/json_pure/lib/json/add/date.rb +34 -0
  45. data/vendor/json_pure/lib/json/add/date_time.rb +50 -0
  46. data/vendor/json_pure/lib/json/add/exception.rb +31 -0
  47. data/vendor/json_pure/lib/json/add/ostruct.rb +31 -0
  48. data/vendor/json_pure/lib/json/add/range.rb +29 -0
  49. data/vendor/json_pure/lib/json/add/rational.rb +22 -0
  50. data/vendor/json_pure/lib/json/add/regexp.rb +30 -0
  51. data/vendor/json_pure/lib/json/add/struct.rb +30 -0
  52. data/vendor/json_pure/lib/json/add/symbol.rb +25 -0
  53. data/vendor/json_pure/lib/json/add/time.rb +38 -0
  54. data/vendor/json_pure/lib/json/common.rb +157 -67
  55. data/vendor/json_pure/lib/json/ext.rb +8 -2
  56. data/vendor/json_pure/lib/json/ext/.keep +0 -0
  57. data/vendor/json_pure/lib/json/generic_object.rb +70 -0
  58. data/vendor/json_pure/lib/json/pure.rb +8 -64
  59. data/vendor/json_pure/lib/json/pure/generator.rb +183 -113
  60. data/vendor/json_pure/lib/json/pure/parser.rb +118 -66
  61. data/vendor/json_pure/lib/json/version.rb +1 -1
  62. data/vendor/json_pure/tests/fixtures/fail18.json +1 -1
  63. data/vendor/json_pure/tests/setup_variant.rb +11 -0
  64. data/vendor/json_pure/tests/test_json.rb +233 -28
  65. data/vendor/json_pure/tests/test_json_addition.rb +68 -34
  66. data/vendor/json_pure/tests/test_json_encoding.rb +11 -14
  67. data/vendor/json_pure/tests/test_json_fixtures.rb +11 -10
  68. data/vendor/json_pure/tests/test_json_generate.rb +207 -7
  69. data/vendor/json_pure/tests/test_json_generic_object.rb +75 -0
  70. data/vendor/json_pure/tests/test_json_string_matching.rb +39 -0
  71. data/vendor/json_pure/tests/test_json_unicode.rb +3 -7
  72. data/vendor/json_pure/tools/fuzz.rb +1 -1
  73. data/vendor/json_pure/tools/server.rb +1 -0
  74. metadata +87 -94
  75. data/vendor/json_pure/benchmarks/data-p4-3GHz-ruby18/GeneratorBenchmarkComparison.log +0 -52
  76. data/vendor/json_pure/benchmarks/data-p4-3GHz-ruby18/GeneratorBenchmarkExt#generator_fast-autocorrelation.dat +0 -1000
  77. data/vendor/json_pure/benchmarks/data-p4-3GHz-ruby18/GeneratorBenchmarkExt#generator_fast.dat +0 -1001
  78. data/vendor/json_pure/benchmarks/data-p4-3GHz-ruby18/GeneratorBenchmarkExt#generator_pretty-autocorrelation.dat +0 -900
  79. data/vendor/json_pure/benchmarks/data-p4-3GHz-ruby18/GeneratorBenchmarkExt#generator_pretty.dat +0 -901
  80. data/vendor/json_pure/benchmarks/data-p4-3GHz-ruby18/GeneratorBenchmarkExt#generator_safe-autocorrelation.dat +0 -1000
  81. data/vendor/json_pure/benchmarks/data-p4-3GHz-ruby18/GeneratorBenchmarkExt#generator_safe.dat +0 -1001
  82. data/vendor/json_pure/benchmarks/data-p4-3GHz-ruby18/GeneratorBenchmarkExt.log +0 -261
  83. data/vendor/json_pure/benchmarks/data-p4-3GHz-ruby18/GeneratorBenchmarkPure#generator_fast-autocorrelation.dat +0 -1000
  84. data/vendor/json_pure/benchmarks/data-p4-3GHz-ruby18/GeneratorBenchmarkPure#generator_fast.dat +0 -1001
  85. data/vendor/json_pure/benchmarks/data-p4-3GHz-ruby18/GeneratorBenchmarkPure#generator_pretty-autocorrelation.dat +0 -1000
  86. data/vendor/json_pure/benchmarks/data-p4-3GHz-ruby18/GeneratorBenchmarkPure#generator_pretty.dat +0 -1001
  87. data/vendor/json_pure/benchmarks/data-p4-3GHz-ruby18/GeneratorBenchmarkPure#generator_safe-autocorrelation.dat +0 -1000
  88. data/vendor/json_pure/benchmarks/data-p4-3GHz-ruby18/GeneratorBenchmarkPure#generator_safe.dat +0 -1001
  89. data/vendor/json_pure/benchmarks/data-p4-3GHz-ruby18/GeneratorBenchmarkPure.log +0 -262
  90. data/vendor/json_pure/benchmarks/data-p4-3GHz-ruby18/GeneratorBenchmarkRails#generator-autocorrelation.dat +0 -1000
  91. data/vendor/json_pure/benchmarks/data-p4-3GHz-ruby18/GeneratorBenchmarkRails#generator.dat +0 -1001
  92. data/vendor/json_pure/benchmarks/data-p4-3GHz-ruby18/GeneratorBenchmarkRails.log +0 -82
  93. data/vendor/json_pure/benchmarks/data-p4-3GHz-ruby18/ParserBenchmarkComparison.log +0 -34
  94. data/vendor/json_pure/benchmarks/data-p4-3GHz-ruby18/ParserBenchmarkExt#parser-autocorrelation.dat +0 -900
  95. data/vendor/json_pure/benchmarks/data-p4-3GHz-ruby18/ParserBenchmarkExt#parser.dat +0 -901
  96. data/vendor/json_pure/benchmarks/data-p4-3GHz-ruby18/ParserBenchmarkExt.log +0 -81
  97. data/vendor/json_pure/benchmarks/data-p4-3GHz-ruby18/ParserBenchmarkPure#parser-autocorrelation.dat +0 -1000
  98. data/vendor/json_pure/benchmarks/data-p4-3GHz-ruby18/ParserBenchmarkPure#parser.dat +0 -1001
  99. data/vendor/json_pure/benchmarks/data-p4-3GHz-ruby18/ParserBenchmarkPure.log +0 -82
  100. data/vendor/json_pure/benchmarks/data-p4-3GHz-ruby18/ParserBenchmarkRails#parser-autocorrelation.dat +0 -1000
  101. data/vendor/json_pure/benchmarks/data-p4-3GHz-ruby18/ParserBenchmarkRails#parser.dat +0 -1001
  102. data/vendor/json_pure/benchmarks/data-p4-3GHz-ruby18/ParserBenchmarkRails.log +0 -82
  103. data/vendor/json_pure/benchmarks/data-p4-3GHz-ruby18/ParserBenchmarkYAML#parser-autocorrelation.dat +0 -1000
  104. data/vendor/json_pure/benchmarks/data-p4-3GHz-ruby18/ParserBenchmarkYAML#parser.dat +0 -1001
  105. data/vendor/json_pure/benchmarks/data-p4-3GHz-ruby18/ParserBenchmarkYAML.log +0 -82
  106. data/vendor/json_pure/benchmarks/generator2_benchmark.rb +0 -222
  107. data/vendor/json_pure/benchmarks/generator_benchmark.rb +0 -224
  108. data/vendor/json_pure/benchmarks/ohai.json +0 -1216
  109. data/vendor/json_pure/benchmarks/ohai.ruby +0 -1
  110. data/vendor/json_pure/benchmarks/parser2_benchmark.rb +0 -251
  111. data/vendor/json_pure/benchmarks/parser_benchmark.rb +0 -259
  112. data/vendor/json_pure/bin/edit_json.rb +0 -9
  113. data/vendor/json_pure/bin/prettify_json.rb +0 -75
  114. data/vendor/json_pure/lib/json/Array.xpm +0 -21
  115. data/vendor/json_pure/lib/json/FalseClass.xpm +0 -21
  116. data/vendor/json_pure/lib/json/Hash.xpm +0 -21
  117. data/vendor/json_pure/lib/json/Key.xpm +0 -73
  118. data/vendor/json_pure/lib/json/NilClass.xpm +0 -21
  119. data/vendor/json_pure/lib/json/Numeric.xpm +0 -28
  120. data/vendor/json_pure/lib/json/String.xpm +0 -96
  121. data/vendor/json_pure/lib/json/TrueClass.xpm +0 -21
  122. data/vendor/json_pure/lib/json/add/rails.rb +0 -58
  123. data/vendor/json_pure/lib/json/editor.rb +0 -1371
  124. data/vendor/json_pure/lib/json/json.xpm +0 -1499
  125. data/vendor/json_pure/tests/test_json_rails.rb +0 -144
@@ -1,3 +1,9 @@
1
+ if ENV['SIMPLECOV_COVERAGE'].to_i == 1
2
+ require 'simplecov'
3
+ SimpleCov.start do
4
+ add_filter "/tests/"
5
+ end
6
+ end
1
7
  require 'json/common'
2
8
 
3
9
  module JSON
@@ -6,10 +12,10 @@ module JSON
6
12
  module Ext
7
13
  require 'json/ext/parser'
8
14
  require 'json/ext/generator'
9
- $DEBUG and warn "Using c extension for JSON."
15
+ $DEBUG and warn "Using Ext extension for JSON."
10
16
  JSON.parser = Parser
11
17
  JSON.generator = Generator
12
18
  end
13
19
 
14
- JSON_LOADED = true
20
+ JSON_LOADED = true unless defined?(::JSON::JSON_LOADED)
15
21
  end
File without changes
@@ -0,0 +1,70 @@
1
+ require 'ostruct'
2
+
3
+ module JSON
4
+ class GenericObject < OpenStruct
5
+ class << self
6
+ alias [] new
7
+
8
+ def json_creatable?
9
+ @json_creatable
10
+ end
11
+
12
+ attr_writer :json_creatable
13
+
14
+ def json_create(data)
15
+ data = data.dup
16
+ data.delete JSON.create_id
17
+ self[data]
18
+ end
19
+
20
+ def from_hash(object)
21
+ case
22
+ when object.respond_to?(:to_hash)
23
+ result = new
24
+ object.to_hash.each do |key, value|
25
+ result[key] = from_hash(value)
26
+ end
27
+ result
28
+ when object.respond_to?(:to_ary)
29
+ object.to_ary.map { |a| from_hash(a) }
30
+ else
31
+ object
32
+ end
33
+ end
34
+
35
+ def load(source, proc = nil, opts = {})
36
+ result = ::JSON.load(source, proc, opts.merge(:object_class => self))
37
+ result.nil? ? new : result
38
+ end
39
+
40
+ def dump(obj, *args)
41
+ ::JSON.dump(obj, *args)
42
+ end
43
+ end
44
+ self.json_creatable = false
45
+
46
+ def to_hash
47
+ table
48
+ end
49
+
50
+ def [](name)
51
+ table[name.to_sym]
52
+ end
53
+
54
+ def []=(name, value)
55
+ __send__ "#{name}=", value
56
+ end
57
+
58
+ def |(other)
59
+ self.class[other.to_hash.merge(to_hash)]
60
+ end
61
+
62
+ def as_json(*)
63
+ { JSON.create_id => self.class.name }.merge to_hash
64
+ end
65
+
66
+ def to_json(*a)
67
+ as_json.to_json(*a)
68
+ end
69
+ end
70
+ end
@@ -1,77 +1,21 @@
1
+ if ENV['SIMPLECOV_COVERAGE'].to_i == 1
2
+ require 'simplecov'
3
+ SimpleCov.start do
4
+ add_filter "/tests/"
5
+ end
6
+ end
1
7
  require 'json/common'
2
8
  require 'json/pure/parser'
3
9
  require 'json/pure/generator'
4
10
 
5
11
  module JSON
6
- begin
7
- require 'iconv'
8
- # An iconv instance to convert from UTF8 to UTF16 Big Endian.
9
- UTF16toUTF8 = Iconv.new('utf-8', 'utf-16be') # :nodoc:
10
- # An iconv instance to convert from UTF16 Big Endian to UTF8.
11
- UTF8toUTF16 = Iconv.new('utf-16be', 'utf-8') # :nodoc:
12
- UTF8toUTF16.iconv('no bom')
13
- rescue LoadError
14
- raise MissingUnicodeSupport,
15
- "iconv couldn't be loaded, which is required for UTF-8/UTF-16 conversions"
16
- rescue Errno::EINVAL, Iconv::InvalidEncoding
17
- # Iconv doesn't support big endian utf-16. Let's try to hack this manually
18
- # into the converters.
19
- begin
20
- old_verbose, $VERBSOSE = $VERBOSE, nil
21
- # An iconv instance to convert from UTF8 to UTF16 Big Endian.
22
- UTF16toUTF8 = Iconv.new('utf-8', 'utf-16') # :nodoc:
23
- # An iconv instance to convert from UTF16 Big Endian to UTF8.
24
- UTF8toUTF16 = Iconv.new('utf-16', 'utf-8') # :nodoc:
25
- UTF8toUTF16.iconv('no bom')
26
- if UTF8toUTF16.iconv("\xe2\x82\xac") == "\xac\x20"
27
- swapper = Class.new do
28
- def initialize(iconv) # :nodoc:
29
- @iconv = iconv
30
- end
31
-
32
- def iconv(string) # :nodoc:
33
- result = @iconv.iconv(string)
34
- JSON.swap!(result)
35
- end
36
- end
37
- UTF8toUTF16 = swapper.new(UTF8toUTF16) # :nodoc:
38
- end
39
- if UTF16toUTF8.iconv("\xac\x20") == "\xe2\x82\xac"
40
- swapper = Class.new do
41
- def initialize(iconv) # :nodoc:
42
- @iconv = iconv
43
- end
44
-
45
- def iconv(string) # :nodoc:
46
- string = JSON.swap!(string.dup)
47
- @iconv.iconv(string)
48
- end
49
- end
50
- UTF16toUTF8 = swapper.new(UTF16toUTF8) # :nodoc:
51
- end
52
- rescue Errno::EINVAL, Iconv::InvalidEncoding
53
- raise MissingUnicodeSupport, "iconv doesn't seem to support UTF-8/UTF-16 conversions"
54
- ensure
55
- $VERBOSE = old_verbose
56
- end
57
- end
58
-
59
- # Swap consecutive bytes of _string_ in place.
60
- def self.swap!(string) # :nodoc:
61
- 0.upto(string.size / 2) do |i|
62
- break unless string[2 * i + 1]
63
- string[2 * i], string[2 * i + 1] = string[2 * i + 1], string[2 * i]
64
- end
65
- string
66
- end
67
-
68
12
  # This module holds all the modules/classes that implement JSON's
69
13
  # functionality in pure ruby.
70
14
  module Pure
71
- $DEBUG and warn "Using pure library for JSON."
15
+ $DEBUG and warn "Using Pure library for JSON."
72
16
  JSON.parser = Parser
73
17
  JSON.generator = Generator
74
18
  end
75
19
 
76
- JSON_LOADED = true
20
+ JSON_LOADED = true unless defined?(::JSON::JSON_LOADED)
77
21
  end
@@ -41,7 +41,6 @@ module JSON
41
41
  if defined?(::Encoding)
42
42
  def utf8_to_json(string) # :nodoc:
43
43
  string = string.dup
44
- string << '' # XXX workaround: avoid buffer sharing
45
44
  string.force_encoding(::Encoding::ASCII_8BIT)
46
45
  string.gsub!(/["\\\x0-\x1f]/) { MAP[$&] }
47
46
  string.force_encoding(::Encoding::UTF_8)
@@ -50,9 +49,8 @@ module JSON
50
49
 
51
50
  def utf8_to_json_ascii(string) # :nodoc:
52
51
  string = string.dup
53
- string << '' # XXX workaround: avoid buffer sharing
54
52
  string.force_encoding(::Encoding::ASCII_8BIT)
55
- string.gsub!(/["\\\x0-\x1f]/) { MAP[$&] }
53
+ string.gsub!(/["\\\x0-\x1f]/n) { MAP[$&] }
56
54
  string.gsub!(/(
57
55
  (?:
58
56
  [\xc2-\xdf][\x80-\xbf] |
@@ -62,17 +60,26 @@ module JSON
62
60
  [\x80-\xc1\xf5-\xff] # invalid
63
61
  )/nx) { |c|
64
62
  c.size == 1 and raise GeneratorError, "invalid utf8 byte: '#{c}'"
65
- s = JSON::UTF8toUTF16.iconv(c).unpack('H*')[0]
63
+ s = JSON.iconv('utf-16be', 'utf-8', c).unpack('H*')[0]
64
+ s.force_encoding(::Encoding::ASCII_8BIT)
66
65
  s.gsub!(/.{4}/n, '\\\\u\&')
66
+ s.force_encoding(::Encoding::UTF_8)
67
67
  }
68
68
  string.force_encoding(::Encoding::UTF_8)
69
69
  string
70
- rescue Iconv::Failure => e
71
- raise GeneratorError, "Caught #{e.class}: #{e}"
70
+ rescue => e
71
+ raise GeneratorError.wrap(e)
72
+ end
73
+
74
+ def valid_utf8?(string)
75
+ encoding = string.encoding
76
+ (encoding == Encoding::UTF_8 || encoding == Encoding::ASCII) &&
77
+ string.valid_encoding?
72
78
  end
79
+ module_function :valid_utf8?
73
80
  else
74
81
  def utf8_to_json(string) # :nodoc:
75
- string.gsub(/["\\\x0-\x1f]/) { MAP[$&] }
82
+ string.gsub(/["\\\x0-\x1f]/n) { MAP[$&] }
76
83
  end
77
84
 
78
85
  def utf8_to_json_ascii(string) # :nodoc:
@@ -86,33 +93,49 @@ module JSON
86
93
  [\x80-\xc1\xf5-\xff] # invalid
87
94
  )/nx) { |c|
88
95
  c.size == 1 and raise GeneratorError, "invalid utf8 byte: '#{c}'"
89
- s = JSON::UTF8toUTF16.iconv(c).unpack('H*')[0]
96
+ s = JSON.iconv('utf-16be', 'utf-8', c).unpack('H*')[0]
90
97
  s.gsub!(/.{4}/n, '\\\\u\&')
91
98
  }
92
99
  string
93
- rescue Iconv::Failure => e
94
- raise GeneratorError, "Caught #{e.class}: #{e}"
100
+ rescue => e
101
+ raise GeneratorError.wrap(e)
102
+ end
103
+
104
+ def valid_utf8?(string)
105
+ string =~
106
+ /\A( [\x09\x0a\x0d\x20-\x7e] # ASCII
107
+ | [\xc2-\xdf][\x80-\xbf] # non-overlong 2-byte
108
+ | \xe0[\xa0-\xbf][\x80-\xbf] # excluding overlongs
109
+ | [\xe1-\xec\xee\xef][\x80-\xbf]{2} # straight 3-byte
110
+ | \xed[\x80-\x9f][\x80-\xbf] # excluding surrogates
111
+ | \xf0[\x90-\xbf][\x80-\xbf]{2} # planes 1-3
112
+ | [\xf1-\xf3][\x80-\xbf]{3} # planes 4-15
113
+ | \xf4[\x80-\x8f][\x80-\xbf]{2} # plane 16
114
+ )*\z/nx
95
115
  end
96
116
  end
97
- module_function :utf8_to_json, :utf8_to_json_ascii
117
+ module_function :utf8_to_json, :utf8_to_json_ascii, :valid_utf8?
118
+
98
119
 
99
120
  module Pure
100
121
  module Generator
101
122
  # This class is used to create State instances, that are use to hold data
102
- # while generating a JSON text from a a Ruby data structure.
123
+ # while generating a JSON text from a Ruby data structure.
103
124
  class State
104
125
  # Creates a State object from _opts_, which ought to be Hash to create
105
126
  # a new State instance configured by _opts_, something else to create
106
127
  # an unconfigured instance. If _opts_ is a State object, it is just
107
128
  # returned.
108
129
  def self.from_state(opts)
109
- case opts
110
- when self
130
+ case
131
+ when self === opts
111
132
  opts
112
- when Hash
113
- new(opts)
133
+ when opts.respond_to?(:to_hash)
134
+ new(opts.to_hash)
135
+ when opts.respond_to?(:to_h)
136
+ new(opts.to_h)
114
137
  else
115
- SAFE_STATE_PROTOTYPE
138
+ SAFE_STATE_PROTOTYPE.dup
116
139
  end
117
140
  end
118
141
 
@@ -123,7 +146,7 @@ module JSON
123
146
  # * *indent*: a string used to indent levels (default: ''),
124
147
  # * *space*: a string that is put after, a : or , delimiter (default: ''),
125
148
  # * *space_before*: a string that is put before a : pair delimiter (default: ''),
126
- # * *object_nl*: a string that is put at the end of a JSON object (default: ''),
149
+ # * *object_nl*: a string that is put at the end of a JSON object (default: ''),
127
150
  # * *array_nl*: a string that is put at the end of a JSON array (default: ''),
128
151
  # * *check_circular*: is deprecated now, use the :max_nesting option instead,
129
152
  # * *max_nesting*: sets the maximum level of data structure nesting in
@@ -131,14 +154,18 @@ module JSON
131
154
  # * *allow_nan*: true if NaN, Infinity, and -Infinity should be
132
155
  # generated, otherwise an exception is thrown, if these values are
133
156
  # encountered. This options defaults to false.
157
+ # * *quirks_mode*: Enables quirks_mode for parser, that is for example
158
+ # generating single JSON values instead of documents is possible.
134
159
  def initialize(opts = {})
135
- @indent = ''
136
- @space = ''
137
- @space_before = ''
138
- @object_nl = ''
139
- @array_nl = ''
140
- @allow_nan = false
141
- @ascii_only = false
160
+ @indent = ''
161
+ @space = ''
162
+ @space_before = ''
163
+ @object_nl = ''
164
+ @array_nl = ''
165
+ @allow_nan = false
166
+ @ascii_only = false
167
+ @quirks_mode = false
168
+ @buffer_initial_length = 1024
142
169
  configure opts
143
170
  end
144
171
 
@@ -163,7 +190,25 @@ module JSON
163
190
  # the generated JSON, max_nesting = 0 if no maximum is checked.
164
191
  attr_accessor :max_nesting
165
192
 
166
- def check_max_nesting(depth) # :nodoc:
193
+ # If this attribute is set to true, quirks mode is enabled, otherwise
194
+ # it's disabled.
195
+ attr_accessor :quirks_mode
196
+
197
+ # :stopdoc:
198
+ attr_reader :buffer_initial_length
199
+
200
+ def buffer_initial_length=(length)
201
+ if length > 0
202
+ @buffer_initial_length = length
203
+ end
204
+ end
205
+ # :startdoc:
206
+
207
+ # This integer returns the current depth data structure nesting in the
208
+ # generated JSON.
209
+ attr_accessor :depth
210
+
211
+ def check_max_nesting # :nodoc:
167
212
  return if @max_nesting.zero?
168
213
  current_nesting = depth + 1
169
214
  current_nesting > @max_nesting and
@@ -182,22 +227,43 @@ module JSON
182
227
  @allow_nan
183
228
  end
184
229
 
230
+ # Returns true, if only ASCII characters should be generated. Otherwise
231
+ # returns false.
185
232
  def ascii_only?
186
233
  @ascii_only
187
234
  end
188
235
 
236
+ # Returns true, if quirks mode is enabled. Otherwise returns false.
237
+ def quirks_mode?
238
+ @quirks_mode
239
+ end
240
+
189
241
  # Configure this State instance with the Hash _opts_, and return
190
242
  # itself.
191
243
  def configure(opts)
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
- if !opts.key?(:max_nesting) # defaults to 19
200
- @max_nesting = 19
244
+ if opts.respond_to?(:to_hash)
245
+ opts = opts.to_hash
246
+ elsif opts.respond_to?(:to_h)
247
+ opts = opts.to_h
248
+ else
249
+ raise TypeError, "can't convert #{opts.class} into Hash"
250
+ end
251
+ for key, value in opts
252
+ instance_variable_set "@#{key}", value
253
+ end
254
+ @indent = opts[:indent] if opts.key?(:indent)
255
+ @space = opts[:space] if opts.key?(:space)
256
+ @space_before = opts[:space_before] if opts.key?(:space_before)
257
+ @object_nl = opts[:object_nl] if opts.key?(:object_nl)
258
+ @array_nl = opts[:array_nl] if opts.key?(:array_nl)
259
+ @allow_nan = !!opts[:allow_nan] if opts.key?(:allow_nan)
260
+ @ascii_only = opts[:ascii_only] if opts.key?(:ascii_only)
261
+ @depth = opts[:depth] || 0
262
+ @quirks_mode = opts[:quirks_mode] if opts.key?(:quirks_mode)
263
+ @buffer_initial_length ||= opts[:buffer_initial_length]
264
+
265
+ if !opts.key?(:max_nesting) # defaults to 100
266
+ @max_nesting = 100
201
267
  elsif opts[:max_nesting]
202
268
  @max_nesting = opts[:max_nesting]
203
269
  else
@@ -205,31 +271,53 @@ module JSON
205
271
  end
206
272
  self
207
273
  end
274
+ alias merge configure
208
275
 
209
276
  # Returns the configuration instance variables as a hash, that can be
210
277
  # passed to the configure method.
211
278
  def to_h
212
279
  result = {}
213
- for iv in %w[indent space space_before object_nl array_nl allow_nan max_nesting]
214
- result[iv.intern] = instance_variable_get("@#{iv}")
280
+ for iv in instance_variables
281
+ iv = iv.to_s[1..-1]
282
+ result[iv.to_sym] = self[iv]
215
283
  end
216
284
  result
217
285
  end
218
286
 
287
+ alias to_hash to_h
288
+
219
289
  # Generates a valid JSON document from object +obj+ and returns the
220
290
  # result. If no valid JSON document can be created this method raises a
221
291
  # GeneratorError exception.
222
292
  def generate(obj)
223
293
  result = obj.to_json(self)
224
- if result !~ /\A\s*(?:\[.*\]|\{.*\})\s*\Z/m
225
- raise GeneratorError, "only generation of JSON objects or arrays allowed"
294
+ JSON.valid_utf8?(result) or raise GeneratorError,
295
+ "source sequence #{result.inspect} is illegal/malformed utf-8"
296
+ unless @quirks_mode
297
+ unless result =~ /\A\s*\[/ && result =~ /\]\s*\Z/ ||
298
+ result =~ /\A\s*\{/ && result =~ /\}\s*\Z/
299
+ then
300
+ raise GeneratorError, "only generation of JSON objects or arrays allowed"
301
+ end
226
302
  end
227
303
  result
228
304
  end
229
305
 
230
306
  # Return the value returned by method +name+.
231
307
  def [](name)
232
- __send__ name
308
+ if respond_to?(name)
309
+ __send__(name)
310
+ else
311
+ instance_variable_get("@#{name}")
312
+ end
313
+ end
314
+
315
+ def []=(name, value)
316
+ if respond_to?(name_writer = "#{name}=")
317
+ __send__ name_writer, value
318
+ else
319
+ instance_variable_set "@#{name}", value
320
+ end
233
321
  end
234
322
  end
235
323
 
@@ -247,51 +335,41 @@ module JSON
247
335
  # _state_ is a JSON::State object, that can also be used to configure the
248
336
  # produced JSON string output further.
249
337
  # _depth_ is used to find out nesting depth, to indent accordingly.
250
- def to_json(state = nil, depth = 0, *)
251
- if state
252
- state = State.from_state(state)
253
- state.check_max_nesting(depth)
254
- end
255
- json_transform(state, depth)
338
+ def to_json(state = nil, *)
339
+ state = State.from_state(state)
340
+ state.check_max_nesting
341
+ json_transform(state)
256
342
  end
257
343
 
258
344
  private
259
345
 
260
- def json_shift(state, depth)
261
- state and not state.object_nl.empty? or return ''
262
- state.indent * depth
346
+ def json_shift(state)
347
+ state.object_nl.empty? or return ''
348
+ state.indent * state.depth
263
349
  end
264
350
 
265
- def json_transform(state, depth)
351
+ def json_transform(state)
266
352
  delim = ','
267
- if state
268
- delim << state.object_nl
269
- result = '{'
270
- result << state.object_nl
271
- depth += 1
272
- first = true
273
- indent = state && !state.object_nl.empty?
274
- each { |key,value|
275
- result << delim unless first
276
- result << state.indent * depth if indent
277
- result << key.to_s.to_json(state, depth)
278
- result << state.space_before
279
- result << ':'
280
- result << state.space
281
- result << value.to_json(state, depth)
282
- first = false
283
- }
284
- depth -= 1
285
- result << state.object_nl
286
- result << state.indent * depth if indent if indent
287
- result << '}'
288
- else
289
- result = '{'
290
- result << map { |key,value|
291
- key.to_s.to_json << ':' << value.to_json
292
- }.join(delim)
293
- result << '}'
294
- end
353
+ delim << state.object_nl
354
+ result = '{'
355
+ result << state.object_nl
356
+ depth = state.depth += 1
357
+ first = true
358
+ indent = !state.object_nl.empty?
359
+ each { |key,value|
360
+ result << delim unless first
361
+ result << state.indent * depth if indent
362
+ result << key.to_s.to_json(state)
363
+ result << state.space_before
364
+ result << ':'
365
+ result << state.space
366
+ result << value.to_json(state)
367
+ first = false
368
+ }
369
+ depth = state.depth -= 1
370
+ result << state.object_nl
371
+ result << state.indent * depth if indent
372
+ result << '}'
295
373
  result
296
374
  end
297
375
  end
@@ -301,39 +379,32 @@ module JSON
301
379
  # this Array instance.
302
380
  # _state_ is a JSON::State object, that can also be used to configure the
303
381
  # produced JSON string output further.
304
- # _depth_ is used to find out nesting depth, to indent accordingly.
305
- def to_json(state = nil, depth = 0, *)
306
- if state
307
- state = State.from_state(state)
308
- state.check_max_nesting(depth)
309
- end
310
- json_transform(state, depth)
382
+ def to_json(state = nil, *)
383
+ state = State.from_state(state)
384
+ state.check_max_nesting
385
+ json_transform(state)
311
386
  end
312
387
 
313
388
  private
314
389
 
315
- def json_transform(state, depth)
390
+ def json_transform(state)
316
391
  delim = ','
317
- if state
318
- delim << state.array_nl
319
- result = '['
320
- result << state.array_nl
321
- depth += 1
322
- first = true
323
- indent = state && !state.array_nl.empty?
324
- each { |value|
325
- result << delim unless first
326
- result << state.indent * depth if indent
327
- result << value.to_json(state, depth)
328
- first = false
329
- }
330
- depth -= 1
331
- result << state.array_nl
392
+ delim << state.array_nl
393
+ result = '['
394
+ result << state.array_nl
395
+ depth = state.depth += 1
396
+ first = true
397
+ indent = !state.array_nl.empty?
398
+ each { |value|
399
+ result << delim unless first
332
400
  result << state.indent * depth if indent
333
- result << ']'
334
- else
335
- '[' << map { |value| value.to_json }.join(delim) << ']'
336
- end
401
+ result << value.to_json(state)
402
+ first = false
403
+ }
404
+ depth = state.depth -= 1
405
+ result << state.array_nl
406
+ result << state.indent * depth if indent
407
+ result << ']'
337
408
  end
338
409
  end
339
410
 
@@ -345,15 +416,16 @@ module JSON
345
416
  module Float
346
417
  # Returns a JSON string representation for this Float number.
347
418
  def to_json(state = nil, *)
419
+ state = State.from_state(state)
348
420
  case
349
421
  when infinite?
350
- if state && state.allow_nan?
422
+ if state.allow_nan?
351
423
  to_s
352
424
  else
353
425
  raise GeneratorError, "#{self} not allowed in JSON"
354
426
  end
355
427
  when nan?
356
- if state && state.allow_nan?
428
+ if state.allow_nan?
357
429
  to_s
358
430
  else
359
431
  raise GeneratorError, "#{self} not allowed in JSON"
@@ -369,9 +441,8 @@ module JSON
369
441
  # This string should be encoded with UTF-8 A call to this method
370
442
  # returns a JSON string encoded with UTF16 big endian characters as
371
443
  # \u????.
372
- def to_json(*args)
373
- state, = *args
374
- state ||= State.from_state(state)
444
+ def to_json(state = nil, *args)
445
+ state = State.from_state(state)
375
446
  if encoding == ::Encoding::UTF_8
376
447
  string = self
377
448
  else
@@ -387,9 +458,8 @@ module JSON
387
458
  # This string should be encoded with UTF-8 A call to this method
388
459
  # returns a JSON string encoded with UTF16 big endian characters as
389
460
  # \u????.
390
- def to_json(*args)
391
- state, = *args
392
- state ||= State.from_state(state)
461
+ def to_json(state = nil, *args)
462
+ state = State.from_state(state)
393
463
  if state.ascii_only?
394
464
  '"' << JSON.utf8_to_json_ascii(self) << '"'
395
465
  else