From 8208d3f3936968ef6e853b1e2621bc0f3d4b1445 Mon Sep 17 00:00:00 2001 From: Florian Frank Date: Thu, 9 Jun 2011 13:40:11 +0200 Subject: Apply patch by Cory Monty . --- ext/json/ext/generator/generator.c | 1 + lib/json.rb | 52 ++++++++++++++++++++++++++++++++++++++ lib/json/add/core.rb | 39 +++++++++++++++++++++++++--- lib/json/common.rb | 6 ++++- 4 files changed, 93 insertions(+), 5 deletions(-) diff --git a/ext/json/ext/generator/generator.c b/ext/json/ext/generator/generator.c index 6505882..f71eebb 100644 --- a/ext/json/ext/generator/generator.c +++ b/ext/json/ext/generator/generator.c @@ -561,6 +561,7 @@ static VALUE mFalseClass_to_json(int argc, VALUE *argv, VALUE self) /* * call-seq: to_json(*) * + * Returns a JSON string for nil: 'null'. */ static VALUE mNilClass_to_json(int argc, VALUE *argv, VALUE self) { diff --git a/lib/json.rb b/lib/json.rb index 789b0de..cc33f72 100644 --- a/lib/json.rb +++ b/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 '' 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\"}" +# +# JSON.generate only allows objects or arrays to be converted +# to JSON syntax. While to_json 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/lib/json/add/core.rb b/lib/json/add/core.rb index 7a901d0..955fdc6 100644 --- a/lib/json/add/core.rb +++ b/lib/json/add/core.rb @@ -6,20 +6,26 @@ unless defined?(::JSON::JSON_LOADED) and ::JSON::JSON_LOADED end require 'date' +# Symbol serialization/deserialization class Symbol + # Stores class name (Symbol) with String representation of Symbol as a JSON string. def to_json(*a) { JSON.create_id => self.class.name, 's' => to_s, }.to_json(*a) end - + + # Deserializes JSON string by converting the string 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 @@ -30,7 +36,8 @@ class Time at(object['s'], object['n'] / 1000) end end - + + # Stores class name (Time) with number of seconds since epoch and number of microseconds for Time as JSON string def to_json(*args) { JSON.create_id => self.class.name, @@ -40,13 +47,17 @@ class Time end end +# Date serialization/deserialization class Date + + # Deserializes JSON string by converting Julian year y, month m, day d and Day of Calendar Reform sg to Date. def self.json_create(object) civil(*object.values_at('y', 'm', 'd', 'sg')) end alias start sg unless method_defined?(:start) - + + # Stores class name (Date) with Julian year y, month m, day d and Day of Calendar Reform sg as JSON string def to_json(*args) { JSON.create_id => self.class.name, @@ -58,7 +69,10 @@ class Date end end +# DateTime serialization/deserialization class DateTime + + # Deserializes JSON string by converting year y, month m, day d, hour H, minute M, second S, offset of and Day of Calendar Reform sg to DateTime. def self.json_create(object) args = object.values_at('y', 'm', 'd', 'H', 'M', 'S') of_a, of_b = object['of'].split('/') @@ -72,7 +86,8 @@ class DateTime end alias start sg unless method_defined?(:start) - + + # Stores class name (DateTime) with Julian year y, month m, day d, hour H, minute M, second S, offset of and Day of Calendar Reform sg as JSON string def to_json(*args) { JSON.create_id => self.class.name, @@ -88,11 +103,15 @@ class DateTime end end +# Range serialization/deserialization class Range + + # Deserializes JSON string by constructing new Range object with arguments a serialized by to_json. def self.json_create(object) new(*object['a']) end + # Stores class name (Range) with JSON array of arguments a which include first (integer), last (integer), and exclude_end? (boolean) as JSON string. def to_json(*args) { JSON.create_id => self.class.name, @@ -101,11 +120,15 @@ class Range end end +# Struct serialization/deserialization class Struct + + # Deserializes JSON string by constructing new Struct object with values v serialized by to_json. def self.json_create(object) new(*object['v']) end + # Stores class name (Struct) with Struct values v as a JSON string. Only named structs are supported. def to_json(*args) klass = self.class.name klass.to_s.empty? and raise JSON::JSONError, "Only named structs are supported!" @@ -116,13 +139,17 @@ class Struct end end +# Exception serialization/deserialization class Exception + + # Deserializes JSON string by constructing new Exception object with message m and backtrace b serialized with to_json def self.json_create(object) result = new(object['m']) result.set_backtrace object['b'] result end + # Stores class name (Exception) with message m and backtrace array b as JSON string def to_json(*args) { JSON.create_id => self.class.name, @@ -132,11 +159,15 @@ class Exception end end +# Regexp serialization/deserialization class Regexp + + # Deserializes JSON string by constructing new Regexp object with source s (Regexp or String) and options o serialized by to_json def self.json_create(object) new(object['s'], object['o']) end + # Stores class name (Regexp) with options o and source s (Regexp or String) as JSON string def to_json(*) { JSON.create_id => self.class.name, diff --git a/lib/json/common.rb b/lib/json/common.rb index f8ce2da..ee933ed 100644 --- a/lib/json/common.rb +++ b/lib/json/common.rb @@ -291,7 +291,8 @@ module JSON recurse_proc(result, &proc) if proc 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 @@ -351,11 +352,13 @@ module JSON # Shortuct for iconv. 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.iconv(to, from, string).first end @@ -408,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 -- cgit v1.2.1