summaryrefslogtreecommitdiff
path: root/ext/json/lib
diff options
context:
space:
mode:
authornaruse <naruse@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2011-07-10 08:01:04 +0000
committernaruse <naruse@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2011-07-10 08:01:04 +0000
commita2e497d5ede45bd4f4a57f494027020d7bd1733b (patch)
tree9773233b59c71615a1b88fd5807b30d2e0f09345 /ext/json/lib
parenta119b9d146fea877acc1e9ba5df0702163ce917a (diff)
* ext/json: Merge json gem 1.5.4+ (f7f78896607b6f6226cd).
[Bug #4700] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@32493 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'ext/json/lib')
-rw-r--r--ext/json/lib/json.rb52
-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
5 files changed, 217 insertions, 34 deletions
diff --git a/ext/json/lib/json.rb b/ext/json/lib/json.rb
index 789b0de546..d7bc1a2d23 100644
--- a/ext/json/lib/json.rb
+++ b/ext/json/lib/json.rb
@@ -1,3 +1,55 @@
+##
+# = JavaScript Object Notation (JSON)
+#
+# JSON is a lightweight data-interchange format. It is easy for us
+# humans to read and write. Plus, equally simple for machines to generate or parse.
+# JSON is completely language agnostic, making it the ideal interchange format.
+#
+# Built on two universally available structures:
+# 1. A collection of name/value pairs. Often referred to as an _object_, hash table, record, struct, keyed list, or associative array.
+# 2. An orderd list of values. More commonly named as an _array_, vector, sequence, or list.
+#
+# To read more about JSON visit: http://json.org
+#
+# == Parsing JSON
+#
+# To parse a JSON string received by another application, or generated within
+# your existing application:
+#
+# require 'json'
+#
+# my_hash = JSON.parse('{"hello": "goodbye"}')
+# puts my_hash["hello"] => "goodbye"
+#
+# Notice the extra quotes <tt>''</tt> around the hash notation. Ruby expects
+# the argument to be a string and can't convert objects like a hash or array.
+#
+# Ruby converts your string into a hash
+#
+# == Generating JSON
+#
+# Creating a JSON string for communication or serialization is
+# just as simple.
+#
+# require 'json'
+#
+# my_hash = {:hello => "goodbye"}
+# puts JSON.generate(my_hash) => "{\"hello\":\"goodbye\"}"
+#
+# Or an alternative way:
+#
+# require 'json'
+# puts {:hello => "goodbye"}.to_json => "{\"hello\":\"goodbye\"}"
+#
+# <tt>JSON.generate</tt> only allows objects or arrays to be converted
+# to JSON syntax. While <tt>to_json</tt> accepts many Ruby classes
+# even though it only acts a method for serialization:
+#
+# require 'json'
+#
+# 1.to_json => "1"
+#
+
require 'json/common'
module JSON
require 'json/version'
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: