summaryrefslogtreecommitdiff
path: root/ext/json/lib/json
diff options
context:
space:
mode:
Diffstat (limited to 'ext/json/lib/json')
-rw-r--r--ext/json/lib/json/add/core.rb147
-rw-r--r--ext/json/lib/json/common.rb31
-rw-r--r--ext/json/lib/json/ext.rb19
-rw-r--r--ext/json/lib/json/version.rb2
4 files changed, 165 insertions, 34 deletions
diff --git a/ext/json/lib/json/add/core.rb b/ext/json/lib/json/add/core.rb
index 03a00dded4..e9850af8f6 100644
--- a/ext/json/lib/json/add/core.rb
+++ b/ext/json/lib/json/add/core.rb
@@ -1,26 +1,37 @@
# This file contains implementations of ruby core's custom objects for
# serialisation/deserialisation.
-unless Object.const_defined?(:JSON) and ::JSON.const_defined?(:JSON_LOADED) and
- ::JSON::JSON_LOADED
+unless defined?(::JSON::JSON_LOADED) and ::JSON::JSON_LOADED
require 'json'
end
require 'date'
+# Symbol serialization/deserialization
class Symbol
- def to_json(*a)
+ # 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,
- }.to_json(*a)
+ '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
@@ -32,34 +43,59 @@ class Time
end
end
- def to_json(*args)
+ # 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
- }.to_json(*args)
+ '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)
- def to_json(*args)
+ # 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,
- }.to_json(*args)
+ }
+ 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('/')
@@ -74,7 +110,9 @@ class DateTime
alias start sg unless method_defined?(:start)
- def to_json(*args)
+ # 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,
@@ -85,64 +123,121 @@ class DateTime
'S' => sec,
'of' => offset.to_s,
'sg' => start,
- }.to_json(*args)
+ }
+ 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
- def to_json(*args)
+ # 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? ]
- }.to_json(*args)
+ 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
- def to_json(*args)
+ # 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,
- }.to_json(*args)
+ '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
- def to_json(*args)
+ # 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,
- }.to_json(*args)
+ '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
- def to_json(*)
+ # 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,
- }.to_json
+ }
+ 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
diff --git a/ext/json/lib/json/common.rb b/ext/json/lib/json/common.rb
index dd9fef8fad..1a5f0481e8 100644
--- a/ext/json/lib/json/common.rb
+++ b/ext/json/lib/json/common.rb
@@ -23,7 +23,7 @@ module JSON
# Set the JSON parser class _parser_ to be used by JSON.
def parser=(parser) # :nodoc:
@parser = parser
- remove_const :Parser if const_defined? :Parser
+ remove_const :Parser if JSON.const_defined_in?(self, :Parser)
const_set :Parser, parser
end
@@ -34,8 +34,8 @@ module JSON
def deep_const_get(path) # :nodoc:
path.to_s.split(/::/).inject(Object) do |p, c|
case
- when c.empty? then p
- when p.const_defined?(c) then p.const_get(c)
+ when c.empty? then p
+ when JSON.const_defined_in?(p, c) then p.const_get(c)
else
begin
p.const_missing(c)
@@ -292,6 +292,7 @@ module JSON
result
end
+ # Recursively calls passed _Proc_ if the parsed data structure is an _Array_ or _Hash_
def recurse_proc(result, &proc)
case result
when Array
@@ -340,17 +341,38 @@ module JSON
raise ArgumentError, "exceed depth limit"
end
+ # Swap consecutive bytes of _string_ in place.
+ def self.swap!(string) # :nodoc:
+ 0.upto(string.size / 2) do |i|
+ break unless string[2 * i + 1]
+ string[2 * i], string[2 * i + 1] = string[2 * i + 1], string[2 * i]
+ end
+ string
+ end
+
# Shortuct for iconv.
- if String.method_defined?(:encode)
+ if ::String.method_defined?(:encode)
+ # Encodes string using Ruby's _String.encode_
def self.iconv(to, from, string)
string.encode(to, from)
end
else
require 'iconv'
+ # Encodes string using _iconv_ library
def self.iconv(to, from, string)
Iconv.conv(to, from, string)
end
end
+
+ if ::Object.method(:const_defined?).arity == 1
+ def self.const_defined_in?(modul, constant)
+ modul.const_defined?(constant)
+ end
+ else
+ def self.const_defined_in?(modul, constant)
+ modul.const_defined?(constant, false)
+ end
+ end
end
module ::Kernel
@@ -389,6 +411,7 @@ module ::Kernel
end
end
+# Extends any Class to include _json_creatable?_ method.
class ::Class
# Returns true, if this class can be used to create an instance
# from a serialised JSON string. The class has to implement a class
diff --git a/ext/json/lib/json/ext.rb b/ext/json/lib/json/ext.rb
index a5e3148c57..1fbc3fd7d1 100644
--- a/ext/json/lib/json/ext.rb
+++ b/ext/json/lib/json/ext.rb
@@ -4,12 +4,25 @@ module JSON
# This module holds all the modules/classes that implement JSON's
# functionality as C extensions.
module Ext
- require 'json/ext/parser'
- require 'json/ext/generator'
+ begin
+ if defined?(RUBY_ENGINE) == 'constant' and RUBY_ENGINE == 'ruby' and RUBY_VERSION =~ /\A1\.9\./
+ require 'json/ext/1.9/parser'
+ require 'json/ext/1.9/generator'
+ elsif !defined?(RUBY_ENGINE) && RUBY_VERSION =~ /\A1\.8\./
+ require 'json/ext/1.8/parser'
+ require 'json/ext/1.8/generator'
+ else
+ require 'json/ext/parser'
+ require 'json/ext/generator'
+ end
+ rescue LoadError
+ require 'json/ext/parser'
+ require 'json/ext/generator'
+ end
$DEBUG and warn "Using Ext extension for JSON."
JSON.parser = Parser
JSON.generator = Generator
end
- JSON_LOADED = true unless const_defined?(:JSON_LOADED)
+ JSON_LOADED = true unless defined?(::JSON::JSON_LOADED)
end
diff --git a/ext/json/lib/json/version.rb b/ext/json/lib/json/version.rb
index beff08b1c7..2175ac0f90 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.0'
+ VERSION = '1.5.4'
VERSION_ARRAY = VERSION.split(/\./).map { |x| x.to_i } # :nodoc:
VERSION_MAJOR = VERSION_ARRAY[0] # :nodoc:
VERSION_MINOR = VERSION_ARRAY[1] # :nodoc: