[前][次][番号順一覧][スレッド一覧]

ruby-changes:21073

From: naruse <ko1@a...>
Date: Tue, 30 Aug 2011 11:23:27 +0900 (JST)
Subject: [ruby-changes:21073] naruse:r33122 (trunk): * ext/json: Merge json gem 1.5.4+ (2149f4185c598fb97db1).

naruse	2011-08-30 11:23:12 +0900 (Tue, 30 Aug 2011)

  New Revision: 33122

  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=33122

  Log:
    * ext/json: Merge json gem 1.5.4+ (2149f4185c598fb97db1).
      [Bug #5173] [ruby-core:38866]

  Modified files:
    trunk/ChangeLog
    trunk/ext/json/generator/generator.c
    trunk/ext/json/generator/generator.h
    trunk/ext/json/lib/json/add/core.rb
    trunk/ext/json/lib/json/common.rb
    trunk/ext/json/lib/json/ext.rb
    trunk/ext/json/lib/json.rb
    trunk/ext/json/parser/parser.c
    trunk/ext/json/parser/parser.h
    trunk/ext/json/parser/parser.rl
    trunk/test/json/test_json.rb
    trunk/test/json/test_json_addition.rb
    trunk/test/json/test_json_generate.rb

Index: ChangeLog
===================================================================
--- ChangeLog	(revision 33121)
+++ ChangeLog	(revision 33122)
@@ -1,3 +1,8 @@
+Tue Aug 30 11:06:19 2011  NARUSE, Yui  <naruse@r...>
+
+	* ext/json: Merge json gem 1.5.4+ (2149f4185c598fb97db1).
+	  [Bug #5173] [ruby-core:38866]
+
 Tue Aug 30 09:57:50 2011  KOSAKI Motohiro  <kosaki.motohiro@g...>
 
 	* lib/thread.rb (Queue#pop): fix a race against Thread.wakeup.
Index: ext/json/generator/generator.c
===================================================================
--- ext/json/generator/generator.c	(revision 33121)
+++ ext/json/generator/generator.c	(revision 33122)
@@ -13,8 +13,8 @@
 
 static ID i_to_s, i_to_json, i_new, i_indent, i_space, i_space_before,
           i_object_nl, i_array_nl, i_max_nesting, i_allow_nan, i_ascii_only,
-          i_pack, i_unpack, i_create_id, i_extend, i_key_p, i_aref, i_send,
-          i_respond_to_p, i_match, i_keys, i_depth, i_dup;
+          i_quirks_mode, i_pack, i_unpack, i_create_id, i_extend, i_key_p,
+          i_aref, i_send, i_respond_to_p, i_match, i_keys, i_depth, i_dup;
 
 /*
  * Copyright 2001-2004 Unicode, Inc.
@@ -349,6 +349,16 @@
     }
 }
 
+static void fbuffer_append_str(FBuffer *fb, VALUE str)
+{
+    const char *newstr = StringValuePtr(str);
+    unsigned long len = RSTRING_LEN(str);
+
+    RB_GC_GUARD(str);
+
+    fbuffer_append(fb, newstr, len);
+}
+
 static void fbuffer_append_char(FBuffer *fb, char newchr)
 {
     fbuffer_inc_capa(fb, 1);
@@ -688,6 +698,8 @@
     state->allow_nan = RTEST(tmp);
     tmp = rb_hash_aref(opts, ID2SYM(i_ascii_only));
     state->ascii_only = RTEST(tmp);
+    tmp = rb_hash_aref(opts, ID2SYM(i_quirks_mode));
+    state->quirks_mode = RTEST(tmp);
     return self;
 }
 
@@ -708,6 +720,7 @@
     rb_hash_aset(result, ID2SYM(i_array_nl), rb_str_new(state->array_nl, state->array_nl_len));
     rb_hash_aset(result, ID2SYM(i_allow_nan), state->allow_nan ? Qtrue : Qfalse);
     rb_hash_aset(result, ID2SYM(i_ascii_only), state->ascii_only ? Qtrue : Qfalse);
+    rb_hash_aset(result, ID2SYM(i_quirks_mode), state->quirks_mode ? Qtrue : Qfalse);
     rb_hash_aset(result, ID2SYM(i_max_nesting), LONG2FIX(state->max_nesting));
     rb_hash_aset(result, ID2SYM(i_depth), LONG2FIX(state->depth));
     return result;
@@ -852,7 +865,7 @@
 static void generate_json_bignum(FBuffer *buffer, VALUE Vstate, JSON_Generator_State *state, VALUE obj)
 {
     VALUE tmp = rb_funcall(obj, i_to_s, 0);
-    fbuffer_append(buffer, RSTRING_PAIR(tmp));
+    fbuffer_append_str(buffer, tmp);
 }
 
 static void generate_json_float(FBuffer *buffer, VALUE Vstate, JSON_Generator_State *state, VALUE obj)
@@ -869,7 +882,7 @@
             rb_raise(eGeneratorError, "%u: %s not allowed in JSON", __LINE__, StringValueCStr(tmp));
         }
     }
-    fbuffer_append(buffer, RSTRING_PAIR(tmp));
+    fbuffer_append_str(buffer, tmp);
 }
 
 static void generate_json(FBuffer *buffer, VALUE Vstate, JSON_Generator_State *state, VALUE obj)
@@ -897,7 +910,7 @@
     } else if (rb_respond_to(obj, i_to_json)) {
         tmp = rb_funcall(obj, i_to_json, 1, Vstate);
         Check_Type(tmp, T_STRING);
-        fbuffer_append(buffer, RSTRING_PAIR(tmp));
+        fbuffer_append_str(buffer, tmp);
     } else {
         tmp = rb_funcall(obj, i_to_s, 0);
         Check_Type(tmp, T_STRING);
@@ -961,11 +974,14 @@
 {
     VALUE result = cState_partial_generate(self, obj);
     VALUE re, args[2];
-    args[0] = rb_str_new2("\\A\\s*(?:\\[.*\\]|\\{.*\\})\\s*\\Z");
-    args[1] = CRegexp_MULTILINE;
-    re = rb_class_new_instance(2, args, rb_cRegexp);
-    if (NIL_P(rb_funcall(re, i_match, 1, result))) {
-        rb_raise(eGeneratorError, "only generation of JSON objects or arrays allowed");
+    GET_STATE(self);
+    if (!state->quirks_mode) {
+        args[0] = rb_str_new2("\\A\\s*(?:\\[.*\\]|\\{.*\\})\\s*\\Z");
+        args[1] = CRegexp_MULTILINE;
+        re = rb_class_new_instance(2, args, rb_cRegexp);
+        if (NIL_P(rb_funcall(re, i_match, 1, result))) {
+            rb_raise(eGeneratorError, "only generation of JSON objects or arrays allowed");
+        }
     }
     return result;
 }
@@ -1288,6 +1304,29 @@
 }
 
 /*
+ * call-seq: quirks_mode?
+ *
+ * Returns true, if quirks mode is enabled. Otherwise returns false.
+ */
+static VALUE cState_quirks_mode_p(VALUE self)
+{
+    GET_STATE(self);
+    return state->quirks_mode ? Qtrue : Qfalse;
+}
+
+/*
+ * call-seq: quirks_mode=(enable)
+ *
+ * If set to true, enables the quirks_mode mode.
+ */
+static VALUE cState_quirks_mode_set(VALUE self, VALUE enable)
+{
+    GET_STATE(self);
+    state->quirks_mode = RTEST(enable);
+    return Qnil;
+}
+
+/*
  * call-seq: depth
  *
  * This integer returns the current depth of data structure nesting.
@@ -1345,6 +1384,9 @@
     rb_define_method(cState, "check_circular?", cState_check_circular_p, 0);
     rb_define_method(cState, "allow_nan?", cState_allow_nan_p, 0);
     rb_define_method(cState, "ascii_only?", cState_ascii_only_p, 0);
+    rb_define_method(cState, "quirks_mode?", cState_quirks_mode_p, 0);
+    rb_define_method(cState, "quirks_mode", cState_quirks_mode_p, 0);
+    rb_define_method(cState, "quirks_mode=", cState_quirks_mode_set, 1);
     rb_define_method(cState, "depth", cState_depth, 0);
     rb_define_method(cState, "depth=", cState_depth_set, 1);
     rb_define_method(cState, "configure", cState_configure, 1);
@@ -1392,6 +1434,7 @@
     i_max_nesting = rb_intern("max_nesting");
     i_allow_nan = rb_intern("allow_nan");
     i_ascii_only = rb_intern("ascii_only");
+    i_quirks_mode = rb_intern("quirks_mode");
     i_depth = rb_intern("depth");
     i_pack = rb_intern("pack");
     i_unpack = rb_intern("unpack");
Index: ext/json/generator/generator.h
===================================================================
--- ext/json/generator/generator.h	(revision 33121)
+++ ext/json/generator/generator.h	(revision 33122)
@@ -45,7 +45,10 @@
 #define RSTRING_LEN(string) RSTRING(string)->len
 #endif
 
-#define RSTRING_PAIR(string) RSTRING_PTR(string), RSTRING_LEN(string)
+/* We don't need to guard objects for rbx, so let's do nothing at all. */
+#ifndef RB_GC_GUARD
+#define RB_GC_GUARD(object)
+#endif
 
 /* fbuffer implementation */
 
@@ -123,6 +126,7 @@
     long max_nesting;
     char allow_nan;
     char ascii_only;
+    char quirks_mode;
     long depth;
 } JSON_Generator_State;
 
Index: ext/json/lib/json/ext.rb
===================================================================
--- ext/json/lib/json/ext.rb	(revision 33121)
+++ ext/json/lib/json/ext.rb	(revision 33122)
@@ -4,21 +4,8 @@
   # This module holds all the modules/classes that implement JSON's
   # functionality as C extensions.
   module Ext
-    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
+    require 'json/ext/parser'
+    require 'json/ext/generator'
     $DEBUG and warn "Using Ext extension for JSON."
     JSON.parser = Parser
     JSON.generator = Generator
Index: ext/json/lib/json/add/core.rb
===================================================================
--- ext/json/lib/json/add/core.rb	(revision 33121)
+++ ext/json/lib/json/add/core.rb	(revision 33122)
@@ -5,6 +5,8 @@
   require 'json'
 end
 require 'date'
+require 'complex'
+require 'rational'
 
 # Symbol serialization/deserialization
 class Symbol
@@ -230,8 +232,8 @@
   def as_json(*)
     {
       JSON.create_id => self.class.name,
-      'o' => options,
-      's' => source,
+      'o'            => options,
+      's'            => source,
     }
   end
 
@@ -241,3 +243,39 @@
     as_json.to_json
   end
 end
+
+class Rational
+  def self.json_create(object)
+    Rational(object['n'], object['d'])
+  end
+
+  def as_json(*)
+    {
+      JSON.create_id => self.class.name,
+      'n'            => numerator,
+      'd'            => denominator,
+    }
+  end
+
+  def to_json(*)
+    as_json.to_json
+  end
+end
+
+class Complex
+  def self.json_create(object)
+    Complex(object['r'], object['i'])
+  end
+
+  def as_json(*)
+    {
+      JSON.create_id => self.class.name,
+      'r'            => real,
+      'i'            => imag,
+    }
+  end
+
+  def to_json(*)
+    as_json.to_json
+  end
+end
Index: ext/json/lib/json/common.rb
===================================================================
--- ext/json/lib/json/common.rb	(revision 33121)
+++ ext/json/lib/json/common.rb	(revision 33122)
@@ -2,11 +2,11 @@
 
 module JSON
   class << self
-    # If _object_ is string-like parse the string and return the parsed result
+    # If _object_ is string-like, parse the string and return the parsed result
     # as a Ruby data structure. Otherwise generate a JSON text from the Ruby
     # data structure object and return it.
     #
-    # The _opts_ argument is passed through to generate/parse respectively, see
+    # The _opts_ argument is passed through to generate/parse respectively. See
     # generate and parse for their documentation.
     def [](object, opts = {})
       if object.respond_to? :to_str
@@ -16,7 +16,7 @@
       end
     end
 
-    # Returns the JSON parser class, that is used by JSON. This might be either
+    # Returns the JSON parser class that is used by JSON. This is either
     # JSON::Ext::Parser or JSON::Pure::Parser.
     attr_reader :parser
 
@@ -28,7 +28,7 @@
     end
 
     # Return the constant located at _path_. The format of _path_ has to be
-    # either ::A::B::C or A::B::C. In any case A has to be located at the top
+    # either ::A::B::C or A::B::C. In any case, A has to be located at the top
     # level (absolute namespace path?). If there doesn't exist a constant at
     # the given path, an ArgumentError is raised.
     def deep_const_get(path) # :nodoc:
@@ -81,15 +81,15 @@
       $VERBOSE = old
     end
 
-    # Returns the JSON generator modul, that is used by JSON. This might be
+    # Returns the JSON generator module that is used by JSON. This is
     # either JSON::Ext::Generator or JSON::Pure::Generator.
     attr_reader :generator
 
-    # Returns the JSON generator state class, that is used by JSON. This might
-    # be either JSON::Ext::Generator::State or JSON::Pure::Generator::State.
+    # Returns the JSON generator state class that is used by JSON. This is
+    # either JSON::Ext::Generator::State or JSON::Pure::Generator::State.
     attr_accessor :state
 
-    # This is create identifier, that is used to decide, if the _json_create_
+    # This is create identifier, which is used to decide if the _json_create_
     # hook of a class should be called. It defaults to 'json_class'.
     attr_accessor :create_id
   end
@@ -104,10 +104,10 @@
   # The base exception for JSON errors.
   class JSONError < StandardError; end
 
-  # This exception is raised, if a parser error occurs.
+  # This exception is raised if a parser error occurs.
   class ParserError < JSONError; end
 
-  # This exception is raised, if the nesting of parsed datastructures is too
+  # This exception is raised if the nesting of parsed data structures is too
   # deep.
   class NestingError < ParserError; end
 
@@ -115,13 +115,13 @@
   class CircularDatastructure < NestingError; end
   # :startdoc:
 
-  # This exception is raised, if a generator or unparser error occurs.
+  # This exception is raised if a generator or unparser error occurs.
   class GeneratorError < JSONError; end
   # For backwards compatibility
   UnparserError = GeneratorError
 
-  # This exception is raised, if the required unicode support is missing on the
-  # system. Usually this means, that the iconv library is not installed.
+  # This exception is raised if the required unicode support is missing on the
+  # system. Usually this means that the iconv library is not installed.
   class MissingUnicodeSupport < JSONError; end
 
   module_function
@@ -131,16 +131,16 @@
   # _opts_ can have the following
   # keys:
   # * *max_nesting*: The maximum depth of nesting allowed in the parsed data
-  #   structures. Disable depth checking with :max_nesting => false, it defaults
+  #   structures. Disable depth checking with :max_nesting => false. It defaults
   #   to 19.
   # * *allow_nan*: If set to true, allow NaN, Infinity and -Infinity in
   #   defiance of RFC 4627 to be parsed by the Parser. This option defaults
   #   to false.
   # * *symbolize_names*: If set to true, returns symbols for the names
-  #   (keys) in a JSON object. Otherwise strings are returned, which is also
+  #   (keys) in a JSON object. Otherwise strings are returned. Strings are
   #   the default.
   # * *create_additions*: If set to false, the Parser doesn't create
-  #   additions even if a matchin class and create_id was found. This option
+  #   additions even if a matching class and create_id was found. This option
   #   defaults to true.
   # * *object_class*: Defaults to Hash
   # * *array_class*: Defaults to Array
@@ -149,19 +149,19 @@
   end
 
   # Parse the JSON document _source_ into a Ruby data structure and return it.
-  # The bang version of the parse method, defaults to the more dangerous values
+  # The bang version of the parse method defaults to the more dangerous values
   # for the _opts_ hash, so be sure only to parse trusted _source_ documents.
   #
   # _opts_ can have the following keys:
   # * *max_nesting*: The maximum depth of nesting allowed in the parsed data
   #   structures. Enable depth checking with :max_nesting => anInteger. The parse!
-  #   methods defaults to not doing max depth checking: This can be dangerous,
+  #   methods defaults to not doing max depth checking: This can be dangerous
   #   if someone wants to fill up your stack.
   # * *allow_nan*: If set to true, allow NaN, Infinity, and -Infinity in
   #   defiance of RFC 4627 to be parsed by the Parser. This option defaults
   #   to true.
   # * *create_additions*: If set to false, the Parser doesn't create
-  #   additions even if a matchin class and create_id was found. This option
+  #   additions even if a matching class and create_id was found. This option
   #   defaults to true.
   def parse!(source, opts = {})
     opts = {
@@ -188,7 +188,7 @@
   # * *object_nl*: a string that is put at the end of a JSON object (default: ''),
   # * *array_nl*: a string that is put at the end of a JSON array (default: ''),
   # * *allow_nan*: true if NaN, Infinity, and -Infinity should be
-  #   generated, otherwise an exception is thrown, if these values are
+  #   generated, otherwise an exception is thrown if these values are
   #   encountered. This options defaults to false.
   # * *max_nesting*: The maximum depth of nesting allowed in the data
   #   structures from which JSON is to be generated. Disable depth checking
@@ -196,9 +196,13 @@
   #
   # See also the fast_generate for the fastest creation method with the least
   # amount of sanity checks, and the pretty_generate method for some
-  # defaults for a pretty output.
+  # defaults for pretty output.
   def generate(obj, opts = nil)
-    state = SAFE_STATE_PROTOTYPE.dup
+    if State === opts
+      state, opts = opts, nil
+    else
+      state = SAFE_STATE_PROTOTYPE.dup
+    end
     if opts
       if opts.respond_to? :to_hash
         opts = opts.to_hash
@@ -223,9 +227,13 @@
   # This method disables the checks for circles in Ruby objects.
   #
   # *WARNING*: Be careful not to pass any Ruby data structures with circles as
-  # _obj_ argument, because this will cause JSON to go into an infinite loop.
+  # _obj_ argument because this will cause JSON to go into an infinite loop.
   def fast_generate(obj, opts = nil)
-    state = FAST_STATE_PROTOTYPE.dup
+    if State === opts
+      state, opts = opts, nil
+    else
+      state = FAST_STATE_PROTOTYPE.dup
+    end
     if opts
       if opts.respond_to? :to_hash
         opts = opts.to_hash
@@ -249,10 +257,14 @@
   # The returned document is a prettier form of the document returned by
   # #unparse.
   #
-  # The _opts_ argument can be used to configure the generator, see the
+  # The _opts_ argument can be used to configure the generator. See the
   # generate method for a more detailed explanation.
   def pretty_generate(obj, opts = nil)
-    state = PRETTY_STATE_PROTOTYPE.dup
+    if State === opts
+      state, opts = opts, nil
+    else
+      state = PRETTY_STATE_PROTOTYPE.dup
+    end
     if opts
       if opts.respond_to? :to_hash
         opts = opts.to_hash
@@ -273,7 +285,7 @@
   # :startdoc:
 
   # 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
+  # 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.
   #
@@ -312,10 +324,10 @@
   # Dumps _obj_ as a JSON string, i.e. calls generate on the object and returns
   # the result.
   #
-  # If anIO (an IO like object or an object that responds to the write method)
+  # If anIO (an IO-like object or an object that responds to the write method)
   # was given, the resulting JSON is written to it.
   #
-  # If the number of nested arrays or objects exceeds _limit_ an ArgumentError
+  # If the number of nested arrays or objects exceeds _limit_, an ArgumentError
   # exception is raised. This argument is similar (but not exactly the
   # same!) to the _limit_ argument in Marshal.dump.
   #
@@ -396,11 +408,11 @@
     nil
   end
 
-  # If _object_ is string-like parse the string and return the parsed result as
-  # a Ruby data structure. Otherwise generate a JSON text from the Ruby data
+  # If _object_ is string-like, parse the string and return the parsed result as
+  # a Ruby data structure. Otherwise, generate a JSON text from the Ruby data
   # structure object and return it.
   #
-  # The _opts_ argument is passed through to generate/parse respectively, see
+  # The _opts_ argument is passed through to generate/parse respectively. See
   # generate and parse for their documentation.
   def JSON(object, *args)
     if object.respond_to? :to_str
@@ -413,10 +425,10 @@
 
 # Extends any Class to include _json_creatable?_ method.
 class ::Class
-  # Returns true, if this class can be used to create an instance
+  # Returns true if this class can be used to create an instance
   # from a serialised JSON string. The class has to implement a class
-  # method _json_create_ that expects a hash as first parameter, which includes
-  # the required data.
+  # method _json_create_ that expects a hash as first parameter. The hash
+  # should include the required data.
   def json_creatable?
     respond_to?(:json_create)
   end
Index: ext/json/lib/json.rb
===================================================================
--- ext/json/lib/json.rb	(revision 33121)
+++ ext/json/lib/json.rb	(revision 33122)
@@ -7,13 +7,13 @@
 #
 # 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.
+#   2. An ordered list of values. More commonly called 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
+# To parse a JSON string received by another application or gene (... truncated)

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]