1require 'json/version' 2require 'json/generic_object' 3 4module JSON 5 class << self 6 # If _object_ is string-like, parse the string and return the parsed result 7 # as a Ruby data structure. Otherwise generate a JSON text from the Ruby 8 # data structure object and return it. 9 # 10 # The _opts_ argument is passed through to generate/parse respectively. See 11 # generate and parse for their documentation. 12 def [](object, opts = {}) 13 if object.respond_to? :to_str 14 JSON.parse(object.to_str, opts) 15 else 16 JSON.generate(object, opts) 17 end 18 end 19 20 # Returns the JSON parser class that is used by JSON. This is either 21 # JSON::Ext::Parser or JSON::Pure::Parser. 22 attr_reader :parser 23 24 # Set the JSON parser class _parser_ to be used by JSON. 25 def parser=(parser) # :nodoc: 26 @parser = parser 27 remove_const :Parser if JSON.const_defined_in?(self, :Parser) 28 const_set :Parser, parser 29 end 30 31 # Return the constant located at _path_. The format of _path_ has to be 32 # either ::A::B::C or A::B::C. In any case, A has to be located at the top 33 # level (absolute namespace path?). If there doesn't exist a constant at 34 # the given path, an ArgumentError is raised. 35 def deep_const_get(path) # :nodoc: 36 path.to_s.split(/::/).inject(Object) do |p, c| 37 case 38 when c.empty? then p 39 when JSON.const_defined_in?(p, c) then p.const_get(c) 40 else 41 begin 42 p.const_missing(c) 43 rescue NameError => e 44 raise ArgumentError, "can't get const #{path}: #{e}" 45 end 46 end 47 end 48 end 49 50 # Set the module _generator_ to be used by JSON. 51 def generator=(generator) # :nodoc: 52 old, $VERBOSE = $VERBOSE, nil 53 @generator = generator 54 generator_methods = generator::GeneratorMethods 55 for const in generator_methods.constants 56 klass = deep_const_get(const) 57 modul = generator_methods.const_get(const) 58 klass.class_eval do 59 instance_methods(false).each do |m| 60 m.to_s == 'to_json' and remove_method m 61 end 62 include modul 63 end 64 end 65 self.state = generator::State 66 const_set :State, self.state 67 const_set :SAFE_STATE_PROTOTYPE, State.new 68 const_set :FAST_STATE_PROTOTYPE, State.new( 69 :indent => '', 70 :space => '', 71 :object_nl => "", 72 :array_nl => "", 73 :max_nesting => false 74 ) 75 const_set :PRETTY_STATE_PROTOTYPE, State.new( 76 :indent => ' ', 77 :space => ' ', 78 :object_nl => "\n", 79 :array_nl => "\n" 80 ) 81 ensure 82 $VERBOSE = old 83 end 84 85 # Returns the JSON generator module that is used by JSON. This is 86 # either JSON::Ext::Generator or JSON::Pure::Generator. 87 attr_reader :generator 88 89 # Returns the JSON generator state class that is used by JSON. This is 90 # either JSON::Ext::Generator::State or JSON::Pure::Generator::State. 91 attr_accessor :state 92 93 # This is create identifier, which is used to decide if the _json_create_ 94 # hook of a class should be called. It defaults to 'json_class'. 95 attr_accessor :create_id 96 end 97 self.create_id = 'json_class' 98 99 NaN = 0.0/0 100 101 Infinity = 1.0/0 102 103 MinusInfinity = -Infinity 104 105 # The base exception for JSON errors. 106 class JSONError < StandardError 107 def self.wrap(exception) 108 obj = new("Wrapped(#{exception.class}): #{exception.message.inspect}") 109 obj.set_backtrace exception.backtrace 110 obj 111 end 112 end 113 114 # This exception is raised if a parser error occurs. 115 class ParserError < JSONError; end 116 117 # This exception is raised if the nesting of parsed data structures is too 118 # deep. 119 class NestingError < ParserError; end 120 121 # :stopdoc: 122 class CircularDatastructure < NestingError; end 123 # :startdoc: 124 125 # This exception is raised if a generator or unparser error occurs. 126 class GeneratorError < JSONError; end 127 # For backwards compatibility 128 UnparserError = GeneratorError 129 130 # This exception is raised if the required unicode support is missing on the 131 # system. Usually this means that the iconv library is not installed. 132 class MissingUnicodeSupport < JSONError; end 133 134 module_function 135 136 # Parse the JSON document _source_ into a Ruby data structure and return it. 137 # 138 # _opts_ can have the following 139 # keys: 140 # * *max_nesting*: The maximum depth of nesting allowed in the parsed data 141 # structures. Disable depth checking with :max_nesting => false. It defaults 142 # to 100. 143 # * *allow_nan*: If set to true, allow NaN, Infinity and -Infinity in 144 # defiance of RFC 4627 to be parsed by the Parser. This option defaults 145 # to false. 146 # * *symbolize_names*: If set to true, returns symbols for the names 147 # (keys) in a JSON object. Otherwise strings are returned. Strings are 148 # the default. 149 # * *create_additions*: If set to false, the Parser doesn't create 150 # additions even if a matching class and create_id was found. This option 151 # defaults to true. 152 # * *object_class*: Defaults to Hash 153 # * *array_class*: Defaults to Array 154 def parse(source, opts = {}) 155 Parser.new(source, opts).parse 156 end 157 158 # Parse the JSON document _source_ into a Ruby data structure and return it. 159 # The bang version of the parse method defaults to the more dangerous values 160 # for the _opts_ hash, so be sure only to parse trusted _source_ documents. 161 # 162 # _opts_ can have the following keys: 163 # * *max_nesting*: The maximum depth of nesting allowed in the parsed data 164 # structures. Enable depth checking with :max_nesting => anInteger. The parse! 165 # methods defaults to not doing max depth checking: This can be dangerous 166 # if someone wants to fill up your stack. 167 # * *allow_nan*: If set to true, allow NaN, Infinity, and -Infinity in 168 # defiance of RFC 4627 to be parsed by the Parser. This option defaults 169 # to true. 170 # * *create_additions*: If set to false, the Parser doesn't create 171 # additions even if a matching class and create_id was found. This option 172 # defaults to true. 173 def parse!(source, opts = {}) 174 opts = { 175 :max_nesting => false, 176 :allow_nan => true 177 }.update(opts) 178 Parser.new(source, opts).parse 179 end 180 181 # Generate a JSON document from the Ruby data structure _obj_ and return 182 # it. _state_ is 183 # * a JSON::State object, 184 # * or a Hash like object (responding to to_hash), 185 # * or an object convertible into a hash by a to_h method, 186 # that is used as or to configure a State object. 187 # 188 # It defaults to a state object, that creates the shortest possible JSON text 189 # in one line, checks for circular data structures and doesn't allow NaN, 190 # Infinity, and -Infinity. 191 # 192 # A _state_ hash can have the following keys: 193 # * *indent*: a string used to indent levels (default: ''), 194 # * *space*: a string that is put after, a : or , delimiter (default: ''), 195 # * *space_before*: a string that is put before a : pair delimiter (default: ''), 196 # * *object_nl*: a string that is put at the end of a JSON object (default: ''), 197 # * *array_nl*: a string that is put at the end of a JSON array (default: ''), 198 # * *allow_nan*: true if NaN, Infinity, and -Infinity should be 199 # generated, otherwise an exception is thrown if these values are 200 # encountered. This options defaults to false. 201 # * *max_nesting*: The maximum depth of nesting allowed in the data 202 # structures from which JSON is to be generated. Disable depth checking 203 # with :max_nesting => false, it defaults to 100. 204 # 205 # See also the fast_generate for the fastest creation method with the least 206 # amount of sanity checks, and the pretty_generate method for some 207 # defaults for pretty output. 208 def generate(obj, opts = nil) 209 if State === opts 210 state, opts = opts, nil 211 else 212 state = SAFE_STATE_PROTOTYPE.dup 213 end 214 if opts 215 if opts.respond_to? :to_hash 216 opts = opts.to_hash 217 elsif opts.respond_to? :to_h 218 opts = opts.to_h 219 else 220 raise TypeError, "can't convert #{opts.class} into Hash" 221 end 222 state = state.configure(opts) 223 end 224 state.generate(obj) 225 end 226 227 # :stopdoc: 228 # I want to deprecate these later, so I'll first be silent about them, and 229 # later delete them. 230 alias unparse generate 231 module_function :unparse 232 # :startdoc: 233 234 # Generate a JSON document from the Ruby data structure _obj_ and return it. 235 # This method disables the checks for circles in Ruby objects. 236 # 237 # *WARNING*: Be careful not to pass any Ruby data structures with circles as 238 # _obj_ argument because this will cause JSON to go into an infinite loop. 239 def fast_generate(obj, opts = nil) 240 if State === opts 241 state, opts = opts, nil 242 else 243 state = FAST_STATE_PROTOTYPE.dup 244 end 245 if opts 246 if opts.respond_to? :to_hash 247 opts = opts.to_hash 248 elsif opts.respond_to? :to_h 249 opts = opts.to_h 250 else 251 raise TypeError, "can't convert #{opts.class} into Hash" 252 end 253 state.configure(opts) 254 end 255 state.generate(obj) 256 end 257 258 # :stopdoc: 259 # I want to deprecate these later, so I'll first be silent about them, and later delete them. 260 alias fast_unparse fast_generate 261 module_function :fast_unparse 262 # :startdoc: 263 264 # Generate a JSON document from the Ruby data structure _obj_ and return it. 265 # The returned document is a prettier form of the document returned by 266 # #unparse. 267 # 268 # The _opts_ argument can be used to configure the generator. See the 269 # generate method for a more detailed explanation. 270 def pretty_generate(obj, opts = nil) 271 if State === opts 272 state, opts = opts, nil 273 else 274 state = PRETTY_STATE_PROTOTYPE.dup 275 end 276 if opts 277 if opts.respond_to? :to_hash 278 opts = opts.to_hash 279 elsif opts.respond_to? :to_h 280 opts = opts.to_h 281 else 282 raise TypeError, "can't convert #{opts.class} into Hash" 283 end 284 state.configure(opts) 285 end 286 state.generate(obj) 287 end 288 289 # :stopdoc: 290 # I want to deprecate these later, so I'll first be silent about them, and later delete them. 291 alias pretty_unparse pretty_generate 292 module_function :pretty_unparse 293 # :startdoc: 294 295 class << self 296 # The global default options for the JSON.load method: 297 # :max_nesting: false 298 # :allow_nan: true 299 # :quirks_mode: true 300 attr_accessor :load_default_options 301 end 302 self.load_default_options = { 303 :max_nesting => false, 304 :allow_nan => true, 305 :quirks_mode => true, 306 :create_additions => true, 307 } 308 309 # Load a ruby data structure from a JSON _source_ and return it. A source can 310 # either be a string-like object, an IO-like object, or an object responding 311 # to the read method. If _proc_ was given, it will be called with any nested 312 # Ruby object as an argument recursively in depth first order. To modify the 313 # default options pass in the optional _options_ argument as well. 314 # 315 # BEWARE: This method is meant to serialise data from trusted user input, 316 # like from your own database server or clients under your control, it could 317 # be dangerous to allow untrusted users to pass JSON sources into it. The 318 # default options for the parser can be changed via the load_default_options 319 # method. 320 # 321 # This method is part of the implementation of the load/dump interface of 322 # Marshal and YAML. 323 def load(source, proc = nil, options = {}) 324 opts = load_default_options.merge options 325 if source.respond_to? :to_str 326 source = source.to_str 327 elsif source.respond_to? :to_io 328 source = source.to_io.read 329 elsif source.respond_to?(:read) 330 source = source.read 331 end 332 if opts[:quirks_mode] && (source.nil? || source.empty?) 333 source = 'null' 334 end 335 result = parse(source, opts) 336 recurse_proc(result, &proc) if proc 337 result 338 end 339 340 # Recursively calls passed _Proc_ if the parsed data structure is an _Array_ or _Hash_ 341 def recurse_proc(result, &proc) 342 case result 343 when Array 344 result.each { |x| recurse_proc x, &proc } 345 proc.call result 346 when Hash 347 result.each { |x, y| recurse_proc x, &proc; recurse_proc y, &proc } 348 proc.call result 349 else 350 proc.call result 351 end 352 end 353 354 alias restore load 355 module_function :restore 356 357 class << self 358 # The global default options for the JSON.dump method: 359 # :max_nesting: false 360 # :allow_nan: true 361 # :quirks_mode: true 362 attr_accessor :dump_default_options 363 end 364 self.dump_default_options = { 365 :max_nesting => false, 366 :allow_nan => true, 367 :quirks_mode => true, 368 } 369 370 # Dumps _obj_ as a JSON string, i.e. calls generate on the object and returns 371 # the result. 372 # 373 # If anIO (an IO-like object or an object that responds to the write method) 374 # was given, the resulting JSON is written to it. 375 # 376 # If the number of nested arrays or objects exceeds _limit_, an ArgumentError 377 # exception is raised. This argument is similar (but not exactly the 378 # same!) to the _limit_ argument in Marshal.dump. 379 # 380 # The default options for the generator can be changed via the 381 # dump_default_options method. 382 # 383 # This method is part of the implementation of the load/dump interface of 384 # Marshal and YAML. 385 def dump(obj, anIO = nil, limit = nil) 386 if anIO and limit.nil? 387 anIO = anIO.to_io if anIO.respond_to?(:to_io) 388 unless anIO.respond_to?(:write) 389 limit = anIO 390 anIO = nil 391 end 392 end 393 opts = JSON.dump_default_options 394 limit and opts.update(:max_nesting => limit) 395 result = generate(obj, opts) 396 if anIO 397 anIO.write result 398 anIO 399 else 400 result 401 end 402 rescue JSON::NestingError 403 raise ArgumentError, "exceed depth limit" 404 end 405 406 # Swap consecutive bytes of _string_ in place. 407 def self.swap!(string) # :nodoc: 408 0.upto(string.size / 2) do |i| 409 break unless string[2 * i + 1] 410 string[2 * i], string[2 * i + 1] = string[2 * i + 1], string[2 * i] 411 end 412 string 413 end 414 415 # Shortuct for iconv. 416 if ::String.method_defined?(:encode) && 417 # XXX Rubinius doesn't support ruby 1.9 encoding yet 418 defined?(RUBY_ENGINE) && RUBY_ENGINE != 'rbx' 419 then 420 # Encodes string using Ruby's _String.encode_ 421 def self.iconv(to, from, string) 422 string.encode(to, from) 423 end 424 else 425 require 'iconv' 426 # Encodes string using _iconv_ library 427 def self.iconv(to, from, string) 428 Iconv.conv(to, from, string) 429 end 430 end 431 432 if ::Object.method(:const_defined?).arity == 1 433 def self.const_defined_in?(modul, constant) 434 modul.const_defined?(constant) 435 end 436 else 437 def self.const_defined_in?(modul, constant) 438 modul.const_defined?(constant, false) 439 end 440 end 441end 442 443module ::Kernel 444 private 445 446 # Outputs _objs_ to STDOUT as JSON strings in the shortest form, that is in 447 # one line. 448 def j(*objs) 449 objs.each do |obj| 450 puts JSON::generate(obj, :allow_nan => true, :max_nesting => false) 451 end 452 nil 453 end 454 455 # Ouputs _objs_ to STDOUT as JSON strings in a pretty format, with 456 # indentation and over many lines. 457 def jj(*objs) 458 objs.each do |obj| 459 puts JSON::pretty_generate(obj, :allow_nan => true, :max_nesting => false) 460 end 461 nil 462 end 463 464 # If _object_ is string-like, parse the string and return the parsed result as 465 # a Ruby data structure. Otherwise, generate a JSON text from the Ruby data 466 # structure object and return it. 467 # 468 # The _opts_ argument is passed through to generate/parse respectively. See 469 # generate and parse for their documentation. 470 def JSON(object, *args) 471 if object.respond_to? :to_str 472 JSON.parse(object.to_str, args.first) 473 else 474 JSON.generate(object, args.first) 475 end 476 end 477end 478 479# Extends any Class to include _json_creatable?_ method. 480class ::Class 481 # Returns true if this class can be used to create an instance 482 # from a serialised JSON string. The class has to implement a class 483 # method _json_create_ that expects a hash as first parameter. The hash 484 # should include the required data. 485 def json_creatable? 486 respond_to?(:json_create) 487 end 488end 489