oj 2.17.4 → 2.17.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
 - data/README.md +2 -3
 - data/ext/oj/dump.c +102 -42
 - data/lib/oj/version.rb +1 -1
 - data/test/bug.rb +37 -50
 - data/test/bug2.rb +10 -0
 - data/test/bug3.rb +46 -0
 - data/test/bug_fast.rb +32 -0
 - data/test/bug_load.rb +24 -0
 - data/test/crash.rb +111 -0
 - data/test/example.rb +11 -0
 - data/test/foo.rb +24 -0
 - data/test/io.rb +48 -0
 - data/test/isolated/test_mimic_rails_datetime.rb +27 -0
 - data/test/{test_range.rb → mod.rb} +6 -9
 - data/test/rails.rb +50 -0
 - data/test/russian.rb +18 -0
 - data/test/struct.rb +29 -0
 - data/test/test_serializer.rb +59 -0
 - data/test/test_various.rb +1 -1
 - data/test/write_timebars.rb +31 -0
 - metadata +70 -61
 - data/test/aaa.rb +0 -21
 - data/test/pact.rb +0 -21
 - data/test/perf1.rb +0 -64
 - data/test/perf2.rb +0 -76
 - data/test/perf_obj_old.rb +0 -213
 - data/test/test_bigd.rb +0 -63
 
    
        checksums.yaml
    ADDED
    
    | 
         @@ -0,0 +1,7 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            ---
         
     | 
| 
      
 2 
     | 
    
         
            +
            SHA1:
         
     | 
| 
      
 3 
     | 
    
         
            +
              metadata.gz: f9904f1f35cca59ff6e3e9f9f3a2e391cdc29404
         
     | 
| 
      
 4 
     | 
    
         
            +
              data.tar.gz: 77f647f9b93058861cbe1f2fe84e1063169fc5b1
         
     | 
| 
      
 5 
     | 
    
         
            +
            SHA512:
         
     | 
| 
      
 6 
     | 
    
         
            +
              metadata.gz: eb5d9a18cc205da2c52035750f274ea4c9a41fbe71b383eff0e032c4006c37c87c8b3a3fb238239e4e4e4f8ee9920007666fe3daa9de1b001e2cc118d1ebcf22
         
     | 
| 
      
 7 
     | 
    
         
            +
              data.tar.gz: 8e414158909fcdf69bb16fc1465b6d710ec36f1845849f716c021629162873026d6fa38cf19330e92a65911804df69eaea6e982b84b7b153853e0e09df303651
         
     | 
    
        data/README.md
    CHANGED
    
    | 
         @@ -170,10 +170,9 @@ Oj.default_options = {:mode => :compat } 
     | 
|
| 
       170 
170 
     | 
    
         | 
| 
       171 
171 
     | 
    
         
             
            ## Releases
         
     | 
| 
       172 
172 
     | 
    
         | 
| 
       173 
     | 
    
         
            -
            **Release 2.17. 
     | 
| 
      
 173 
     | 
    
         
            +
            **Future Release 2.17.5**
         
     | 
| 
       174 
174 
     | 
    
         | 
| 
       175 
     | 
    
         
            -
            - Added  
     | 
| 
       176 
     | 
    
         
            -
              it is consistent with the undocumented feature in the json gem.
         
     | 
| 
      
 175 
     | 
    
         
            +
            - Added additional code to check for as_json arguments and recursive calls.
         
     | 
| 
       177 
176 
     | 
    
         | 
| 
       178 
177 
     | 
    
         
             
            [Older release notes](http://www.ohler.com/dev/oj_misc/release_notes.html).
         
     | 
| 
       179 
178 
     | 
    
         | 
    
        data/ext/oj/dump.c
    CHANGED
    
    | 
         @@ -59,7 +59,7 @@ 
     | 
|
| 
       59 
59 
     | 
    
         
             
            typedef unsigned long	ulong;
         
     | 
| 
       60 
60 
     | 
    
         | 
| 
       61 
61 
     | 
    
         
             
            static void	raise_strict(VALUE obj);
         
     | 
| 
       62 
     | 
    
         
            -
            static void	dump_val(VALUE obj, int depth, Out out, int argc, VALUE *argv);
         
     | 
| 
      
 62 
     | 
    
         
            +
            static void	dump_val(VALUE obj, int depth, Out out, int argc, VALUE *argv, bool as_ok);
         
     | 
| 
       63 
63 
     | 
    
         
             
            static void	dump_nil(Out out);
         
     | 
| 
       64 
64 
     | 
    
         
             
            static void	dump_true(Out out);
         
     | 
| 
       65 
65 
     | 
    
         
             
            static void	dump_false(Out out);
         
     | 
| 
         @@ -85,11 +85,11 @@ static void	dump_ruby_time(VALUE obj, Out out); 
     | 
|
| 
       85 
85 
     | 
    
         
             
            static void	dump_xml_time(VALUE obj, Out out);
         
     | 
| 
       86 
86 
     | 
    
         
             
            static void	dump_data_strict(VALUE obj, Out out);
         
     | 
| 
       87 
87 
     | 
    
         
             
            static void	dump_data_null(VALUE obj, Out out);
         
     | 
| 
       88 
     | 
    
         
            -
            static void	dump_data_comp(VALUE obj, int depth, Out out);
         
     | 
| 
      
 88 
     | 
    
         
            +
            static void	dump_data_comp(VALUE obj, int depth, Out out, int argc, VALUE *argv, bool as_ok);
         
     | 
| 
       89 
89 
     | 
    
         
             
            static void	dump_data_obj(VALUE obj, int depth, Out out);
         
     | 
| 
       90 
     | 
    
         
            -
            static void	dump_obj_comp(VALUE obj, int depth, Out out, int argc, VALUE *argv);
         
     | 
| 
      
 90 
     | 
    
         
            +
            static void	dump_obj_comp(VALUE obj, int depth, Out out, int argc, VALUE *argv, bool as_ok);
         
     | 
| 
       91 
91 
     | 
    
         
             
            static void	dump_obj_obj(VALUE obj, int depth, Out out);
         
     | 
| 
       92 
     | 
    
         
            -
            static void	dump_struct_comp(VALUE obj, int depth, Out out);
         
     | 
| 
      
 92 
     | 
    
         
            +
            static void	dump_struct_comp(VALUE obj, int depth, Out out, int argc, VALUE *argv, bool as_ok);
         
     | 
| 
       93 
93 
     | 
    
         
             
            static void	dump_struct_obj(VALUE obj, int depth, Out out);
         
     | 
| 
       94 
94 
     | 
    
         
             
            #if HAS_IVAR_HELPERS
         
     | 
| 
       95 
95 
     | 
    
         
             
            static int	dump_attr_cb(ID key, VALUE value, Out out);
         
     | 
| 
         @@ -795,7 +795,7 @@ dump_array(VALUE a, VALUE clas, int depth, Out out) { 
     | 
|
| 
       795 
795 
     | 
    
         
             
            	    } else {
         
     | 
| 
       796 
796 
     | 
    
         
             
            		fill_indent(out, d2);
         
     | 
| 
       797 
797 
     | 
    
         
             
            	    }
         
     | 
| 
       798 
     | 
    
         
            -
            	    dump_val(rb_ary_entry(a, i), d2, out, 0, 0);
         
     | 
| 
      
 798 
     | 
    
         
            +
            	    dump_val(rb_ary_entry(a, i), d2, out, 0, 0, true);
         
     | 
| 
       799 
799 
     | 
    
         
             
            	    if (i < cnt) {
         
     | 
| 
       800 
800 
     | 
    
         
             
            		*out->cur++ = ',';
         
     | 
| 
       801 
801 
     | 
    
         
             
            	    }
         
     | 
| 
         @@ -876,7 +876,7 @@ hash_cb_strict(VALUE key, VALUE value, Out out) { 
     | 
|
| 
       876 
876 
     | 
    
         
             
            	    out->cur += out->opts->dump_opts.after_size;
         
     | 
| 
       877 
877 
     | 
    
         
             
            	}
         
     | 
| 
       878 
878 
     | 
    
         
             
                }
         
     | 
