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

ruby-changes:11704

From: naruse <ko1@a...>
Date: Tue, 5 May 2009 11:33:10 +0900 (JST)
Subject: [ruby-changes:11704] Ruby:r23346 (trunk): Update to JSON 1.1.4.

naruse	2009-05-05 11:32:49 +0900 (Tue, 05 May 2009)

  New Revision: 23346

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

  Log:
    Update to JSON 1.1.4.

  Removed files:
    trunk/ext/json/lib/json/pure/generator.rb
    trunk/ext/json/lib/json/pure/parser.rb
    trunk/ext/json/lib/json/pure.rb
  Modified files:
    trunk/ChangeLog
    trunk/ext/json/ext/generator/generator.c
    trunk/ext/json/ext/parser/parser.c
    trunk/ext/json/ext/parser/parser.rl
    trunk/ext/json/lib/json/add/core.rb
    trunk/ext/json/lib/json/common.rb
    trunk/ext/json/lib/json/editor.rb
    trunk/ext/json/lib/json/ext.rb
    trunk/ext/json/lib/json/version.rb
    trunk/ext/json/lib/json.rb

Index: ChangeLog
===================================================================
--- ChangeLog	(revision 23345)
+++ ChangeLog	(revision 23346)
@@ -1,3 +1,7 @@
+Tue May  5 10:42:28 2009  NARUSE, Yui  <naruse@r...>
+
+	* ext/json: Update to JSON 1.1.4.
+
 Tue May  5 07:22:37 2009  NARUSE, Yui  <naruse@r...>
 
 	* transcode.c: NOMAP is now multibyte direct map.
Index: ext/json/ext/generator/generator.c
===================================================================
--- ext/json/ext/generator/generator.c	(revision 23345)
+++ ext/json/ext/generator/generator.c	(revision 23346)
@@ -1,8 +1,33 @@
 #include <string.h>
 #include "ruby.h"
+#if HAVE_RUBY_ST_H
+#include "ruby/st.h"
+#endif
+#if HAVE_ST_H
+#include "st.h"
+#endif
 #include "unicode.h"
 #include <math.h>
 
+#ifndef RHASH_TBL
+#define RHASH_TBL(hsh) (RHASH(hsh)->tbl)
+#endif
+
+#ifndef RHASH_SIZE
+#define RHASH_SIZE(hsh) (RHASH(hsh)->tbl->num_entries)
+#endif
+
+#ifndef RFLOAT_VALUE
+#define RFLOAT_VALUE(val) (RFLOAT(val)->value)
+#endif
+
+#ifdef HAVE_RUBY_ENCODING_H
+#include "ruby/encoding.h"
+#define FORCE_UTF8(obj) rb_enc_associate((obj), rb_utf8_encoding())
+#else
+#define FORCE_UTF8(obj)
+#endif
+
 #define check_max_nesting(state, depth) do {                                   \
     long current_nesting = 1 + depth;                                          \
     if (state->max_nesting != 0 && current_nesting > state->max_nesting)       \
@@ -163,6 +188,7 @@
         }
     }
     OBJ_INFECT(result, self);
+    FORCE_UTF8(result);
     return result;
 }
 
@@ -260,6 +286,7 @@
         result = mArray_json_transfrom(self, Vstate, Vdepth);
     }
     OBJ_INFECT(result, self);
+    FORCE_UTF8(result);
     return result;
 }
 
