diff options
Diffstat (limited to 'ext/json/lib/json')
-rw-r--r-- | ext/json/lib/json/add/core.rb | 250 | ||||
-rw-r--r-- | ext/json/lib/json/common.rb | 45 | ||||
-rw-r--r-- | ext/json/lib/json/ext.rb | 6 | ||||
-rw-r--r-- | ext/json/lib/json/version.rb | 2 |
4 files changed, 56 insertions, 247 deletions
diff --git a/ext/json/lib/json/add/core.rb b/ext/json/lib/json/add/core.rb index 1ae00d01a5..77d9dc0b20 100644 --- a/ext/json/lib/json/add/core.rb +++ b/ext/json/lib/json/add/core.rb @@ -1,243 +1,11 @@ -# This file contains implementations of ruby core's custom objects for +# This file requires the implementations of ruby core's custom objects for # serialisation/deserialisation. -unless defined?(::JSON::JSON_LOADED) and ::JSON::JSON_LOADED - require 'json' -end -require 'date' - -# Symbol serialization/deserialization -class Symbol - # Returns a hash, that will be turned into a JSON object and represent this - # object. - def as_json(*) - { - JSON.create_id => self.class.name, - 's' => to_s, - } - end - - # Stores class name (Symbol) with String representation of Symbol as a JSON string. - def to_json(*a) - as_json.to_json(*a) - end - - # Deserializes JSON string by converting the <tt>string</tt> value stored in the object to a Symbol - def self.json_create(o) - o['s'].to_sym - end -end - -# Time serialization/deserialization -class Time - - # Deserializes JSON string by converting time since epoch to Time - def self.json_create(object) - if usec = object.delete('u') # used to be tv_usec -> tv_nsec - object['n'] = usec * 1000 - end - if respond_to?(:tv_nsec) - at(*object.values_at('s', 'n')) - else - at(object['s'], object['n'] / 1000) - end - end - - # Returns a hash, that will be turned into a JSON object and represent this - # object. - def as_json(*) - { - JSON.create_id => self.class.name, - 's' => tv_sec, - 'n' => respond_to?(:tv_nsec) ? tv_nsec : tv_usec * 1000 - } - end - - # Stores class name (Time) with number of seconds since epoch and number of - # microseconds for Time as JSON string - def to_json(*args) - as_json.to_json(*args) - end -end - -# Date serialization/deserialization -class Date - - # Deserializes JSON string by converting Julian year <tt>y</tt>, month - # <tt>m</tt>, day <tt>d</tt> and Day of Calendar Reform <tt>sg</tt> to Date. - def self.json_create(object) - civil(*object.values_at('y', 'm', 'd', 'sg')) - end - - alias start sg unless method_defined?(:start) - - # Returns a hash, that will be turned into a JSON object and represent this - # object. - def as_json(*) - { - JSON.create_id => self.class.name, - 'y' => year, - 'm' => month, - 'd' => day, - 'sg' => start, - } - end - - # Stores class name (Date) with Julian year <tt>y</tt>, month <tt>m</tt>, day - # <tt>d</tt> and Day of Calendar Reform <tt>sg</tt> as JSON string - def to_json(*args) - as_json.to_json(*args) - end -end - -# DateTime serialization/deserialization -class DateTime - - # Deserializes JSON string by converting year <tt>y</tt>, month <tt>m</tt>, - # day <tt>d</tt>, hour <tt>H</tt>, minute <tt>M</tt>, second <tt>S</tt>, - # offset <tt>of</tt> and Day of Calendar Reform <tt>sg</tt> to DateTime. - def self.json_create(object) - args = object.values_at('y', 'm', 'd', 'H', 'M', 'S') - of_a, of_b = object['of'].split('/') - if of_b and of_b != '0' - args << Rational(of_a.to_i, of_b.to_i) - else - args << of_a - end - args << object['sg'] - civil(*args) - end - - alias start sg unless method_defined?(:start) - - # Returns a hash, that will be turned into a JSON object and represent this - # object. - def as_json(*) - { - JSON.create_id => self.class.name, - 'y' => year, - 'm' => month, - 'd' => day, - 'H' => hour, - 'M' => min, - 'S' => sec, - 'of' => offset.to_s, - 'sg' => start, - } - end - - # Stores class name (DateTime) with Julian year <tt>y</tt>, month <tt>m</tt>, - # day <tt>d</tt>, hour <tt>H</tt>, minute <tt>M</tt>, second <tt>S</tt>, - # offset <tt>of</tt> and Day of Calendar Reform <tt>sg</tt> as JSON string - def to_json(*args) - as_json.to_json(*args) - end -end - -# Range serialization/deserialization -class Range - - # Deserializes JSON string by constructing new Range object with arguments - # <tt>a</tt> serialized by <tt>to_json</tt>. - def self.json_create(object) - new(*object['a']) - end - - # Returns a hash, that will be turned into a JSON object and represent this - # object. - def as_json(*) - { - JSON.create_id => self.class.name, - 'a' => [ first, last, exclude_end? ] - } - end - - # Stores class name (Range) with JSON array of arguments <tt>a</tt> which - # include <tt>first</tt> (integer), <tt>last</tt> (integer), and - # <tt>exclude_end?</tt> (boolean) as JSON string. - def to_json(*args) - as_json.to_json(*args) - end -end - -# Struct serialization/deserialization -class Struct - - # Deserializes JSON string by constructing new Struct object with values - # <tt>v</tt> serialized by <tt>to_json</tt>. - def self.json_create(object) - new(*object['v']) - end - - # Returns a hash, that will be turned into a JSON object and represent this - # object. - def as_json(*) - klass = self.class.name - klass.to_s.empty? and raise JSON::JSONError, "Only named structs are supported!" - { - JSON.create_id => klass, - 'v' => values, - } - end - - # Stores class name (Struct) with Struct values <tt>v</tt> as a JSON string. - # Only named structs are supported. - def to_json(*args) - as_json.to_json(*args) - end -end - -# Exception serialization/deserialization -class Exception - - # Deserializes JSON string by constructing new Exception object with message - # <tt>m</tt> and backtrace <tt>b</tt> serialized with <tt>to_json</tt> - def self.json_create(object) - result = new(object['m']) - result.set_backtrace object['b'] - result - end - - # Returns a hash, that will be turned into a JSON object and represent this - # object. - def as_json(*) - { - JSON.create_id => self.class.name, - 'm' => message, - 'b' => backtrace, - } - end - - # Stores class name (Exception) with message <tt>m</tt> and backtrace array - # <tt>b</tt> as JSON string - def to_json(*args) - as_json.to_json(*args) - end -end - -# Regexp serialization/deserialization -class Regexp - - # Deserializes JSON string by constructing new Regexp object with source - # <tt>s</tt> (Regexp or String) and options <tt>o</tt> serialized by - # <tt>to_json</tt> - def self.json_create(object) - new(object['s'], object['o']) - end - - # Returns a hash, that will be turned into a JSON object and represent this - # object. - def as_json(*) - { - JSON.create_id => self.class.name, - 'o' => options, - 's' => source, - } - end - - # Stores class name (Regexp) with options <tt>o</tt> and source <tt>s</tt> - # (Regexp or String) as JSON string - def to_json(*) - as_json.to_json - end -end +require 'json/add/date' +require 'json/add/date_time' +require 'json/add/exception' +require 'json/add/range' +require 'json/add/regexp' +require 'json/add/struct' +require 'json/add/symbol' +require 'json/add/time' diff --git a/ext/json/lib/json/common.rb b/ext/json/lib/json/common.rb index 43e249c954..cf7a8b9003 100644 --- a/ext/json/lib/json/common.rb +++ b/ext/json/lib/json/common.rb @@ -284,22 +284,40 @@ module JSON module_function :pretty_unparse # :startdoc: + class << self + # The global default options for the JSON.load method: + # :max_nesting: false + # :allow_nan: true + # :quirks_mode: true + attr_accessor :load_default_options + end + self.load_default_options = { + :max_nesting => false, + :allow_nan => true, + :quirks_mode => true, + } + # Load a ruby data structure from a JSON _source_ and return it. A source can # either be a string-like object, an IO-like object, or an object responding # to the read method. If _proc_ was given, it will be called with any nested - # Ruby object as an argument recursively in depth first order. + # Ruby object as an argument recursively in depth first order. The default + # options for the parser can be changed via the load_default_options method. # # This method is part of the implementation of the load/dump interface of # Marshal and YAML. def load(source, proc = nil) + opts = load_default_options if source.respond_to? :to_str source = source.to_str elsif source.respond_to? :to_io source = source.to_io.read - else + elsif source.respond_to?(:read) source = source.read end - result = parse(source, :max_nesting => false, :allow_nan => true) + if opts[:quirks_mode] && (source.nil? || source.empty?) + source = 'null' + end + result = parse(source, opts) recurse_proc(result, &proc) if proc result end @@ -321,6 +339,19 @@ module JSON alias restore load module_function :restore + class << self + # The global default options for the JSON.dump method: + # :max_nesting: false + # :allow_nan: true + # :quirks_mode: true + attr_accessor :dump_default_options + end + self.dump_default_options = { + :max_nesting => false, + :allow_nan => true, + :quirks_mode => true, + } + # Dumps _obj_ as a JSON string, i.e. calls generate on the object and returns # the result. # @@ -331,6 +362,9 @@ module JSON # exception is raised. This argument is similar (but not exactly the # same!) to the _limit_ argument in Marshal.dump. # + # The default options for the generator can be changed via the + # dump_default_options method. + # # This method is part of the implementation of the load/dump interface of # Marshal and YAML. def dump(obj, anIO = nil, limit = nil) @@ -341,8 +375,9 @@ module JSON anIO = nil end end - limit ||= 0 - result = generate(obj, :allow_nan => true, :max_nesting => limit) + opts = JSON.dump_default_options + limit and opts.update(:max_nesting => limit) + result = generate(obj, opts) if anIO anIO.write result anIO diff --git a/ext/json/lib/json/ext.rb b/ext/json/lib/json/ext.rb index 7264a857fa..c5f813181d 100644 --- a/ext/json/lib/json/ext.rb +++ b/ext/json/lib/json/ext.rb @@ -1,3 +1,9 @@ +if ENV['SIMPLECOV_COVERAGE'].to_i == 1 + require 'simplecov' + SimpleCov.start do + add_filter "/tests/" + end +end require 'json/common' module JSON diff --git a/ext/json/lib/json/version.rb b/ext/json/lib/json/version.rb index 2175ac0f90..63ebcf3195 100644 --- a/ext/json/lib/json/version.rb +++ b/ext/json/lib/json/version.rb @@ -1,6 +1,6 @@ module JSON # JSON version - VERSION = '1.5.4' + VERSION = '1.6.6' VERSION_ARRAY = VERSION.split(/\./).map { |x| x.to_i } # :nodoc: VERSION_MAJOR = VERSION_ARRAY[0] # :nodoc: VERSION_MINOR = VERSION_ARRAY[1] # :nodoc: |