| 
       879 
     | 
    
         
            -
                dump_val(value, depth, out, 0, 0);
         
     | 
| 
      
 879 
     | 
    
         
            +
                dump_val(value, depth, out, 0, 0, false);
         
     | 
| 
       880 
880 
     | 
    
         
             
                out->depth = depth;
         
     | 
| 
       881 
881 
     | 
    
         
             
                *out->cur++ = ',';
         
     | 
| 
       882 
882 
     | 
    
         | 
| 
         @@ -943,7 +943,7 @@ hash_cb_compat(VALUE key, VALUE value, Out out) { 
     | 
|
| 
       943 
943 
     | 
    
         
             
            	    out->cur += out->opts->dump_opts.after_size;
         
     | 
| 
       944 
944 
     | 
    
         
             
            	}
         
     | 
| 
       945 
945 
     | 
    
         
             
                }
         
     | 
| 
       946 
     | 
    
         
            -
                dump_val(value, depth, out, 0, 0);
         
     | 
| 
      
 946 
     | 
    
         
            +
                dump_val(value, depth, out, 0, 0, true);
         
     | 
| 
       947 
947 
     | 
    
         
             
                out->depth = depth;
         
     | 
| 
       948 
948 
     | 
    
         
             
                *out->cur++ = ',';
         
     | 
| 
       949 
949 
     | 
    
         | 