@@ -270,7 +297,9 @@
  */
 static VALUE mInteger_to_json(int argc, VALUE *argv, VALUE self)
 {
-    return rb_funcall(self, i_to_s, 0);
+    VALUE result = rb_funcall(self, i_to_s, 0);
+    FORCE_UTF8(result);
+    return result;
 }
 
 /*
@@ -281,27 +310,29 @@
 static VALUE mFloat_to_json(int argc, VALUE *argv, VALUE self)
 {
     JSON_Generator_State *state = NULL;
-    VALUE Vstate, rest, tmp;
+    VALUE Vstate, rest, tmp, result;
     double value = RFLOAT_VALUE(self);
     rb_scan_args(argc, argv, "01*", &Vstate, &rest);
     if (!NIL_P(Vstate)) Data_Get_Struct(Vstate, JSON_Generator_State, state);
     if (isinf(value)) {
         if (!state || state->allow_nan) {
-            return rb_funcall(self, i_to_s, 0);
+            result = rb_funcall(self, i_to_s, 0);
         } else {
             tmp = rb_funcall(self, i_to_s, 0);
             rb_raise(eGeneratorError, "%u: %s not allowed in JSON", __LINE__, StringValueCStr(tmp));
         }
     } else if (isnan(value)) {
         if (!state || state->allow_nan) {
-            return rb_funcall(self, i_to_s, 0);
+            result = rb_funcall(self, i_to_s, 0);
         } else {
             tmp = rb_funcall(self, i_to_s, 0);
             rb_raise(eGeneratorError, "%u: %s not allowed in JSON", __LINE__, StringValueCStr(tmp));
         }
     } else {
-        return rb_funcall(self, i_to_s, 0);
+        result = rb_funcall(self, i_to_s, 0);
     }
+    FORCE_UTF8(result);
+    return result;
 }
 
 /*
@@ -310,7 +341,9 @@
  * Extends _modul_ with the String::Extend module.
  */
 static VALUE mString_included_s(VALUE self, VALUE modul) {
-    return rb_funcall(modul, i_extend, 1, mString_Extend);
+    VALUE result = rb_funcall(modul, i_extend, 1, mString_Extend);
+    FORCE_UTF8(result);
+    return result;
 }
 
 /*
@@ -326,6 +359,7 @@
     rb_str_buf_cat2(result, "\"");
     JSON_convert_UTF8_to_JSON(result, self, strictConversion);
     rb_str_buf_cat2(result, "\"");
+    FORCE_UTF8(result);
     return result;
 }
 
@@ -343,6 +377,7 @@
     rb_hash_aset(result, rb_funcall(mJSON, i_create_id, 0), rb_class_name(rb_obj_class(self)));
     ary = rb_funcall(self, i_unpack, 1, rb_str_new2("C*"));
     rb_hash_aset(result, rb_str_new2("raw"), ary);
+    FORCE_UTF8(result);
     return result;
 }
 
@@ -353,9 +388,11 @@
  * to_json_raw_object of this String.
  */
 static VALUE mString_to_json_raw(int argc, VALUE *argv, VALUE self) {
-    VALUE obj = mString_to_json_raw_object(self);
+    VALUE result, obj = mString_to_json_raw_object(self);
     Check_Type(obj, T_HASH);
-    return mHash_to_json(argc, argv, obj);
+    result = mHash_to_json(argc, argv, obj);
+    FORCE_UTF8(result);
+    return result;
 }
 
 /*
@@ -378,7 +415,9 @@
  */
 static VALUE mTrueClass_to_json(int argc, VALUE *argv, VALUE self)
 {
-    return rb_str_new2("true");
+    VALUE result = rb_str_new2("true");
+    FORCE_UTF8(result);
+    return result;
 }
 
 /*
@@ -388,7 +427,9 @@
  */
 static VALUE mFalseClass_to_json(int argc, VALUE *argv, VALUE self)
 {
-    return rb_str_new2("false");
+    VALUE result = rb_str_new2("false");
+    FORCE_UTF8(result);
+    return result;
 }
 
 /*
@@ -397,7 +438,9 @@
  */
 static VALUE mNilClass_to_json(int argc, VALUE *argv, VALUE self)
 {
-    return rb_str_new2("null");
+    VALUE result = rb_str_new2("null");
+    FORCE_UTF8(result);
+    return result;
 }
 
 /*
@@ -409,9 +452,11 @@
  */
 static VALUE mObject_to_json(int argc, VALUE *argv, VALUE self)
 {
-    VALUE string = rb_funcall(self, i_to_s, 0);
+    VALUE result, string = rb_funcall(self, i_to_s, 0);
     Check_Type(string, T_STRING);
-    return mString_to_json(argc, argv, string);
+    result = mString_to_json(argc, argv, string);
+    FORCE_UTF8(result);
+    return result;
 }
 
 /* 
Index: ext/json/ext/parser/parser.rl
===================================================================
--- ext/json/ext/parser/parser.rl	(revision 23345)
+++ ext/json/ext/parser/parser.rl	(revision 23346)
@@ -1,8 +1,28 @@
 #include "ruby.h"
 #include "unicode.h"
+#if HAVE_RE_H
+#include "re.h"
+#endif
+#if HAVE_RUBY_ST_H
+#include "ruby/st.h"
+#endif
+#if HAVE_ST_H
+#include "st.h"
+#endif
 
 #define EVIL 0x666
 
+#ifndef RHASH_TBL
+#define RHASH_TBL(hsh) (RHASH(hsh)->tbl)
+#endif
+
+#ifdef HAVE_RUBY_ENCODING_H
+#include "ruby/encoding.h"
+#define FORCE_UTF8(obj) rb_enc_associate((obj), rb_utf8_encoding())
+#else
+#define FORCE_UTF8(obj)
+#endif
+
 static VALUE mJSON, mExt, cParser, eParserError, eNestingError;
 static VALUE CNaN, CInfinity, CMinusInfinity;
 
@@ -390,8 +410,14 @@
 
     action parse_string {
         *result = json_string_unescape(json->memo + 1, p);
-        if (NIL_P(*result)) { fhold; fbreak; } else fexec p + 1;
-    }
+        if (NIL_P(*result)) {
+			fhold;
+			fbreak;
+		} else {
+			FORCE_UTF8(*result);
+			fexec p + 1;
+		}
+	}
 
     action exit { fhold; fbreak; }
 
Index: ext/json/ext/parser/parser.c
===================================================================
--- ext/json/ext/parser/parser.c	(revision 23345)
+++ ext/json/ext/parser/parser.c	(revision 23346)
@@ -1,10 +1,30 @@
+
 #line 1 "parser.rl"
 #include "ruby.h"
-#include "ruby/encoding.h"
 #include "unicode.h"
+#if HAVE_RE_H
+#include "re.h"
+#endif
+#if HAVE_RUBY_ST_H
+#include "ruby/st.h"
+#endif
+#if HAVE_ST_H
+#include "st.h"
+#endif
 
 #define EVIL 0x666
 
+#ifndef RHASH_TBL
+#define RHASH_TBL(hsh) (RHASH(hsh)->tbl)
+#endif
+
+#ifdef HAVE_RUBY_ENCODING_H
+#include "ruby/encoding.h"
+#define FORCE_UTF8(obj) rb_enc_associate((obj), rb_utf8_encoding())
+#else
+#define FORCE_UTF8(obj)
+#endif
+
 static VALUE mJSON, mExt, cParser, eParserError, eNestingError;
 static VALUE CNaN, CInfinity, CMinusInfinity;
 
@@ -35,20 +55,22 @@
     JSON_Parser *json;                      \
     Data_Get_Struct(self, JSON_Parser, json);
 
-#line 64 "parser.rl"
 
+#line 82 "parser.rl"
 
 
-#line 44 "parser.c"
+
+#line 64 "parser.c"
 static const int JSON_object_start = 1;
 static const int JSON_object_first_final = 27;
 static const int JSON_object_error = 0;
 
 static const int JSON_object_en_main = 1;
 
-#line 97 "parser.rl"
 
+#line 115 "parser.rl"
 
+
 static char *JSON_parse_object(JSON_Parser *json, char *p, char *pe, VALUE *result)
 {
     int cs = EVIL;
@@ -61,13 +83,14 @@
     *result = rb_hash_new();
 
     
-#line 66 "parser.c"
+#line 87 "parser.c"
 	{
 	cs = JSON_object_start;
 	}
-#line 111 "parser.rl"
+
+#line 129 "parser.rl"
     
-#line 72 "parser.c"
+#line 94 "parser.c"
 	{
 	if ( p == pe )
 		goto _test_eof;
@@ -95,7 +118,7 @@
 		goto st2;
 	goto st0;
 tr2:
-#line 83 "parser.rl"
+#line 101 "parser.rl"
 	{
         char *np = JSON_parse_string(json, p, pe, &last_name);
         if (np == NULL) { p--; {p++; cs = 3; goto _out;} } else {p = (( np))-1;}
@@ -105,7 +128,7 @@
 	if ( ++p == pe )
 		goto _test_eof3;
 case 3:
-#line 110 "parser.c"
+#line 132 "parser.c"
 	switch( (*p) ) {
 		case 13: goto st3;
 		case 32: goto st3;
@@ -172,7 +195,7 @@
 		goto st8;
 	goto st0;
 tr11:
-#line 72 "parser.rl"
+#line 90 "parser.rl"
 	{
         VALUE v = Qnil;
         char *np = JSON_parse_value(json, p, pe, &v); 
@@ -188,7 +211,7 @@
 	if ( ++p == pe )
 		goto _test_eof9;
 case 9:
-#line 193 "parser.c"
+#line 215 "parser.c"
 	switch( (*p) ) {
 		case 13: goto st9;
 		case 32: goto st9;
@@ -277,14 +300,14 @@
 		goto st9;
 	goto st18;
 tr4:
-#line 88 "parser.rl"
+#line 106 "parser.rl"
 	{ p--; {p++; cs = 27; goto _out;} }
 	goto st27;
 st27:
 	if ( ++p == pe )
 		goto _test_eof27;
 case 27:
-#line 289 "parser.c"
+#line 311 "parser.c"
 	goto st0;
 st19:
 	if ( ++p == pe )
@@ -381,8 +404,9 @@
 	_test_eof: {}
 	_out: {}
 	}
-#line 112 "parser.rl"
 
+#line 130 "parser.rl"
+
     if (cs >= JSON_object_first_final) {
         if (RTEST(json->create_id)) {
             VALUE klassname = rb_hash_aref(*result, json->create_id);
@@ -400,28 +424,30 @@
 }
 
 
-#line 405 "parser.c"
+#line 428 "parser.c"
 static const int JSON_value_start = 1;
 static const int JSON_value_first_final = 21;
 static const int JSON_value_error = 0;
 
 static const int JSON_value_en_main = 1;
 
-#line 210 "parser.rl"
 
+#line 228 "parser.rl"
 
+
 static char *JSON_parse_value(JSON_Parser *json, char *p, char *pe, VALUE *result)
 {
     int cs = EVIL;
 
     
-#line 420 "parser.c"
+#line 444 "parser.c"
 	{
 	cs = JSON_value_start;
 	}
-#line 217 "parser.rl"
+
+#line 235 "parser.rl"
     
-#line 426 "parser.c"
+#line 451 "parser.c"
 	{
 	if ( p == pe )
 		goto _test_eof;
@@ -446,14 +472,14 @@
 cs = 0;
 	goto _out;
 tr0:
-#line 158 "parser.rl"
+#line 176 "parser.rl"
 	{
         char *np = JSON_parse_string(json, p, pe, result);
         if (np == NULL) { p--; {p++; cs = 21; goto _out;} } else {p = (( np))-1;}
     }
 	goto st21;
 tr2:
-#line 163 "parser.rl"
+#line 181 "parser.rl"
 	{
         char *np;
         if(pe > p + 9 && !strncmp(MinusInfinity, p, 9)) {
@@ -473,7 +499,7 @@
     }
 	goto st21;
 tr5:
-#line 181 "parser.rl"
+#line 199 "parser.rl"
 	{ 
         char *np;
         json->current_nesting++;
@@ -483,7 +509,7 @@
     }
 	goto st21;
 tr9:
-#line 189 "parser.rl"
+#line 207 "parser.rl"
 	{ 
         char *np;
         json->current_nesting++;
@@ -493,7 +519,7 @@
     }
 	goto st21;
 tr16:
-#line 151 "parser.rl"
+#line 169 "parser.rl"
 	{
         if (json->allow_nan) {
             *result = CInfinity;
@@ -503,7 +529,7 @@
     }
 	goto st21;
 tr18:
-#line 144 "parser.rl"
+#line 162 "parser.rl"
 	{
         if (json->allow_nan) {
             *result = CNaN;
@@ -513,19 +539,19 @@
     }
 	goto st21;
 tr22:
-#line 138 "parser.rl"
+#line 156 "parser.rl"
 	{
         *result = Qfalse;
     }
 	goto st21;
 tr25:
-#line 135 "parser.rl"
+#line 153 "parser.rl"
 	{
         *result = Qnil;
     }
 	goto st21;
 tr28:
-#line 141 "parser.rl"
+#line 159 "parser.rl"
 	{
         *result = Qtrue;
     }
@@ -534,9 +560,9 @@
 	if ( ++p == pe )
 		goto _test_eof21;
 case 21:
-#line 197 "parser.rl"
+#line 215 "parser.rl"
 	{ p--; {p++; cs = 21; goto _out;} }
-#line 541 "parser.c"
+#line 566 "parser.c"
 	goto st0;
 st2:
 	if ( ++p == pe )
@@ -696,8 +722,9 @@
 	_test_eof: {}
 	_out: {}
 	}
-#line 218 "parser.rl"
 
+#line 236 "parser.rl"
+
     if (cs >= JSON_value_first_final) {
         return p;
     } else {
@@ -706,29 +733,31 @@
 }
 
 
-#line 711 "parser.c"
+#line 737 "parser.c"
 static const int JSON_integer_start = 1;
 static const int JSON_integer_first_final = 5;
 static const int JSON_integer_error = 0;
 
 static const int JSON_integer_en_main = 1;
 
-#line 234 "parser.rl"
 
+#line 252 "parser.rl"
 
+
 static char *JSON_parse_integer(JSON_Parser *json, char *p, char *pe, VALUE *result)
 {
     int cs = EVIL;
 
     
-#line 726 "parser.c"
+#line 753 "parser.c"
 	{
 	cs = JSON_integer_start;
 	}
-#line 241 "parser.rl"
+
+#line 259 "parser.rl"
     json->memo = p;
     
-#line 733 "parser.c"
+#line 761 "parser.c"
 	{
 	if ( p == pe )
 		goto _test_eof;
@@ -762,14 +791,14 @@
 		goto st0;
 	goto tr4;
 tr4:
-#line 231 "parser.rl"
+#line 249 "parser.rl"
 	{ p--; {p++; cs = 5; goto _out;} }
 	goto st5;
 st5:
 	if ( ++p == pe )
 		goto _test_eof5;
 case 5:
-#line 774 "parser.c"
+#line 802 "parser.c"
 	goto st0;
 st4:
 	if ( ++p == pe )
@@ -787,8 +816,9 @@
 	_test_eof: {}
 	_out: {}
 	}
-#line 243 "parser.rl"
 
+#line 261 "parser.rl"
+
     if (cs >= JSON_integer_first_final) {
         long len = p - json->memo;
         *result = rb_Integer(rb_str_new(json->memo, len));
@@ -799,29 +829,31 @@
 }
 
 
-#line 804 "parser.c"
+#line 833 "parser.c"
 static const int JSON_float_start = 1;
 static const int JSON_float_first_final = 10;
 static const int JSON_float_error = 0;
 
 static const int JSON_float_en_main = 1;
 
-#line 265 "parser.rl"
 
+#line 283 "parser.rl"
 
+
 static char *JSON_parse_float(JSON_Parser *json, char *p, char *pe, VALUE *result)
 {
     int cs = EVIL;
 
     
-#line 819 "parser.c"
+#line 849 "parser.c"
 	{
 	cs = JSON_float_start;
 	}
-#line 272 "parser.rl"
+
+#line 290 "parser.rl"
     json->memo = p;
     
-#line 826 "parser.c"
+#line 857 "parser.c"
 	{
 	if ( p == pe )
 		goto _test_eof;
@@ -879,14 +911,14 @@
 		goto st0;
 	goto tr7;
 tr7:
-#line 259 "parser.rl"
+#line 277 "parser.rl"
 	{ p--; {p++; cs = 10; goto _out;} }
 	goto st10;
 st10:
 	if ( ++p == pe )
 		goto _test_eof10;
 case 10:
-#line 891 "parser.c"
+#line 922 "parser.c"
 	goto st0;
 st6:
 	if ( ++p == pe )
@@ -946,8 +978,9 @@
 	_test_eof: {}
 	_out: {}
 	}
-#line 274 "parser.rl"
 
+#line 292 "parser.rl"
+
     if (cs >= JSON_float_first_final) {
         long len = p - json->memo;
         *result = rb_Float(rb_str_new(json->memo, len));
@@ -959,16 +992,17 @@
 
 
 
-#line 964 "parser.c"
+#line 996 "parser.c"
 static const int JSON_array_start = 1;
 static const int JSON_array_first_final = 17;
 static const int JSON_array_error = 0;
 
 static const int JSON_array_en_main = 1;
 
-#line 310 "parser.rl"
 
+#line 328 "parser.rl"
 
+
 static char *JSON_parse_array(JSON_Parser *json, char *p, char *pe, VALUE *result)
 {
     int cs = EVIL;
@@ -979,13 +1013,14 @@
     *result = rb_ary_new();
 
     
-#line 984 "parser.c"
+#line 1017 "parser.c"
 	{
 	cs = JSON_array_start;
 	}
-#line 322 "parser.rl"
+
+#line 340 "parser.rl"
     
-#line 990 "parser.c"
+#line 1024 "parser.c"
 	{
 	if ( p == pe )
 		goto _test_eof;
@@ -1024,7 +1059,7 @@
 		goto st2;
 	goto st0;
 tr2:
-#line 291 "parser.rl"
+#line 309 "parser.rl"
 	{
         VALUE v = Qnil;
         char *np = JSON_parse_value(json, p, pe, &v); 
@@ -1040,7 +1075,7 @@
 	if ( ++p == pe )
 		goto _test_eof3;
 case 3:
-#line 1045 "parser.c"
+#line 1079 "parser.c"
 	switch( (*p) ) {
 		case 13: goto st3;
 		case 32: goto st3;
@@ -1140,14 +1175,14 @@
 		goto st3;
 	goto st12;
 tr4:
-#line 302 "parser.rl"
+#line 320 "parser.rl"
 	{ p--; {p++; cs = 17; goto _out;} }
 	goto st17;
 st17:
 	if ( ++p == pe )
 		goto _test_eof17;
 case 17:
-#line 1152 "parser.c"
+#line 1186 "parser.c"
 	goto st0;
 st13:
 	if ( ++p == pe )
@@ -1202,8 +1237,9 @@
 	_test_eof: {}
 	_out: {}
 	}
-#line 323 "parser.rl"
 
+#line 341 "parser.rl"
+
     if(cs >= JSON_array_first_final) {
         return p + 1;
     } else {
@@ -1268,30 +1304,32 @@
 }
 
 
-#line 1273 "parser.c"
+#line 1308 "parser.c"
 static const int JSON_string_start = 1;
 static const int JSON_string_first_final = 8;
 static const int JSON_string_error = 0;
 
 static const int JSON_string_en_main = 1;
 
-#line 401 "parser.rl"
 
+#line 425 "parser.rl"
 
+
 static char *JSON_parse_string(JSON_Parser *json, char *p, char *pe, VALUE *result)
 {
     int cs = EVIL;
 
     *result = rb_str_new("", 0);
     
-#line 1289 "parser.c"
+#line 1325 "parser.c"
 	{
 	cs = JSON_string_start;
 	}
-#line 409 "parser.rl"
+
+#line 433 "parser.rl"
     json->memo = p;
     
-#line 1296 "parser.c"
+#line 1333 "parser.c"
 	{
 	if ( p == pe )
 		goto _test_eof;
@@ -1316,19 +1354,25 @@
 		goto st0;
 	goto st2;
 tr2:
-#line 393 "parser.rl"
+#line 411 "parser.rl"
 	{
         *result = json_string_unescape(json->memo + 1, p);
-        if (NIL_P(*result)) { p--; {p++; cs = 8; goto _out;} } else {p = (( p + 1))-1;}
-    }
-#line 398 "parser.rl"
+        if (NIL_P(*result)) {
+			p--;
+			{p++; cs = 8; goto _out;}
+		} else {
+			FORCE_UTF8(*result);
+			{p = (( p + 1))-1;}
+		}
+	}
+#line 422 "parser.rl"
 	{ p--; {p++; cs = 8; goto _out;} }
 	goto st8;
 st8:
 	if ( ++p == pe )
 		goto _test_eof8;
 case 8:
-#line 1333 "parser.c"
+#line 1376 "parser.c"
 	goto st0;
 st3:
 	if ( ++p == pe )
@@ -1403,11 +1447,11 @@
 	_test_eof: {}
 	_out: {}
 	}
-#line 411 "parser.rl"
 
+#line 435 "parser.rl"
+
     if (cs >= JSON_string_first_final) {
-	rb_enc_associate(*result, rb_utf8_encoding());
-	return p + 1;
+        return p + 1;
     } else {
         return NULL;
     }
@@ -1415,16 +1459,17 @@
 
 
 
-#line 1419 "parser.c"
+#line 1463 "parser.c"
 static const int JSON_start = 1;
 static const int JSON_first_final = 10;
 static const int JSON_error = 0;
 
 static const int JSON_en_main = 1;
 
-#line 445 "parser.rl"
 
+#line 469 "parser.rl"
 
+
 /* 
  * Document-class: JSON::Ext::Parser
  *
@@ -1545,15 +1590,16 @@
     GET_STRUCT;
 
     
-#line 1549 "parser.c"
+#line 1594 "parser.c"
 	{
 	cs = JSON_start;
 	}
-#line 567 "parser.rl"
+
+#line 591 "parser.rl"
     p = json->source;
     pe = p + json->len;
     
-#line 1557 "parser.c"
+#line 1603 "parser.c"
 	{
 	if ( p == pe )
 		goto _test_eof;
@@ -1609,7 +1655,7 @@
 		goto st1;
 	goto st5;
 tr3:
-#line 434 "parser.rl"
+#line 458 "parser.rl"
 	{
         char *np;
         json->current_nesting = 1;
@@ -1618,7 +1664,7 @@
     }
 	goto st10;
 tr4:
-#line 427 "parser.rl"
+#line 451 "parser.rl"
 	{
         char *np;
         json->current_nesting = 1;
@@ -1630,7 +1676,7 @@
 	if ( ++p == pe )
 		goto _test_eof10;
 case 10:
-#line 1634 "parser.c"
+#line 1680 "parser.c"
 	switch( (*p) ) {
 		case 13: goto st10;
 		case 32: goto st10;
@@ -1686,8 +1732,9 @@
 	_test_eof: {}
 	_out: {}
 	}
-#line 570 "parser.rl"
 
+#line 594 "parser.rl"
+
     if (cs >= JSON_first_final && p == pe) {
         return result;
     } else {
Index: ext/json/lib/json/pure.rb
===================================================================
--- ext/json/lib/json/pure.rb	(revision 23345)
+++ ext/json/lib/json/pure.rb	(revision 23346)
@@ -1,22 +0,0 @@
-require 'json/common'
-require 'json/pure/parser'
-require 'json/pure/generator'
-
-module JSON
-  # 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
-
-  # This module holds all the modules/classes that implement JSON's
-  # functionality in pure ruby.
-  module Pure
-    $DEBUG and warn "Using pure library for JSON."
-    JSON.parser = Parser
-    JSON.generator = Generator
-  end
-end
Index: ext/json/lib/json/ext.rb
===================================================================
--- ext/json/lib/json/ext.rb	(revision 23345)
+++ ext/json/lib/json/ext.rb	(revision 23346)
@@ -10,4 +10,6 @@
     JSON.parser = Parser
     JSON.generator = Generator
   end
+
+  JSON_LOADED = true
 end
Index: ext/json/lib/json/version.rb
===================================================================
--- ext/json/lib/json/version.rb	(revision 23345)
+++ ext/json/lib/json/version.rb	(revision 23346)
@@ -1,6 +1,6 @@
 module JSON
   # JSON version
-  VERSION         = '1.1.3'
+  VERSION         = '1.1.4'
   VERSION_ARRAY   = VERSION.split(/\./).map { |x| x.to_i } # :nodoc:
   VERSION_MAJOR   = VERSION_ARRAY[0] # :nodoc:
   VERSION_MINOR   = VERSION_ARRAY[1] # :nodoc:
Index: ext/json/lib/json/add/core.rb
===================================================================
--- ext/json/lib/json/add/core.rb	(revision 23345)
+++ ext/json/lib/json/add/core.rb	(revision 23346)
@@ -96,7 +96,7 @@
 
   def to_json(*args)
     klass = self.class.name
-    klass.nil? and raise JSON::JSONError, "Only named structs are supported!"
+    klass.to_s.empty? and raise JSON::JSONError, "Only named structs are supported!"
     {
       'json_class' => klass,
       'v'     => values,
Index: ext/json/lib/json/editor.rb
===================================================================
--- ext/json/lib/json/editor.rb	(revision 23345)
+++ ext/json/lib/json/editor.rb	(revision 23346)
@@ -769,7 +769,12 @@
             iter.type, iter.content = 'FalseClass', 'false'
           end
         when 'Numeric'
-          iter.content = (Integer(value) rescue Float(value) rescue 0).to_s
+          iter.content =
+            if value == 'Infinity'
+              value
+            else
+              (Integer(value) rescue Float(value) rescue 0).to_s
+            end
         when 'String'
           iter.content = value
         when 'Hash', 'Array'
@@ -937,7 +942,11 @@
             type = types[type_input.active]
             @content = case type
             when 'Numeric'
-              Integer(value_input.text) rescue Float(value_input.text) rescue 0
+              if (t = value_input.text) == 'Infinity'
+                1 / 0.0
+              else
+                Integer(t) rescue Float(t) rescue 0
+              end
             else
               value_input.text
             end.to_s

Property changes on: ext/json/lib/json/editor.rb
___________________________________________________________________
Name: svn:executable
   + *


Property changes on: ext/json/lib/json/common.rb
___________________________________________________________________
Name: svn:executable
   + *

Index: ext/json/lib/json/pure/generator.rb
===================================================================
--- ext/json/lib/json/pure/generator.rb	(revision 23345)
+++ ext/json/lib/json/pure/generator.rb	(revision 23346)
@@ -1,394 +0,0 @@
-module JSON
-  MAP = {
-    "\x0" => '\u0000',
-    "\x1" => '\u0001',
-    "\x2" => '\u0002',
-    "\x3" => '\u0003',
-    "\x4" => '\u0004',
-    "\x5" => '\u0005',
-    "\x6" => '\u0006',
-    "\x7" => '\u0007',
-    "\b"  =>  '\b',
-    "\t"  =>  '\t',
-    "\n"  =>  '\n',
-    "\xb" => '\u000b',
-    "\f"  =>  '\f',
-    "\r"  =>  '\r',
-    "\xe" => '\u000e',
-    "\xf" => '\u000f',
-    "\x10" => '\u0010',
-    "\x11" => '\u0011',
-    "\x12" => '\u0012',
-    "\x13" => '\u0013',
-    "\x14" => '\u0014',
-    "\x15" => '\u0015',
-    "\x16" => '\u0016',
-    "\x17" => '\u0017',
-    "\x18" => '\u0018',
-    "\x19" => '\u0019',
-    "\x1a" => '\u001a',
-    "\x1b" => '\u001b',
-    "\x1c" => '\u001c',
-    "\x1d" => '\u001d',
-    "\x1e" => '\u001e',
-    "\x1f" => '\u001f',
-    '"'   =>  '\"',
-    '\\'  =>  '\\\\',
-    '/'   =>  '\/',
-  } # :nodoc:
-
-  # Convert a UTF8 encoded Ruby string _string_ to a JSON string, encoded with
-  # UTF16 big endian characters as \u????, and return it.
-  def utf8_to_json(string) # :nodoc:
-    string = string.dup.force_encoding(Encoding::ASCII_8BIT)
-    string.gsub!(/["\\\/\x0-\x1f]/) { MAP[$&] }
-    string.gsub!(/(
-                    (?:
-                      [\xc2-\xdf][\x80-\xbf]    |
-                      [\xe0-\xef][\x80-\xbf]{2} |
-                      [\xf0-\xf4][\x80-\xbf]{3}
-                    )+ |
-                    [\x80-\xc1\xf5-\xff]       # invalid
-                  )/nx) { |c|
-      c.size == 1 and raise GeneratorError, "invalid utf8 byte: '#{c}'"
-      c.unpack("U*").map{|c|
-        c>0xFFFF ? ('\ud%03x\ud%03x'%[0x7C0+c/1024,0xC00+c%1024]) : ('\u%04x'%c)
-      }.join("")
-    }
-    string
-  end
-  module_function :utf8_to_json
-
-  module Pure
-    module Generator
-      # This class is used to create State instances, that are use to hold data
-      # while generating a JSON text from a a Ruby data structure.
-      class State
-        # Creates a State object from _opts_, which ought to be Hash to create
-        # a new State instance configured by _opts_, something else to create
-        # an unconfigured instance. If _opts_ is a State object, it is just
-        # returned.
-        def self.from_state(opts)
-          case opts
-          when self
-            opts
-          when Hash
-            new(opts)
-          else
-            new
-          end
-        end
-
-        # Instantiates a new State object, configured by _opts_.
-        #
-        # _opts_ can have the following keys:
-        #
-        # * *indent*: a string used to indent levels (default: ''),
-        # * *space*: a string that is put after, a : or , delimiter (default: ''),
-        # * *space_before*: a string that is put before a : pair delimiter (default: ''),
-        # * *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: ''),
-        # * *check_circular*: true if checking for circular data structures
-        #   should be done (the default), false otherwise.
-        # * *check_circular*: true if checking for circular data structures
-        #   should be done, false (the default) otherwise.
-        # * *allow_nan*: true if NaN, Infinity, and -Infinity should be
-        #   generated, otherwise an exception is thrown, if these values are
-        #   encountered. This options defaults to false.
-        def initialize(opts = {})
-          @seen = {}
-          @indent         = ''
-          @space          = ''
-          @space_before   = ''
-          @object_nl      = ''
-          @array_nl       = ''
-          @check_circular = true
-          @allow_nan      = false
-          configure opts
-        end
-
-        # This string is used to indent levels in the JSON text.
-        attr_accessor :indent
-
-        # This string is used to insert a space between the tokens in a JSON
-        # string.
-        attr_accessor :space
-
-        # This string is used to insert a space before the ':' in JSON objects.
-        attr_accessor :space_before
-
-        # This string is put at the end of a line that holds a JSON object (or
-        # Hash).
-        attr_accessor :object_nl
-
-        # This string is put at the end of a line that holds a JSON array.
-        attr_accessor :array_nl
-
-        # This integer returns the maximum level of data structure nesting in
-        # the generated JSON, max_nesting = 0 if no maximum is checked.
-        attr_accessor :max_nesting
-
-        def check_max_nesting(depth) # :nodoc:
-          return if @max_nesting.zero?
-          current_nesting = depth + 1
-          current_nesting > @max_nesting and
-            raise NestingError, "nesting of #{current_nesting} is too deep"
-        end
-
-        # Returns true, if circular data structures should be checked,
-        # otherwise returns false.
-        def check_circular?
-          @check_circular
-        end
-
-        # Returns true if NaN, Infinity, and -Infinity should be considered as
-        # valid JSON and output.
-        def allow_nan?
-          @allow_nan
-        end
-
-        # Returns _true_, if _object_ was already seen during this generating
-        # run.
-        def seen?(object)
-          @seen.key?(object.__id__)
-        end
-
-        # Remember _object_, to find out if it was already encountered (if a
-        # cyclic data structure is if a cyclic data structure is rendered).
-        def remember(object)
-          @seen[object.__id__] = true
-        end
-
-        # Forget _object_ for this generating run.
-        def forget(object)
-          @seen.delete object.__id__
-        end
-
-        # Configure this State instance with the Hash _opts_, and return
-        # itself.
-        def configure(opts)
-          @indent         = opts[:indent] if opts.key?(:indent)
-          @space          = opts[:space] if opts.key?(:space)
-          @space_before   = opts[:space_before] if opts.key?(:space_before)
-          @object_nl      = opts[:object_nl] if opts.key?(:object_nl)
-          @array_nl       = opts[:array_nl] if opts.key?(:array_nl)
-          @check_circular = !!opts[:check_circular] if opts.key?(:check_circular)
-          @allow_nan      = !!opts[:allow_nan] if opts.key?(:allow_nan)
-          if !opts.key?(:max_nesting) # defaults to 19
-            @max_nesting = 19
-          elsif opts[:max_nesting]
-            @max_nesting = opts[:max_nesting]
-          else
-            @max_nesting = 0
-          end
-          self
-        end
-
-        # Returns the configuration instance variables as a hash, that can be
-        # passed to the configure method.
-        def to_h
-          result = {}
-          for iv in %w[indent space space_before object_nl array_nl check_circular allow_nan max_nesting]
-            result[iv.intern] = instance_variable_get("@#{iv}")
-          end
-          result
-        end
-      end
-
-      module GeneratorMethods
-        module Object
-          # Converts this object to a string (calling #to_s), converts
-          # it to a JSON string, and returns the result. This is a fallback, if no
-          # special method #to_json was defined for some object.
-          def to_json(*) to_s.to_json end
-        end
-
-        module Hash
-          # Returns a JSON string containing a JSON object, that is unparsed from
-          # this Hash instance.
-          # _state_ is a JSON::State object, that can also be used to configure the
-          # produced JSON string output further.
-          # _depth_ is used to find out nesting depth, to indent accordingly.
-          def to_json(state = nil, depth = 0, *)
-            if state
-              state = JSON.state.from_state(state)
-              state.check_max_nesting(depth)
-              json_check_circular(state) { json_transform(state, depth) }
-            else
-              json_transform(state, depth)
-            end
-          end
-
-          private
-
-          def json_check_circular(state)
-            if state and state.check_circular?
-              state.seen?(self) and raise JSON::CircularDatastructure,
-                  "circular data structures not supported!"
-              state.remember self
-            end
-            yield
-          ensure
-            state and state.forget self
-          end
-
-          def json_shift(state, depth)
-            state and not state.object_nl.empty? or return ''
-            state.indent * depth
-          end
-
-          def json_transform(state, depth)
-            delim = ','
-            delim << state.object_nl if state
-            result = '{'
-            result << state.object_nl if state
-            result << map { |key,value|
-              s = json_shift(state, depth + 1)
-              s << key.to_s.to_json(state, depth + 1)
-              s << state.space_before if state
-              s << ':'
-              s << state.space if state
-              s << value.to_json(state, depth + 1)
-            }.join(delim)
-            result << state.object_nl if state
-            result << json_shift(state, depth)
-            result << '}'
-            result
-          end
-        end
-
-        module Array
-          # Returns a JSON string containing a JSON array, that is unparsed from
-          # this Array instance.
-          # _state_ is a JSON::State object, that can also be used to configure the
-          # produced JSON string output further.
-          # _depth_ is used to find out nesting depth, to indent accordingly.
-          def to_json(state = nil, depth = 0, *)
-            if state
-              state = JSON.state.from_state(state)
-              state.check_max_nesting(depth)
-              json_check_circular(state) { json_transform(state, depth) }
-            else
-              json_transform(state, depth)
-            end
-          end
-
-          private
-
-          def json_check_circular(state)
-            if state and state.check_circular?
-              state.seen?(self) and raise JSON::CircularDatastructure,
-                "circular data structures not supported!"
-              state.remember self
-            end
-            yield
-          ensure
-            state and state.forget self
-          end
-
-          def json_shift(state, depth)
-            state and not state.array_nl.empty? or return ''
-            state.indent * depth
-          end
-
-          def json_transform(state, depth)
-            delim = ','
-            delim << state.array_nl if state
-            result = '['
-            result << state.array_nl if state
-            result << map { |value|
-              json_shift(state, depth + 1) << value.to_json(state, depth + 1)
-            }.join(delim)
-            result << state.array_nl if state
-            result << json_shift(state, depth)
-            result << ']'
-            result
-          end
-        end
-
-        module Integer
-          # Returns a JSON string representation for this Integer number.
-          def to_json(*) to_s end
-        end
-
-        module Float
-          # Returns a JSON string representation for this Float number.
-          def to_json(state = nil, *)
-            case
-            when infinite?
-              if !state || state.allow_nan?
-                to_s
-              else
-                raise GeneratorError, "#{self} not allowed in JSON"
-              end
-            when nan?
-              if !state || state.allow_nan?
-                to_s
-              else
-                raise GeneratorError, "#{self} not allowed in JSON"
-              end
-            else
-              to_s
-            end
-          end
-        end
-
-        module String
-          # This string should be encoded with UTF-8 A call to this method
-          # returns a JSON string encoded with UTF16 big endian characters as
-          # \u????.
-          def to_json(*)
-            '"' << JSON.utf8_to_json(self) << '"'
-          end
-
-          # Module that holds the extinding methods if, the String module is
-          # included.
-          module Extend
-            # Raw Strings are JSON Objects (the raw bytes are stored in an array for the
-            # key "raw"). The Ruby String can be created by this module method.
-            def json_create(o)
-              o['raw'].pack('C*')
-            end
-          end
-
-          # Extends _modul_ with the String::Extend module.
-          def self.included(modul)
-            modul.extend Extend
-          end
-
-          # This method creates a raw object hash, that can be nested into
-          # other data structures and will be unparsed as a raw string. This
-          # method should be used, if you want to convert raw strings to JSON
-          # instead of UTF-8 strings, e. g. binary data.
-          def to_json_raw_object
-            {
-              JSON.create_id  => self.class.name,
-              'raw'           => self.unpack('C*'),
-            }
-          end
-
-          # This method creates a JSON text from the result of
-          # a call to to_json_raw_object of this String.
-          def to_json_raw(*args)
-            to_json_raw_object.to_json(*args)
-          end
-        end
-
-        module TrueClass
-          # Returns a JSON string for true: 'true'.
-          def to_json(*) 'true' end
-        end
-
-        module FalseClass
-          # Returns a JSON string for false: 'false'.
-          def to_json(*) 'false' end
-        end
-
-        module NilClass
-          # Returns a JSON string for nil: 'null'.
-          def to_json(*) 'null' end
-        end
-      end
-    end
-  end
-end
Index: ext/json/lib/json/pure/parser.rb
===================================================================
--- ext/json/lib/json/pure/parser.rb	(revision 23345)
+++ ext/json/lib/json/pure/parser.rb	(revision 23346)
@@ -1,269 +0,0 @@
-require 'strscan'
-
-module JSON
-  module Pure
-    # This class implements the JSON parser that is used to parse a JSON string
-    # into a Ruby data structure.
-    class Parser < StringScanner
-      STRING                = /" ((?:[^\x0-\x1f"\\] |
-                                  \\["\\\/bfnrt] |
-                                  \\u[0-9a-fA-F]{4} |
-                                  \\[\x20-\xff])*)
-                              "/nx
-      INTEGER               = /(-?0|-?[1-9]\d*)/
-      FLOAT                 = /(-?
-                                (?:0|[1-9]\d*)
-                                (?:
-                                  \.\d+(?i:e[+-]?\d+) |
-                                  \.\d+ |
-                                  (?i:e[+-]?\d+)
-                                )
-                                )/x
-      NAN                   = /NaN/
-      INFINITY              = /Infinity/
-      MINUS_INFINITY        = /-Infinity/
-      OBJECT_OPEN           = /\{/
-      OBJECT_CLOSE          = /\}/
-      ARRAY_OPEN            = /\[/
-      ARRAY_CLOSE           = /\]/
-      PAIR_DELIMITER        = /:/
-      COLLECTION_DELIMITER  = /,/
-      TRUE                  = /true/
-      FALSE                 = /false/
-      NULL                  = /null/
-      IGNORE                = %r(
-        (?:
-         //[^\n\r]*[\n\r]| # line comments
-         /\*               # c-style comments
-         (?:
-          [^*/]|        # normal chars
-          /[^*]|        # slashes that do not start a nested comment
-          \*[^/]|       # asterisks that do not end this comment
-          /(?=\*/)      # single slash before this comment's end
-         )*
-           \*/               # the End of this comment
-           |[ \t\r\n]+       # whitespaces: space, horicontal tab, lf, cr
-        )+
-      )mx
-
-      UNPARSED = Object.new
-
-      # Creates a new JSON::Pure::Parser instance for the string _source_.
-      #
-      # It will be configured by the _opts_ hash. _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|nil|0,
-      #   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.
-      # * *create_additions*: If set to false, the Parser doesn't create
-      #   additions even if a matchin class and create_id was found. This option
-      #   defaults to true.
-      def initialize(source, opts = {})
-        super
-        if !opts.key?(:max_nesting) # defaults to 19
-          @max_nesting = 19
-        elsif opts[:max_nesting]
-          @max_nesting = opts[:max_nesting]
-        else
-          @max_nesting = 0
-        end
-        @allow_nan = !!opts[:allow_nan]
-        ca = true
-        ca = opts[:create_additions] if opts.key?(:create_additions)
-        @create_id = ca ? JSON.create_id : nil
-      end
-
-      alias source string
-
-      # Parses the current JSON string _source_ and returns the complete data
-      # structure as a result.
-      def parse
-        reset
-        obj = nil
-        until eos?
-          case
-          when scan(OBJECT_OPEN)
-            obj and raise ParserError, "source '#{peek(20)}' not in JSON!"
-            @current_nesting = 1
-            obj = parse_object
-          when scan(ARRAY_OPEN)
-            obj and raise ParserError, "source '#{peek(20)}' not in JSON!"
-            @current_nesting = 1
-            obj = parse_array
-          when skip(IGNORE)
-            ;
-          else
-            raise ParserError, "source '#{peek(20)}' not in JSON!"
-          end
-        end
-        obj or raise ParserError, "source did not contain any JSON!"
-        obj
-      end
-
-      private
-
-      # Unescape characters in strings.
-      UNESCAPE_MAP = Hash.new { |h, k| h[k] = k.chr }
-      UNESCAPE_MAP.update({
-        ?"  => '"',
-        ?\\ => '\\',
-        ?/  => '/',
-        ?b  => "\b",
-        ?f  => "\f",
-        ?n  => "\n",
-        ?r  => "\r",
-        ?t  => "\t",
-        ?u  => nil,
-      })
-
-      def parse_string
-        if scan(STRING)
-          return '' if self[1].empty?
-          self[1].gsub(%r((?:\\[\\bfnrt"/]|(?:\\u(?:[A-Fa-f\d]{4}))+|\\[\x20-\xff]))n) do |c|
-            if u = UNESCAPE_MAP[$&[1]]
-              u
-            else # \uXXXX
-              res = []
-              stack = nil
-              [c.delete!('\\\\u')].pack("H*").unpack("n*").each do |c|
-                case c
-                when 0xD800..0xDBFF
-                  raise JSON::ParserError, "partial character in source" if stack
-                  stack = c
-                when 0xDC00..0xDFFF
-                  raise JSON::ParserError,
-                    "partial character in source" unless (0xD800..0xDBFF).include?(stack)
-                  res << (stack << 10) - 0x35fdc00 + c
-                  stack = nil
-                else
-                  raise JSON::ParserError, "partial character in source" if stack
-                  res << c
-                end
-              end
-              raise JSON::ParserError, "partial character in source" if stack
-              res.pack("U*")
-            end
-          end.force_encoding("UTF-8")
-        else
-          UNPARSED
-        end
-      end
-
-      def parse_value
-        case
-        when scan(FLOAT)
-          Float(self[1])
-        when scan(INTEGER)
-          Integer(self[1])
-        when scan(TRUE)
-          true
-        when scan(FALSE)
-          false
-        when scan(NULL)
-          nil
-        when (string = parse_string) != UNPARSED
-          string
-        when scan(ARRAY_OPEN)
-          @current_nesting += 1
-          ary = parse_array
-          @current_nesting -= 1
-          ary
-        when scan(OBJECT_OPEN)
-          @current_nesting += 1
-          obj = parse_object
-          @current_nesting -= 1
-          obj
-        when @allow_nan && scan(NAN)
-          NaN
-        when @allow_nan && scan(INFINITY)
-          Infinity
-        when @allow_nan && scan(MINUS_INFINITY)
-          MinusInfinity
-        else
-          UNPARSED
-        end
-      end
-
-      def parse_array
-        raise NestingError, "nesting of #@current_nesting is to deep" if
-          @max_nesting.nonzero? && @current_nesting > @max_nesting
-        result = []
-        delim = false
-        until eos?
-          case
-          when (value = parse_value) != UNPARSED
-            delim = false
-            result << value
-            skip(IGNORE)
-            if scan(COLLECTION_DELIMITER)
-              delim = true
-            elsif match?(ARRAY_CLOSE)
-              ;
-            else
-              raise ParserError, "expected ',' or ']' in array at '#{peek(20)}'!"
-            end
-          when scan(ARRAY_CLOSE)
-            if delim
-              raise ParserError, "expected next element in array at '#{peek(20)}'!"
-            end
-            break
-          when skip(IGNORE)
-            ;
-          else
-            raise ParserError, "unexpected token in array at '#{peek(20)}'!"
-          end
-        end
-        result
-      end
-
-      def parse_object
-        raise NestingError, "nesting of #@current_nesting is to deep" if
-          @max_nesting.nonzero? && @current_nesting > @max_nesting
-        result = {}
-        delim = false
-        until eos?
-          case
-          when (string = parse_string) != UNPARSED
-            skip(IGNORE)
-            unless scan(PAIR_DELIMITER)
-              raise ParserError, "expected ':' in object at '#{peek(20)}'!"
-            end
-            skip(IGNORE)
-            unless (value = parse_value).equal? UNPARSED
-              result[string] = value
-              delim = false
-              skip(IGNORE)
-              if scan(COLLECTION_DELIMITER)
-                delim = true
-              elsif match?(OBJECT_CLOSE)
-                ;
-              else
-                raise ParserError, "expected ',' or '}' in object at '#{peek(20)}'!"
-              end
-            else
-              raise ParserError, "expected value in object at '#{peek(20)}'!"
-            end
-          when scan(OBJECT_CLOSE)
-            if delim
-              raise ParserError, "expected next name, value pair in object at '#{peek(20)}'!"
-            end
-            if @create_id and klassname = result[@create_id]
-              klass = JSON.deep_const_get klassname
-              break unless klass and klass.json_creatable?
-              result = klass.json_create(result)
-            end
-            break
-          when skip(IGNORE)
-            ;
-          else
-            raise ParserError, "unexpected token in object at '#{peek(20)}'!"
-          end
-        end
-        result
-      end
-    end
-  end
-end
Index: ext/json/lib/json.rb
===================================================================
--- ext/json/lib/json.rb	(revision 23345)
+++ ext/json/lib/json.rb	(revision 23346)
@@ -77,57 +77,121 @@
 #
 # == Speed Comparisons
 #
-# I have created some benchmark results (see the benchmarks subdir of the
-# package) for the JSON-Parser to estimate the speed up in the C extension:
+# I have created some benchmark results (see the benchmarks/data-p4-3Ghz
+# subdir of the package) for the JSON-parser to estimate the speed up in the C
+# extension:
 #
-# JSON::Pure::Parser::  28.90  calls/second
-# JSON::Ext::Parser::  505.50 calls/second
+#  Comparing times (call_time_mean):
+#   1 ParserBenchmarkExt#parser   900 repeats:
+#         553.922304770 (  real) ->   21.500x
+#           0.001805307
+#   2 ParserBenchmarkYAML#parser  1000 repeats:
+#         224.513358139 (  real) ->    8.714x
+#           0.004454078
+#   3 ParserBenchmarkPure#parser  1000 repeats:
+#          26.755020642 (  real) ->    1.038x
+#           0.037376163
+#   4 ParserBenchmarkRails#parser 1000 repeats:
+#          25.763381731 (  real) ->    1.000x
+#           0.038814780
+#             calls/sec (  time) ->    speed  covers
+#             secs/call
 #
-# This is ca. <b>17.5</b> times the speed of the pure Ruby implementation.
+# In the table above 1 is JSON::Ext::Parser, 2 is YAML.load with YAML
+# compatbile JSON document, 3 is is JSON::Pure::Parser, and 4 is
+# ActiveSupport::JSON.decode. The ActiveSupport JSON-decoder converts the
+# input first to YAML and then uses the YAML-parser, the conversion seems to
+# slow it down so much that it is only as fast as the JSON::Pure::Parser!
 #
-# I have benchmarked the JSON-Generator as well. This generates a few more
-# values, because there are different modes, that also influence the achieved
-# speed:
+# If you look at the benchmark data you can see that this is mostly caused by
+# the frequent high outliers - the median of the Rails-parser runs is still
+# overall smaller than the median of the JSON::Pure::Parser runs:
 #
-# * JSON::Pure::Generator:
-#   generate::        35.06 calls/second
-#   pretty_generate:: 34.00 calls/second
-#   fast_generate::   41.06 calls/second
+#  Comparing times (call_time_median):
+#   1 ParserBenchmarkExt#parser   900 repeats:
+#         800.592479481 (  real) ->   26.936x
+#           0.001249075
+#   2 ParserBenchmarkYAML#parser  1000 repeats:
+#         271.002390644 (  real) ->    9.118x
+#           0.003690004
+#   3 ParserBenchmarkRails#parser 1000 repeats:
+#          30.227910865 (  real) ->    1.017x
+#           0.033082008
+#   4 ParserBenchmarkPure#parser  1000 repeats:
+#          29.722384421 (  real) ->    1.000x
+#           0.033644676
+#             calls/sec (  time) ->    speed  covers
+#             secs/call
 #
-# * JSON::Ext::Generator:
-#   generate::        492.11 calls/second
-#   pretty_generate:: 348.85 calls/second
-#   fast_generate::   541.60 calls/second
+# I have benchmarked the JSON-Generator as well. This generated a few more
+# values, because there are different modes that also influence the achieved
+# speed:
 #
-# * Speedup Ext/Pure:
-#   generate safe::   14.0 times
-#   generate pretty:: 10.3 times
-#   generate fast::   13.2 times
+#  Comparing times (call_time_mean):
+#   1 GeneratorBenchmarkExt#generator_fast    1000 repeats:
+#         547.354332608 (  real) ->   15.090x
+#           0.001826970
+#   2 GeneratorBenchmarkExt#generator_safe    1000 repeats:
+#         443.968212317 (  real) ->   12.240x
+#           0.002252414
+#   3 GeneratorBenchmarkExt#generator_pretty  900 repeats:
+#         375.104545883 (  real) ->   10.341x
+#           0.002665923
+#   4 GeneratorBenchmarkPure#generator_fast   1000 repeats:
+#          49.978706968 (  real) ->    1.378x
+#           0.020008521
+#   5 GeneratorBenchmarkRails#generator       1000 repeats:
+#          38.531868759 (  real) ->    1.062x
+#           0.025952543
+#   6 GeneratorBenchmarkPure#generator_safe   1000 repeats:
+#          36.927649925 (  real) ->    1.018x 7 (>=3859)
+#           0.027079979
+#   7 GeneratorBenchmarkPure#generator_pretty 1000 repeats:
+#          36.272134441 (  real) ->    1.000x 6 (>=3859)
+#           0.027569373
+#             calls/sec (  time) ->    speed  covers
+#             secs/call
 #
-# The rails framework includes a generator as well, also it seems to be rather
-# slow: I measured only 23.87 calls/second which is slower than any of my pure
-# generator results. Here a comparison of the different speedups with the Rails
-# measurement as the divisor:
+# In the table above 1-3 are JSON::Ext::Generator methods. 4, 6, and 7 are
+# JSON::Pure::Generator methods and 5 is the Rails JSON generator. It is now a
+# bit faster than the generator_safe and generator_pretty methods of the pure
+# variant but slower than the others.
 #
-# * Speedup Pure/Rails:
-#   generate safe::   1.5 times
-#   generate pretty:: 1.4 times
-#   generate fast::   1.7 times
+# To achieve the fastest JSON text output, you can use the fast_generate
+# method. Beware, that this will disable the checking for circular Ruby data
+# structures, which may cause JSON to go into an infinite loop.
 #
-# * Speedup Ext/Rails:
-#   generate safe::   20.6 times
-#   generate pretty:: 14.6 times
-#   generate fast::   22.7 times
+# Here are the median comparisons for completeness' sake:
 #
-# To achieve the fastest JSON text output, you can use the
-# fast_generate/fast_unparse methods. Beware, that this will disable the
-# checking for circular Ruby data structures, which may cause JSON to go into
-# an infinite loop.
+#  Comparing times (call_time_median):
+#   1 GeneratorBenchmarkExt#generator_fast    1000 repeats:
+#         708.258020939 (  real) ->   16.547x
+#           0.001411915
+#   2 GeneratorBenchmarkExt#generator_safe    1000 repeats:
+#         569.105020353 (  real) ->   13.296x
+#           0.001757145
+#   3 GeneratorBenchmarkExt#generator_pretty  900 repeats:
+#         482.825371244 (  real) ->   11.280x
+#           0.002071142
+#   4 GeneratorBenchmarkPure#generator_fast   1000 repeats:
+#          62.717626652 (  real) ->    1.465x
+#           0.015944481
+#   5 GeneratorBenchmarkRails#generator       1000 repeats:
+#          43.965681162 (  real) ->    1.027x
+#           0.022745013
+#   6 GeneratorBenchmarkPure#generator_safe   1000 repeats:
+#          43.929073409 (  real) ->    1.026x 7 (>=3859)
+#           0.022763968
+#   7 GeneratorBenchmarkPure#generator_pretty 1000 repeats:
+#          42.802514491 (  real) ->    1.000x 6 (>=3859)
+#           0.023363113
+#             calls/sec (  time) ->    speed  covers
+#             secs/call
 #
 # == Examples
 #
-# To create a JSON text from a ruby data structure, you
-# can call JSON.generate (or JSON.unparse) like that:
+# To create a JSON text from a ruby data structure, you can call JSON.generate
+# like that:
 #
 #  json = JSON.generate [1, 2, {"a"=>3.141}, false, true, nil, 4..10]
 #  # => "[1,2,{\"a\":3.141},false,true,null,\"4..10\"]"
@@ -210,8 +274,8 @@
 #    }
 #  ]
 #
-# There are also the methods Kernel#j for unparse, and Kernel#jj for
-# pretty_unparse output to the console, that work analogous to Core Ruby's p
+# There are also the methods Kernel#j for generate, and Kernel#jj for
+# pretty_generate output to the console, that work analogous to Core Ruby's p
 # and the pp library's pp methods.
 #
 # The script tools/server.rb contains a small example if you want to test, how
@@ -230,6 +294,4 @@
       require 'json/pure'
     end
   end
-
-  JSON_LOADED = true
 end

Property changes on: ext/json/lib/json.rb
___________________________________________________________________
Name: svn:executable
   + *


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

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