| 
         @@ -965,11 +965,11 @@ hash_cb_object(VALUE key, VALUE value, Out out) { 
     | 
|
| 
       965 
965 
     | 
    
         
             
                if (rb_type(key) == T_STRING) {
         
     | 
| 
       966 
966 
     | 
    
         
             
            	dump_str_obj(key, Qundef, depth, out);
         
     | 
| 
       967 
967 
     | 
    
         
             
            	*out->cur++ = ':';
         
     | 
| 
       968 
     | 
    
         
            -
            	dump_val(value, depth, out, 0, 0);
         
     | 
| 
      
 968 
     | 
    
         
            +
            	dump_val(value, depth, out, 0, 0, true);
         
     | 
| 
       969 
969 
     | 
    
         
             
                } else if (rb_type(key) == T_SYMBOL) {
         
     | 
| 
       970 
970 
     | 
    
         
             
            	dump_sym_obj(key, out);
         
     | 
| 
       971 
971 
     | 
    
         
             
            	*out->cur++ = ':';
         
     | 
| 
       972 
     | 
    
         
            -
            	dump_val(value, depth, out, 0, 0);
         
     | 
| 
      
 972 
     | 
    
         
            +
            	dump_val(value, depth, out, 0, 0, true);
         
     | 
| 
       973 
973 
     | 
    
         
             
                } else {
         
     | 
| 
       974 
974 
     | 
    
         
             
            	int	d2 = depth + 1;
         
     | 
| 
       975 
975 
     | 
    
         
             
            	long	s2 = size + out->indent + 1;
         
     | 
| 
         @@ -997,13 +997,13 @@ hash_cb_object(VALUE key, VALUE value, Out out) { 
     | 
|
| 
       997 
997 
     | 
    
         
             
            	*out->cur++ = ':';
         
     | 
| 
       998 
998 
     | 
    
         
             
            	*out->cur++ = '[';
         
     | 
| 
       999 
999 
     | 
    
         
             
            	fill_indent(out, d2);
         
     | 
| 
       1000 
     | 
    
         
            -
            	dump_val(key, d2, out, 0, 0);
         
     | 
| 
      
 1000 
     | 
    
         
            +
            	dump_val(key, d2, out, 0, 0, true);
         
     | 
| 
       1001 
1001 
     | 
    
         
             
            	if (out->end - out->cur <= (long)s2) {
         
     | 
| 
       1002 
1002 
     | 
    
         
             
            	    grow(out, s2);
         
     | 
| 
       1003 
1003 
     | 
    
         
             
            	}
         
     | 
| 
       1004 
1004 
     | 
    
         
             
            	*out->cur++ = ',';
         
     | 
| 
       1005 
1005 
     | 
    
         
             
            	fill_indent(out, d2);
         
     | 
| 
       1006 
     | 
    
         
            -
            	dump_val(value, d2, out, 0, 0);
         
     | 
| 
      
 1006 
     | 
    
         
            +
            	dump_val(value, d2, out, 0, 0, true);
         
     | 
| 
       1007 
1007 
     | 
    
         
             
            	if (out->end - out->cur <= (long)size) {
         
     | 
| 
       1008 
1008 
     | 
    
         
             
            	    grow(out, size);
         
     | 
| 
       1009 
1009 
     | 
    
         
             
            	}
         
     | 
| 
         @@ -1318,10 +1318,10 @@ dump_data_null(VALUE obj, Out out) { 
     | 
|
| 
       1318 
1318 
     | 
    
         
             
            }
         
     | 
| 
       1319 
1319 
     | 
    
         | 
| 
       1320 
1320 
     | 
    
         
             
            static void
         
     | 
| 
       1321 
     | 
    
         
            -
            dump_data_comp(VALUE obj, int depth, Out out) {
         
     | 
| 
      
 1321 
     | 
    
         
            +
            dump_data_comp(VALUE obj, int depth, Out out, int argc, VALUE *argv, bool as_ok) {
         
     | 
| 
       1322 
1322 
     | 
    
         
             
                VALUE	clas = rb_obj_class(obj);
         
     | 
| 
       1323 
1323 
     | 
    
         | 
| 
       1324 
     | 
    
         
            -
                if (rb_respond_to(obj, oj_to_hash_id)) {
         
     | 
| 
      
 1324 
     | 
    
         
            +
                if (as_ok && rb_respond_to(obj, oj_to_hash_id)) {
         
     | 
| 
       1325 
1325 
     | 
    
         
             
            	volatile VALUE	h = rb_funcall(obj, oj_to_hash_id, 0);
         
     | 
| 
       1326 
1326 
     | 
    
         | 
| 
       1327 
1327 
     | 
    
         
             
            	if (T_HASH != rb_type(h)) {
         
     | 
| 
         @@ -1330,7 +1330,7 @@ dump_data_comp(VALUE obj, int depth, Out out) { 
     | 
|
| 
       1330 
1330 
     | 
    
         
             
            	    // will be dumped.
         
     | 
| 
       1331 
1331 
     | 
    
         | 
| 
       1332 
1332 
     | 
    
         
             
            	    //rb_raise(rb_eTypeError, "%s.to_hash() did not return a Hash.\n", rb_class2name(rb_obj_class(obj)));
         
     | 
| 
       1333 
     | 
    
         
            -
            	    dump_val(h, depth, out, 0, 0);
         
     | 
| 
      
 1333 
     | 
    
         
            +
            	    dump_val(h, depth, out, 0, 0, false);
         
     | 
| 
       1334 
1334 
     | 
    
         
             
            	}
         
     | 
| 
       1335 
1335 
     | 
    
         
             
            	dump_hash(h, Qundef, depth, out->opts->mode, out);
         
     | 
| 
       1336 
1336 
     | 
    
         | 
| 
         @@ -1338,16 +1338,36 @@ dump_data_comp(VALUE obj, int depth, Out out) { 
     | 
|
| 
       1338 
1338 
     | 
    
         
             
            	volatile VALUE	rstr = rb_funcall(obj, oj_to_s_id, 0);
         
     | 
| 
       1339 
1339 
     | 
    
         | 
| 
       1340 
1340 
     | 
    
         
             
            	dump_raw(rb_string_value_ptr((VALUE*)&rstr), RSTRING_LEN(rstr), out);
         
     | 
| 
       1341 
     | 
    
         
            -
                } else if (rb_respond_to(obj, oj_as_json_id)) {
         
     | 
| 
       1342 
     | 
    
         
            -
            	volatile VALUE	aj 
     | 
| 
      
 1341 
     | 
    
         
            +
                } else if (as_ok && rb_respond_to(obj, oj_as_json_id)) {
         
     | 
| 
      
 1342 
     | 
    
         
            +
            	volatile VALUE	aj;
         
     | 
| 
      
 1343 
     | 
    
         
            +
             
     | 
| 
      
 1344 
     | 
    
         
            +
            	// Some classes elect to not take an options argument so check the arity
         
     | 
| 
      
 1345 
     | 
    
         
            +
            	// of as_json.
         
     | 
| 
      
 1346 
     | 
    
         
            +
            	switch (rb_obj_method_arity(obj, oj_as_json_id)) {
         
     | 
| 
      
 1347 
     | 
    
         
            +
            	case 0:
         
     | 
| 
      
 1348 
     | 
    
         
            +
            	    aj = rb_funcall2(obj, oj_as_json_id, 0, 0);
         
     | 
| 
      
 1349 
     | 
    
         
            +
            	    break;
         
     | 
| 
      
 1350 
     | 
    
         
            +
            	case 1:
         
     | 
| 
      
 1351 
     | 
    
         
            +
            	    if (1 <= argc) {
         
     | 
| 
      
 1352 
     | 
    
         
            +
            		aj = rb_funcall2(obj, oj_as_json_id, 1, argv);
         
     | 
| 
      
 1353 
     | 
    
         
            +
            	    } else {
         
     | 
| 
      
 1354 
     | 
    
         
            +
            		VALUE	nothing [1];
         
     | 
| 
       1343 
1355 
     | 
    
         | 
| 
      
 1356 
     | 
    
         
            +
            		nothing[0] = Qnil;
         
     | 
| 
      
 1357 
     | 
    
         
            +
            		aj = rb_funcall2(obj, oj_as_json_id, 1, nothing);
         
     | 
| 
      
 1358 
     | 
    
         
            +
            	    }
         
     | 
| 
      
 1359 
     | 
    
         
            +
            	    break;
         
     | 
| 
      
 1360 
     | 
    
         
            +
            	default:
         
     | 
| 
      
 1361 
     | 
    
         
            +
            	    aj = rb_funcall2(obj, oj_as_json_id, argc, argv);
         
     | 
| 
      
 1362 
     | 
    
         
            +
            	    break;
         
     | 
| 
      
 1363 
     | 
    
         
            +
            	}
         
     | 
| 
       1344 
1364 
     | 
    
         
             
            	// Catch the obvious brain damaged recursive dumping.
         
     | 
| 
       1345 
1365 
     | 
    
         
             
            	if (aj == obj) {
         
     | 
| 
       1346 
1366 
     | 
    
         
             
            	    volatile VALUE	rstr = rb_funcall(obj, oj_to_s_id, 0);
         
     | 
| 
       1347 
1367 
     | 
    
         | 
| 
       1348 
1368 
     | 
    
         
             
            	    dump_cstr(rb_string_value_ptr((VALUE*)&rstr), RSTRING_LEN(rstr), 0, 0, out);
         
     | 
| 
       1349 
1369 
     | 
    
         
             
            	} else {
         
     | 
| 
       1350 
     | 
    
         
            -
            	    dump_val(aj, depth, out, 0, 0);
         
     | 
| 
      
 1370 
     | 
    
         
            +
            	    dump_val(aj, depth, out, 0, 0, false);
         
     | 
| 
       1351 
1371 
     | 
    
         
             
            	}
         
     | 
| 
       1352 
1372 
     | 
    
         
             
                } else if (Yes == out->opts->to_json && rb_respond_to(obj, oj_to_json_id)) {
         
     | 
| 
       1353 
1373 
     | 
    
         
             
            	volatile VALUE	rs;
         
     | 
| 
         @@ -1430,8 +1450,8 @@ dump_data_obj(VALUE obj, int depth, Out out) { 
     | 
|
| 
       1430 
1450 
     | 
    
         
             
            }
         
     | 
| 
       1431 
1451 
     | 
    
         | 
| 
       1432 
1452 
     | 
    
         
             
            static void
         
     | 
| 
       1433 
     | 
    
         
            -
            dump_obj_comp(VALUE obj, int depth, Out out, int argc, VALUE *argv) {
         
     | 
| 
       1434 
     | 
    
         
            -
                if (rb_respond_to(obj, oj_to_hash_id)) {
         
     | 
| 
      
 1453 
     | 
    
         
            +
            dump_obj_comp(VALUE obj, int depth, Out out, int argc, VALUE *argv, bool as_ok) {
         
     | 
| 
      
 1454 
     | 
    
         
            +
                if (as_ok && rb_respond_to(obj, oj_to_hash_id)) {
         
     | 
| 
       1435 
1455 
     | 
    
         
             
            	volatile VALUE	h = rb_funcall(obj, oj_to_hash_id, 0);
         
     | 
| 
       1436 
1456 
     | 
    
         | 
| 
       1437 
1457 
     | 
    
         
             
            	if (T_HASH != rb_type(h)) {
         
     | 
| 
         @@ -1440,20 +1460,40 @@ dump_obj_comp(VALUE obj, int depth, Out out, int argc, VALUE *argv) { 
     | 
|
| 
       1440 
1460 
     | 
    
         
             
            	    // will be dumped.
         
     | 
| 
       1441 
1461 
     | 
    
         | 
| 
       1442 
1462 
     | 
    
         
             
            	    //rb_raise(rb_eTypeError, "%s.to_hash() did not return a Hash.\n", rb_class2name(rb_obj_class(obj)));
         
     | 
| 
       1443 
     | 
    
         
            -
            	    dump_val(h, depth, out, 0, 0);
         
     | 
| 
      
 1463 
     | 
    
         
            +
            	    dump_val(h, depth, out, 0, 0, false);
         
     | 
| 
       1444 
1464 
     | 
    
         
             
            	} else {
         
     | 
| 
       1445 
1465 
     | 
    
         
             
            	    dump_hash(h, Qundef, depth, out->opts->mode, out);
         
     | 
| 
       1446 
1466 
     | 
    
         
             
            	}
         
     | 
| 
       1447 
     | 
    
         
            -
                } else if (rb_respond_to(obj, oj_as_json_id)) {
         
     | 
| 
       1448 
     | 
    
         
            -
            	volatile VALUE	aj 
     | 
| 
      
 1467 
     | 
    
         
            +
                } else if (as_ok && rb_respond_to(obj, oj_as_json_id)) {
         
     | 
| 
      
 1468 
     | 
    
         
            +
            	volatile VALUE	aj;
         
     | 
| 
       1449 
1469 
     | 
    
         | 
| 
      
 1470 
     | 
    
         
            +
            	// Some classes elect to not take an options argument so check the arity
         
     | 
| 
      
 1471 
     | 
    
         
            +
            	// of as_json.
         
     | 
| 
      
 1472 
     | 
    
         
            +
            	switch (rb_obj_method_arity(obj, oj_as_json_id)) {
         
     | 
| 
      
 1473 
     | 
    
         
            +
            	case 0:
         
     | 
| 
      
 1474 
     | 
    
         
            +
            	    aj = rb_funcall2(obj, oj_as_json_id, 0, 0);
         
     | 
| 
      
 1475 
     | 
    
         
            +
            	    break;
         
     | 
| 
      
 1476 
     | 
    
         
            +
            	case 1:
         
     | 
| 
      
 1477 
     | 
    
         
            +
            	    if (1 <= argc) {
         
     | 
| 
      
 1478 
     | 
    
         
            +
            		aj = rb_funcall2(obj, oj_as_json_id, 1, argv);
         
     | 
| 
      
 1479 
     | 
    
         
            +
            	    } else {
         
     | 
| 
      
 1480 
     | 
    
         
            +
            		VALUE	nothing [1];
         
     | 
| 
      
 1481 
     | 
    
         
            +
             
     | 
| 
      
 1482 
     | 
    
         
            +
            		nothing[0] = Qnil;
         
     | 
| 
      
 1483 
     | 
    
         
            +
            		aj = rb_funcall2(obj, oj_as_json_id, 1, nothing);
         
     | 
| 
      
 1484 
     | 
    
         
            +
            	    }
         
     | 
| 
      
 1485 
     | 
    
         
            +
            	    break;
         
     | 
| 
      
 1486 
     | 
    
         
            +
            	default:
         
     | 
| 
      
 1487 
     | 
    
         
            +
            	    aj = rb_funcall2(obj, oj_as_json_id, argc, argv);
         
     | 
| 
      
 1488 
     | 
    
         
            +
            	    break;
         
     | 
| 
      
 1489 
     | 
    
         
            +
            	}
         
     | 
| 
       1450 
1490 
     | 
    
         
             
            	// Catch the obvious brain damaged recursive dumping.
         
     | 
| 
       1451 
1491 
     | 
    
         
             
            	if (aj == obj) {
         
     | 
| 
       1452 
1492 
     | 
    
         
             
            	    volatile VALUE	rstr = rb_funcall(obj, oj_to_s_id, 0);
         
     | 
| 
       1453 
1493 
     | 
    
         | 
| 
       1454 
1494 
     | 
    
         
             
            	    dump_cstr(rb_string_value_ptr((VALUE*)&rstr), RSTRING_LEN(rstr), 0, 0, out);
         
     | 
| 
       1455 
1495 
     | 
    
         
             
            	} else {
         
     | 
| 
       1456 
     | 
    
         
            -
            	    dump_val(aj, depth, out, 0, 0);
         
     | 
| 
      
 1496 
     | 
    
         
            +
            	    dump_val(aj, depth, out, 0, 0, false);
         
     | 
| 
       1457 
1497 
     | 
    
         
             
            	}
         
     | 
| 
       1458 
1498 
     | 
    
         
             
                } else if (Yes == out->opts->to_json && rb_respond_to(obj, oj_to_json_id)) {
         
     | 
| 
       1459 
1499 
     | 
    
         
             
            	volatile VALUE	rs;
         
     | 
| 
         @@ -1567,7 +1607,7 @@ dump_attr_cb(ID key, VALUE value, Out out) { 
     | 
|
| 
       1567 
1607 
     | 
    
         
             
            	dump_cstr(buf, strlen(buf), 0, 0, out);
         
     | 
| 
       1568 
1608 
     | 
    
         
             
                }
         
     | 
| 
       1569 
1609 
     | 
    
         
             
                *out->cur++ = ':';
         
     | 
| 
       1570 
     | 
    
         
            -
                dump_val(value, depth, out, 0, 0);
         
     | 
| 
      
 1610 
     | 
    
         
            +
                dump_val(value, depth, out, 0, 0, true);
         
     | 
| 
       1571 
1611 
     | 
    
         
             
                out->depth = depth;
         
     | 
| 
       1572 
1612 
     | 
    
         
             
                *out->cur++ = ',';
         
     | 
| 
       1573 
1613 
     | 
    
         | 
| 
         @@ -1727,7 +1767,7 @@ dump_obj_attrs(VALUE obj, VALUE clas, slot_t id, int depth, Out out) { 
     | 
|
| 
       1727 
1767 
     | 
    
         
             
            		dump_cstr(buf, strlen(attr) + 1, 0, 0, out);
         
     | 
| 
       1728 
1768 
     | 
    
         
             
            	    }
         
     | 
| 
       1729 
1769 
     | 
    
         
             
            	    *out->cur++ = ':';
         
     | 
| 
       1730 
     | 
    
         
            -
            	    dump_val(value, d2, out, 0, 0);
         
     | 
| 
      
 1770 
     | 
    
         
            +
            	    dump_val(value, d2, out, 0, 0, true);
         
     | 
| 
       1731 
1771 
     | 
    
         
             
            	    if (out->end - out->cur <= 2) {
         
     | 
| 
       1732 
1772 
     | 
    
         
             
            		grow(out, 2);
         
     | 
| 
       1733 
1773 
     | 
    
         
             
            	    }
         
     | 
| 
         @@ -1748,7 +1788,7 @@ dump_obj_attrs(VALUE obj, VALUE clas, slot_t id, int depth, Out out) { 
     | 
|
| 
       1748 
1788 
     | 
    
         
             
            	    dump_cstr("~mesg", 5, 0, 0, out);
         
     | 
| 
       1749 
1789 
     | 
    
         
             
            	    *out->cur++ = ':';
         
     | 
| 
       1750 
1790 
     | 
    
         
             
            	    rv = rb_funcall2(obj, rb_intern("message"), 0, 0);
         
     | 
| 
       1751 
     | 
    
         
            -
            	    dump_val(rv, d2, out, 0, 0);
         
     | 
| 
      
 1791 
     | 
    
         
            +
            	    dump_val(rv, d2, out, 0, 0, true);
         
     | 
| 
       1752 
1792 
     | 
    
         
             
            	    if (out->end - out->cur <= 2) {
         
     | 
| 
       1753 
1793 
     | 
    
         
             
            		grow(out, 2);
         
     | 
| 
       1754 
1794 
     | 
    
         
             
            	    }
         
     | 
| 
         @@ -1761,7 +1801,7 @@ dump_obj_attrs(VALUE obj, VALUE clas, slot_t id, int depth, Out out) { 
     | 
|
| 
       1761 
1801 
     | 
    
         
             
            	    dump_cstr("~bt", 3, 0, 0, out);
         
     | 
| 
       1762 
1802 
     | 
    
         
             
            	    *out->cur++ = ':';
         
     | 
| 
       1763 
1803 
     | 
    
         
             
            	    rv = rb_funcall2(obj, rb_intern("backtrace"), 0, 0);
         
     | 
| 
       1764 
     | 
    
         
            -
            	    dump_val(rv, d2, out, 0, 0);
         
     | 
| 
      
 1804 
     | 
    
         
            +
            	    dump_val(rv, d2, out, 0, 0, true);
         
     | 
| 
       1765 
1805 
     | 
    
         
             
            	    if (out->end - out->cur <= 2) {
         
     | 
| 
       1766 
1806 
     | 
    
         
             
            		grow(out, 2);
         
     | 
| 
       1767 
1807 
     | 
    
         
             
            	    }
         
     | 
| 
         @@ -1775,8 +1815,8 @@ dump_obj_attrs(VALUE obj, VALUE clas, slot_t id, int depth, Out out) { 
     | 
|
| 
       1775 
1815 
     | 
    
         
             
            }
         
     | 
| 
       1776 
1816 
     | 
    
         | 
| 
       1777 
1817 
     | 
    
         
             
            static void
         
     | 
| 
       1778 
     | 
    
         
            -
            dump_struct_comp(VALUE obj, int depth, Out out) {
         
     | 
| 
       1779 
     | 
    
         
            -
                if (rb_respond_to(obj, oj_to_hash_id)) {
         
     | 
| 
      
 1818 
     | 
    
         
            +
            dump_struct_comp(VALUE obj, int depth, Out out, int argc, VALUE *argv, bool as_ok) {
         
     | 
| 
      
 1819 
     | 
    
         
            +
                if (as_ok && rb_respond_to(obj, oj_to_hash_id)) {
         
     | 
| 
       1780 
1820 
     | 
    
         
             
            	volatile VALUE	h = rb_funcall(obj, oj_to_hash_id, 0);
         
     | 
| 
       1781 
1821 
     | 
    
         | 
| 
       1782 
1822 
     | 
    
         
             
            	if (T_HASH != rb_type(h)) {
         
     | 
| 
         @@ -1785,19 +1825,39 @@ dump_struct_comp(VALUE obj, int depth, Out out) { 
     | 
|
| 
       1785 
1825 
     | 
    
         
             
            	    // will be dumped.
         
     | 
| 
       1786 
1826 
     | 
    
         | 
| 
       1787 
1827 
     | 
    
         
             
            	    //rb_raise(rb_eTypeError, "%s.to_hash() did not return a Hash.\n", rb_class2name(rb_obj_class(obj)));
         
     | 
| 
       1788 
     | 
    
         
            -
            	    dump_val(h, depth, out, 0, 0);
         
     | 
| 
      
 1828 
     | 
    
         
            +
            	    dump_val(h, depth, out, 0, 0, false);
         
     | 
| 
       1789 
1829 
     | 
    
         
             
            	}
         
     | 
| 
       1790 
1830 
     | 
    
         
             
            	dump_hash(h, Qundef, depth, out->opts->mode, out);
         
     | 
| 
       1791 
     | 
    
         
            -
                } else if (rb_respond_to(obj, oj_as_json_id)) {
         
     | 
| 
       1792 
     | 
    
         
            -
            	volatile VALUE	aj 
     | 
| 
      
 1831 
     | 
    
         
            +
                } else if (as_ok && rb_respond_to(obj, oj_as_json_id)) {
         
     | 
| 
      
 1832 
     | 
    
         
            +
            	volatile VALUE	aj;
         
     | 
| 
      
 1833 
     | 
    
         
            +
             
     | 
| 
      
 1834 
     | 
    
         
            +
            	// Some classes elect to not take an options argument so check the arity
         
     | 
| 
      
 1835 
     | 
    
         
            +
            	// of as_json.
         
     | 
| 
      
 1836 
     | 
    
         
            +
            	switch (rb_obj_method_arity(obj, oj_as_json_id)) {
         
     | 
| 
      
 1837 
     | 
    
         
            +
            	case 0:
         
     | 
| 
      
 1838 
     | 
    
         
            +
            	    aj = rb_funcall2(obj, oj_as_json_id, 0, 0);
         
     | 
| 
      
 1839 
     | 
    
         
            +
            	    break;
         
     | 
| 
      
 1840 
     | 
    
         
            +
            	case 1:
         
     | 
| 
      
 1841 
     | 
    
         
            +
            	    if (1 <= argc) {
         
     | 
| 
      
 1842 
     | 
    
         
            +
            		aj = rb_funcall2(obj, oj_as_json_id, 1, argv);
         
     | 
| 
      
 1843 
     | 
    
         
            +
            	    } else {
         
     | 
| 
      
 1844 
     | 
    
         
            +
            		VALUE	nothing [1];
         
     | 
| 
       1793 
1845 
     | 
    
         | 
| 
      
 1846 
     | 
    
         
            +
            		nothing[0] = Qnil;
         
     | 
| 
      
 1847 
     | 
    
         
            +
            		aj = rb_funcall2(obj, oj_as_json_id, 1, nothing);
         
     | 
| 
      
 1848 
     | 
    
         
            +
            	    }
         
     | 
| 
      
 1849 
     | 
    
         
            +
            	    break;
         
     | 
| 
      
 1850 
     | 
    
         
            +
            	default:
         
     | 
| 
      
 1851 
     | 
    
         
            +
            	    aj = rb_funcall2(obj, oj_as_json_id, argc, argv);
         
     | 
| 
      
 1852 
     | 
    
         
            +
            	    break;
         
     | 
| 
      
 1853 
     | 
    
         
            +
            	}
         
     | 
| 
       1794 
1854 
     | 
    
         
             
            	// Catch the obvious brain damaged recursive dumping.
         
     | 
| 
       1795 
1855 
     | 
    
         
             
            	if (aj == obj) {
         
     | 
| 
       1796 
1856 
     | 
    
         
             
            	    volatile VALUE	rstr = rb_funcall(obj, oj_to_s_id, 0);
         
     | 
| 
       1797 
1857 
     | 
    
         | 
| 
       1798 
1858 
     | 
    
         
             
            	    dump_cstr(rb_string_value_ptr((VALUE*)&rstr), RSTRING_LEN(rstr), 0, 0, out);
         
     | 
| 
       1799 
1859 
     | 
    
         
             
            	} else {
         
     | 
| 
       1800 
     | 
    
         
            -
            	    dump_val(aj, depth, out, 0, 0);
         
     | 
| 
      
 1860 
     | 
    
         
            +
            	    dump_val(aj, depth, out, 0, 0, false);
         
     | 
| 
       1801 
1861 
     | 
    
         
             
            	}
         
     | 
| 
       1802 
1862 
     | 
    
         
             
                } else if (Yes == out->opts->to_json && rb_respond_to(obj, oj_to_json_id)) {
         
     | 
| 
       1803 
1863 
     | 
    
         
             
            	volatile VALUE	rs = rb_funcall(obj, oj_to_json_id, 0);
         
     | 
| 
         @@ -1882,7 +1942,7 @@ dump_struct_obj(VALUE obj, int depth, Out out) { 
     | 
|
| 
       1882 
1942 
     | 
    
         
             
            		grow(out, size);
         
     | 
| 
       1883 
1943 
     | 
    
         
             
            	    }
         
     | 
| 
       1884 
1944 
     | 
    
         
             
            	    fill_indent(out, d3);
         
     | 
| 
       1885 
     | 
    
         
            -
            	    dump_val(*vp, d3, out, 0, 0);
         
     | 
| 
      
 1945 
     | 
    
         
            +
            	    dump_val(*vp, d3, out, 0, 0, true);
         
     | 
| 
       1886 
1946 
     | 
    
         
             
            	    *out->cur++ = ',';
         
     | 
| 
       1887 
1947 
     | 
    
         
             
            	}
         
     | 
| 
       1888 
1948 
     | 
    
         
             
                }
         
     | 
| 
         @@ -2005,7 +2065,7 @@ dump_odd(VALUE obj, Odd odd, VALUE clas, int depth, Out out) { 
     | 
|
| 
       2005 
2065 
     | 
    
         
             
            	    fill_indent(out, d2);
         
     | 
| 
       2006 
2066 
     | 
    
         
             
            	    dump_cstr(name, nlen, 0, 0, out);
         
     | 
| 
       2007 
2067 
     | 
    
         
             
            	    *out->cur++ = ':';
         
     | 
| 
       2008 
     | 
    
         
            -
            	    dump_val(v, d2, out, 0, 0);
         
     | 
| 
      
 2068 
     | 
    
         
            +
            	    dump_val(v, d2, out, 0, 0, true);
         
     | 
| 
       2009 
2069 
     | 
    
         
             
            	    if (out->end - out->cur <= 2) {
         
     | 
| 
       2010 
2070 
     | 
    
         
             
            		grow(out, 2);
         
     | 
| 
       2011 
2071 
     | 
    
         
             
            	    }
         
     | 
| 
         @@ -2023,7 +2083,7 @@ raise_strict(VALUE obj) { 
     | 
|
| 
       2023 
2083 
     | 
    
         
             
            }
         
     | 
| 
       2024 
2084 
     | 
    
         | 
| 
       2025 
2085 
     | 
    
         
             
            static void
         
     | 
| 
       2026 
     | 
    
         
            -
            dump_val(VALUE obj, int depth, Out out, int argc, VALUE *argv) {
         
     | 
| 
      
 2086 
     | 
    
         
            +
            dump_val(VALUE obj, int depth, Out out, int argc, VALUE *argv, bool as_ok) {
         
     | 
| 
       2027 
2087 
     | 
    
         
             
                int	type = rb_type(obj);
         
     | 
| 
       2028 
2088 
     | 
    
         | 
| 
       2029 
2089 
     | 
    
         
             
                if (MAX_DEPTH < depth) {
         
     | 
| 
         @@ -2061,7 +2121,7 @@ dump_val(VALUE obj, int depth, Out out, int argc, VALUE *argv) { 
     | 
|
| 
       2061 
2121 
     | 
    
         
             
            	switch (out->opts->mode) {
         
     | 
| 
       2062 
2122 
     | 
    
         
             
            	case StrictMode:	raise_strict(obj);		break;
         
     | 
| 
       2063 
2123 
     | 
    
         
             
            	case NullMode:		dump_nil(out);			break;
         
     | 
| 
       2064 
     | 
    
         
            -
            	case CompatMode:	dump_struct_comp(obj, depth, out);	break;
         
     | 
| 
      
 2124 
     | 
    
         
            +
            	case CompatMode:	dump_struct_comp(obj, depth, out, argc, argv, as_ok);	break;
         
     | 
| 
       2065 
2125 
     | 
    
         
             
            	case ObjectMode:
         
     | 
| 
       2066 
2126 
     | 
    
         
             
            	default:		dump_struct_obj(obj, depth, out);	break;
         
     | 
| 
       2067 
2127 
     | 
    
         
             
            	}
         
     | 
| 
         @@ -2098,7 +2158,7 @@ dump_val(VALUE obj, int depth, Out out, int argc, VALUE *argv) { 
     | 
|
| 
       2098 
2158 
     | 
    
         
             
            		switch (out->opts->mode) {
         
     | 
| 
       2099 
2159 
     | 
    
         
             
            		case StrictMode:	dump_data_strict(obj, out);	break;
         
     | 
| 
       2100 
2160 
     | 
    
         
             
            		case NullMode:		dump_data_null(obj, out);	break;
         
     | 
| 
       2101 
     | 
    
         
            -
            		case CompatMode:	dump_obj_comp(obj, depth, out, argc, argv);	break;
         
     | 
| 
      
 2161 
     | 
    
         
            +
            		case CompatMode:	dump_obj_comp(obj, depth, out, argc, argv, as_ok);	break;
         
     | 
| 
       2102 
2162 
     | 
    
         
             
            		case ObjectMode:
         
     | 
| 
       2103 
2163 
     | 
    
         
             
            		default:		dump_obj_obj(obj, depth, out);	break;
         
     | 
| 
       2104 
2164 
     | 
    
         
             
            		}
         
     | 
| 
         @@ -2107,7 +2167,7 @@ dump_val(VALUE obj, int depth, Out out, int argc, VALUE *argv) { 
     | 
|
| 
       2107 
2167 
     | 
    
         
             
            		switch (out->opts->mode) {
         
     | 
| 
       2108 
2168 
     | 
    
         
             
            		case StrictMode:	dump_data_strict(obj, out);	break;
         
     | 
| 
       2109 
2169 
     | 
    
         
             
            		case NullMode:		dump_data_null(obj, out);	break;
         
     | 
| 
       2110 
     | 
    
         
            -
            		case CompatMode:	dump_data_comp(obj, depth, out);break;
         
     | 
| 
      
 2170 
     | 
    
         
            +
            		case CompatMode:	dump_data_comp(obj, depth, out, argc, argv, as_ok);break;
         
     | 
| 
       2111 
2171 
     | 
    
         
             
            		case ObjectMode:
         
     | 
| 
       2112 
2172 
     | 
    
         
             
            		default:		dump_data_obj(obj, depth, out);	break;
         
     | 
| 
       2113 
2173 
     | 
    
         
             
            		}
         
     | 
| 
         @@ -2121,7 +2181,7 @@ dump_val(VALUE obj, int depth, Out out, int argc, VALUE *argv) { 
     | 
|
| 
       2121 
2181 
     | 
    
         
             
            		case NullMode:		dump_nil(out);			break;
         
     | 
| 
       2122 
2182 
     | 
    
         
             
            		case CompatMode:
         
     | 
| 
       2123 
2183 
     | 
    
         
             
            		case ObjectMode:
         
     | 
| 
       2124 
     | 
    
         
            -
            		default:		dump_obj_comp(obj, depth, out, argc, argv);	break;
         
     | 
| 
      
 2184 
     | 
    
         
            +
            		default:		dump_obj_comp(obj, depth, out, argc, argv, as_ok);	break;
         
     | 
| 
       2125 
2185 
     | 
    
         
             
            		}
         
     | 
| 
       2126 
2186 
     | 
    
         
             
            		break;
         
     | 
| 
       2127 
2187 
     | 
    
         
             
            	    default:
         
     | 
| 
         @@ -2165,7 +2225,7 @@ oj_dump_obj_to_json_using_params(VALUE obj, Options copts, Out out, int argc, VA 
     | 
|
| 
       2165 
2225 
     | 
    
         
             
            	oj_cache8_new(&out->circ_cache);
         
     | 
| 
       2166 
2226 
     | 
    
         
             
                }
         
     | 
| 
       2167 
2227 
     | 
    
         
             
                out->indent = copts->indent;
         
     | 
| 
       2168 
     | 
    
         
            -
                dump_val(obj, 0, out, argc, argv);
         
     | 
| 
      
 2228 
     | 
    
         
            +
                dump_val(obj, 0, out, argc, argv, true);
         
     | 
| 
       2169 
2229 
     | 
    
         
             
                if (0 < out->indent) {
         
     | 
| 
       2170 
2230 
     | 
    
         
             
            	switch (*(out->cur - 1)) {
         
     | 
| 
       2171 
2231 
     | 
    
         
             
            	case ']':
         
     | 
| 
         @@ -2615,7 +2675,7 @@ oj_str_writer_push_value(StrWriter sw, VALUE val, const char *key) { 
     | 
|
| 
       2615 
2675 
     | 
    
         
             
            	    *sw->out.cur++ = ':';
         
     | 
| 
       2616 
2676 
     | 
    
         
             
            	}
         
     | 
| 
       2617 
2677 
     | 
    
         
             
                }
         
     | 
| 
       2618 
     | 
    
         
            -
                dump_val(val, sw->depth, &sw->out, 0, 0);
         
     | 
| 
      
 2678 
     | 
    
         
            +
                dump_val(val, sw->depth, &sw->out, 0, 0, true);
         
     | 
| 
       2619 
2679 
     | 
    
         
             
            }
         
     | 
| 
       2620 
2680 
     | 
    
         | 
| 
       2621 
2681 
     | 
    
         
             
            void
         
     | 
    
        data/lib/oj/version.rb
    CHANGED
    
    
    
        data/test/bug.rb
    CHANGED
    
    | 
         @@ -5,60 +5,47 @@ $: << File.dirname(__FILE__) 
     | 
|
| 
       5 
5 
     | 
    
         | 
| 
       6 
6 
     | 
    
         
             
            require 'helper'
         
     | 
| 
       7 
7 
     | 
    
         | 
| 
       8 
     | 
    
         
            -
            require 'oj'
         
     | 
| 
       9 
     | 
    
         
            -
            require 'securerandom'
         
     | 
| 
       10 
     | 
    
         
            -
             
     | 
| 
       11 
8 
     | 
    
         
             
            class Handler
         
     | 
| 
       12 
     | 
    
         
            -
              def  
     | 
| 
       13 
     | 
    
         
            -
             
     | 
| 
       14 
     | 
    
         
            -
              def array_start()     [] end
         
     | 
| 
       15 
     | 
    
         
            -
              def array_append(a,v) a << v end
         
     | 
| 
       16 
     | 
    
         
            -
              def error(message, line, column)
         
     | 
| 
       17 
     | 
    
         
            -
                raise Exception.new(message, line, column)
         
     | 
| 
      
 9 
     | 
    
         
            +
              def initialize
         
     | 
| 
      
 10 
     | 
    
         
            +
                @state = []
         
     | 
| 
       18 
11 
     | 
    
         
             
              end
         
     | 
| 
       19 
     | 
    
         
            -
            end
         
     | 
| 
       20 
12 
     | 
    
         | 
| 
       21 
     | 
    
         
            -
             
     | 
| 
      
 13 
     | 
    
         
            +
              def hash_start
         
     | 
| 
      
 14 
     | 
    
         
            +
                @state << {}
         
     | 
| 
      
 15 
     | 
    
         
            +
                @state.last
         
     | 
| 
      
 16 
     | 
    
         
            +
              end
         
     | 
| 
      
 17 
     | 
    
         
            +
             
     | 
| 
      
 18 
     | 
    
         
            +
              def hash_end
         
     | 
| 
      
 19 
     | 
    
         
            +
                @state.pop
         
     | 
| 
      
 20 
     | 
    
         
            +
              end
         
     | 
| 
       22 
21 
     | 
    
         | 
| 
       23 
     | 
    
         
            -
             
     | 
| 
       24 
     | 
    
         
            -
             
     | 
| 
       25 
     | 
    
         
            -
              `mkfifo #{name}`
         
     | 
| 
       26 
     | 
    
         
            -
              if fork
         
     | 
| 
       27 
     | 
    
         
            -
                open(name, 'r+') do |read_io|
         
     | 
| 
       28 
     | 
    
         
            -
                  p "start reading #{read_io.stat.ftype}"
         
     | 
| 
       29 
     | 
    
         
            -
                  Oj.sc_parse(Handler.new, read_io) {|v| p v}
         
     | 
| 
       30 
     | 
    
         
            -
                  p "stop reading"
         
     | 
| 
       31 
     | 
    
         
            -
                end
         
     | 
| 
       32 
     | 
    
         
            -
              else
         
     | 
| 
       33 
     | 
    
         
            -
                open(name, 'w+') do |write_io|
         
     | 
| 
       34 
     | 
    
         
            -
                  p "start writing #{write_io.stat.ftype}  autoclose: #{write_io.autoclose?}"
         
     | 
| 
       35 
     | 
    
         
            -
                  write_io.write json
         
     | 
| 
       36 
     | 
    
         
            -
                  write_io.write json
         
     | 
| 
       37 
     | 
    
         
            -
                  p "stop writing"
         
     | 
| 
       38 
     | 
    
         
            -
                end
         
     | 
| 
       39 
     | 
    
         
            -
                sleep(1) # make it obvious that there are two threads
         
     | 
| 
       40 
     | 
    
         
            -
                open(name, 'w+') do |write_io|
         
     | 
| 
       41 
     | 
    
         
            -
                  p "start writing #{write_io.stat.ftype}"
         
     | 
| 
       42 
     | 
    
         
            -
                  write_io.write json
         
     | 
| 
       43 
     | 
    
         
            -
                  write_io.write json
         
     | 
| 
       44 
     | 
    
         
            -
                  p "stop writing"
         
     | 
| 
       45 
     | 
    
         
            -
                end
         
     | 
| 
      
 22 
     | 
    
         
            +
              def hash_set(h,k,v)
         
     | 
| 
      
 23 
     | 
    
         
            +
                h.store(k,v)
         
     | 
| 
       46 
24 
     | 
    
         
             
              end
         
     | 
| 
       47 
     | 
    
         
            -
             
     | 
| 
       48 
     | 
    
         
            -
               
     | 
| 
       49 
     | 
    
         
            -
                 
     | 
| 
       50 
     | 
    
         
            -
             
     | 
| 
       51 
     | 
    
         
            -
             
     | 
| 
       52 
     | 
    
         
            -
             
     | 
| 
       53 
     | 
    
         
            -
             
     | 
| 
       54 
     | 
    
         
            -
             
     | 
| 
       55 
     | 
    
         
            -
                 
     | 
| 
       56 
     | 
    
         
            -
                  read_io.close
         
     | 
| 
       57 
     | 
    
         
            -
                  p "start writing #{write_io.stat.ftype}"
         
     | 
| 
       58 
     | 
    
         
            -
                  write_io.write json
         
     | 
| 
       59 
     | 
    
         
            -
                  write_io.write json
         
     | 
| 
       60 
     | 
    
         
            -
                  p "stop writing"
         
     | 
| 
       61 
     | 
    
         
            -
                  write_io.close
         
     | 
| 
       62 
     | 
    
         
            -
                end
         
     | 
| 
      
 25 
     | 
    
         
            +
             
     | 
| 
      
 26 
     | 
    
         
            +
              def array_start
         
     | 
| 
      
 27 
     | 
    
         
            +
                @state << []
         
     | 
| 
      
 28 
     | 
    
         
            +
                @state.last
         
     | 
| 
      
 29 
     | 
    
         
            +
              end
         
     | 
| 
      
 30 
     | 
    
         
            +
             
     | 
| 
      
 31 
     | 
    
         
            +
             
     | 
| 
      
 32 
     | 
    
         
            +
              def array_end
         
     | 
| 
      
 33 
     | 
    
         
            +
                @state.pop
         
     | 
| 
       63 
34 
     | 
    
         
             
              end
         
     | 
| 
      
 35 
     | 
    
         
            +
             
     | 
| 
      
 36 
     | 
    
         
            +
              def array_append(a,v)
         
     | 
| 
      
 37 
     | 
    
         
            +
                a << v
         
     | 
| 
      
 38 
     | 
    
         
            +
              end
         
     | 
| 
      
 39 
     | 
    
         
            +
             
     | 
| 
      
 40 
     | 
    
         
            +
              def add_value(v)
         
     | 
| 
      
 41 
     | 
    
         
            +
                p v
         
     | 
| 
      
 42 
     | 
    
         
            +
              end
         
     | 
| 
      
 43 
     | 
    
         
            +
             
     | 
| 
      
 44 
     | 
    
         
            +
              def error(message, line, column); p "ERROR: #{message}" end
         
     | 
| 
       64 
45 
     | 
    
         
             
            end
         
     | 
| 
      
 46 
     | 
    
         
            +
             
     | 
| 
      
 47 
     | 
    
         
            +
            $handler = Handler.new
         
     | 
| 
      
 48 
     | 
    
         
            +
             
     | 
| 
      
 49 
     | 
    
         
            +
            IO.popen("cat tst") { |p| puts Oj.sc_parse($handler, p) }
         
     | 
| 
      
 50 
     | 
    
         
            +
             
     | 
| 
      
 51 
     | 
    
         
            +
            #File.open('tst', 'r') { |file|  Oj.sc_parse($handler, file) }
         
     |