oj 3.7.11 → 3.9.1
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 +4 -4
 - data/README.md +10 -2
 - data/ext/oj/custom.c +74 -48
 - data/ext/oj/dump.c +46 -26
 - data/ext/oj/dump.h +2 -0
 - data/ext/oj/dump_compat.c +13 -9
 - data/ext/oj/extconf.rb +1 -0
 - data/ext/oj/mimic_json.c +7 -2
 - data/ext/oj/object.c +8 -5
 - data/ext/oj/oj.c +37 -27
 - data/ext/oj/oj.h +8 -4
 - data/ext/oj/parse.c +2 -1
 - data/ext/oj/rails.c +41 -28
 - data/ext/oj/resolve.c +3 -3
 - data/ext/oj/sparse.c +2 -2
 - data/ext/oj/string_writer.c +25 -3
 - data/ext/oj/val_stack.c +9 -9
 - data/ext/oj/val_stack.h +9 -9
 - data/lib/oj/json.rb +1 -1
 - data/lib/oj/mimic.rb +1 -1
 - data/lib/oj/version.rb +1 -1
 - data/pages/Modes.md +3 -2
 - data/pages/Options.md +23 -2
 - data/pages/Security.md +1 -1
 - data/test/test_custom.rb +99 -2
 - data/test/test_various.rb +2 -0
 - metadata +4 -4
 
    
        checksums.yaml
    CHANGED
    
    | 
         @@ -1,7 +1,7 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            ---
         
     | 
| 
       2 
2 
     | 
    
         
             
            SHA256:
         
     | 
| 
       3 
     | 
    
         
            -
              metadata.gz:  
     | 
| 
       4 
     | 
    
         
            -
              data.tar.gz:  
     | 
| 
      
 3 
     | 
    
         
            +
              metadata.gz: 4a9bfd0e254e8c30855238077fd24a8398fe6f51027d061865a4bae5b8843577
         
     | 
| 
      
 4 
     | 
    
         
            +
              data.tar.gz: df12b305f11cae6ed49e002b64f02681df83b613674cec99baeaacc9e9308b27
         
     | 
| 
       5 
5 
     | 
    
         
             
            SHA512:
         
     | 
| 
       6 
     | 
    
         
            -
              metadata.gz:  
     | 
| 
       7 
     | 
    
         
            -
              data.tar.gz:  
     | 
| 
      
 6 
     | 
    
         
            +
              metadata.gz: 69db529090d8152e069fab0bb18327ba9cb823817e6282aafeb3caf073a723964e7daf9bf40ffe4921306d8b0caf0fa71e1912bfa6c9c411ee7b87ba8aa4be60
         
     | 
| 
      
 7 
     | 
    
         
            +
              data.tar.gz: c438cdbc8e9ecb36a47b09d88a8e8170a76b1cb04ca966586b8096dbf176503aa9e88da3d4d429f1ad3bc0aef696f58d6367620a35c0f93fc5fda3ec43caa4f9
         
     | 
    
        data/README.md
    CHANGED
    
    | 
         @@ -65,7 +65,7 @@ See [{file:CHANGELOG.md}](CHANGELOG.md) 
     | 
|
| 
       65 
65 
     | 
    
         | 
| 
       66 
66 
     | 
    
         
             
            ## Links
         
     | 
| 
       67 
67 
     | 
    
         | 
| 
       68 
     | 
    
         
            -
             
     | 
| 
      
 68 
     | 
    
         
            +
            - *Documentation*: http://www.ohler.com/oj/doc, http://rubydoc.info/gems/oj
         
     | 
| 
       69 
69 
     | 
    
         | 
| 
       70 
70 
     | 
    
         
             
            - *GitHub* *repo*: https://github.com/ohler55/oj
         
     | 
| 
       71 
71 
     | 
    
         | 
| 
         @@ -93,4 +93,12 @@ Follow [@peterohler on Twitter](http://twitter.com/peterohler) for announcements 
     | 
|
| 
       93 
93 
     | 
    
         | 
| 
       94 
94 
     | 
    
         
             
             - *OjC, a C JSON parser*: https://www.ohler.com/ojc also at https://github.com/ohler55/ojc
         
     | 
| 
       95 
95 
     | 
    
         | 
| 
       96 
     | 
    
         
            -
             - * 
     | 
| 
      
 96 
     | 
    
         
            +
             - *Agoo, a high performance Ruby web server supporting GraphQL on GitHub*: https://github.com/ohler55/agoo
         
     | 
| 
      
 97 
     | 
    
         
            +
             
     | 
| 
      
 98 
     | 
    
         
            +
             - *Agoo-C, a high performance C web server supporting GraphQL on GitHub*: https://github.com/ohler55/agoo-c
         
     | 
| 
      
 99 
     | 
    
         
            +
             
     | 
| 
      
 100 
     | 
    
         
            +
            #### Contributing
         
     | 
| 
      
 101 
     | 
    
         
            +
             
     | 
| 
      
 102 
     | 
    
         
            +
            + Provide a Pull Request off the `develop` branch.
         
     | 
| 
      
 103 
     | 
    
         
            +
            + Report a bug
         
     | 
| 
      
 104 
     | 
    
         
            +
            + Suggest an idea
         
     | 
    
        data/ext/oj/custom.c
    CHANGED
    
    | 
         @@ -32,6 +32,13 @@ dump_obj_str(VALUE obj, int depth, Out out) { 
     | 
|
| 
       32 
32 
     | 
    
         
             
                oj_code_attrs(obj, attrs, depth, out, Yes == out->opts->create_ok);
         
     | 
| 
       33 
33 
     | 
    
         
             
            }
         
     | 
| 
       34 
34 
     | 
    
         | 
| 
      
 35 
     | 
    
         
            +
            static void
         
     | 
| 
      
 36 
     | 
    
         
            +
            dump_obj_as_str(VALUE obj, int depth, Out out) {
         
     | 
| 
      
 37 
     | 
    
         
            +
                volatile VALUE	rstr = rb_funcall(obj, oj_to_s_id, 0);
         
     | 
| 
      
 38 
     | 
    
         
            +
                const char		*str = rb_string_value_ptr((VALUE*)&rstr);
         
     | 
| 
      
 39 
     | 
    
         
            +
             
     | 
| 
      
 40 
     | 
    
         
            +
                oj_dump_cstr(str, RSTRING_LEN(rstr), 0, 0, out);
         
     | 
| 
      
 41 
     | 
    
         
            +
            }
         
     | 
| 
       35 
42 
     | 
    
         | 
| 
       36 
43 
     | 
    
         
             
            static void
         
     | 
| 
       37 
44 
     | 
    
         
             
            bigdecimal_dump(VALUE obj, int depth, Out out) {
         
     | 
| 
         @@ -57,19 +64,23 @@ static ID	imag_id = 0; 
     | 
|
| 
       57 
64 
     | 
    
         | 
| 
       58 
65 
     | 
    
         
             
            static void
         
     | 
| 
       59 
66 
     | 
    
         
             
            complex_dump(VALUE obj, int depth, Out out) {
         
     | 
| 
       60 
     | 
    
         
            -
                 
     | 
| 
       61 
     | 
    
         
            -
            	 
     | 
| 
       62 
     | 
    
         
            -
             
     | 
| 
       63 
     | 
    
         
            -
             
     | 
| 
       64 
     | 
    
         
            -
             
     | 
| 
       65 
     | 
    
         
            -
             
     | 
| 
       66 
     | 
    
         
            -
            	 
     | 
| 
       67 
     | 
    
         
            -
             
     | 
| 
       68 
     | 
    
         
            -
             
     | 
| 
       69 
     | 
    
         
            -
             
     | 
| 
       70 
     | 
    
         
            -
             
     | 
| 
      
 67 
     | 
    
         
            +
                if (NULL != out->opts->create_id) {
         
     | 
| 
      
 68 
     | 
    
         
            +
            	struct _attr	attrs[] = {
         
     | 
| 
      
 69 
     | 
    
         
            +
            	    { "real", 4, Qnil },
         
     | 
| 
      
 70 
     | 
    
         
            +
            	    { "imag", 4, Qnil },
         
     | 
| 
      
 71 
     | 
    
         
            +
            	    { NULL, 0, Qnil },
         
     | 
| 
      
 72 
     | 
    
         
            +
            	};
         
     | 
| 
      
 73 
     | 
    
         
            +
            	if (0 == real_id) {
         
     | 
| 
      
 74 
     | 
    
         
            +
            	    real_id = rb_intern("real");
         
     | 
| 
      
 75 
     | 
    
         
            +
            	    imag_id = rb_intern("imag");
         
     | 
| 
      
 76 
     | 
    
         
            +
            	}
         
     | 
| 
      
 77 
     | 
    
         
            +
            	attrs[0].value = rb_funcall(obj, real_id, 0);
         
     | 
| 
      
 78 
     | 
    
         
            +
            	attrs[1].value = rb_funcall(obj, imag_id, 0);
         
     | 
| 
       71 
79 
     | 
    
         | 
| 
       72 
     | 
    
         
            -
             
     | 
| 
      
 80 
     | 
    
         
            +
            	oj_code_attrs(obj, attrs, depth, out, Yes == out->opts->create_ok);
         
     | 
| 
      
 81 
     | 
    
         
            +
                } else {
         
     | 
| 
      
 82 
     | 
    
         
            +
            	dump_obj_as_str(obj, depth, out);
         
     | 
| 
      
 83 
     | 
    
         
            +
                }
         
     | 
| 
       73 
84 
     | 
    
         
             
            }
         
     | 
| 
       74 
85 
     | 
    
         | 
| 
       75 
86 
     | 
    
         
             
            static VALUE
         
     | 
| 
         @@ -115,7 +126,7 @@ date_dump(VALUE obj, int depth, Out out) { 
     | 
|
| 
       115 
126 
     | 
    
         
             
                } else {
         
     | 
| 
       116 
127 
     | 
    
         
             
            	volatile VALUE	v;
         
     | 
| 
       117 
128 
     | 
    
         
             
            	volatile VALUE	ov;
         
     | 
| 
       118 
     | 
    
         
            -
             
     | 
| 
      
 129 
     | 
    
         
            +
             
     | 
| 
       119 
130 
     | 
    
         
             
            	switch (out->opts->time_format) {
         
     | 
| 
       120 
131 
     | 
    
         
             
            	case RubyTime:
         
     | 
| 
       121 
132 
     | 
    
         
             
            	case XmlTime:
         
     | 
| 
         @@ -150,7 +161,7 @@ date_dump(VALUE obj, int depth, Out out) { 
     | 
|
| 
       150 
161 
     | 
    
         
             
            static VALUE
         
     | 
| 
       151 
162 
     | 
    
         
             
            date_load(VALUE clas, VALUE args) {
         
     | 
| 
       152 
163 
     | 
    
         
             
                volatile VALUE	v;
         
     | 
| 
       153 
     | 
    
         
            -
             
     | 
| 
      
 164 
     | 
    
         
            +
             
     | 
| 
       154 
165 
     | 
    
         
             
                if (Qnil != (v = rb_hash_aref(args, rb_str_new2("s")))) {
         
     | 
| 
       155 
166 
     | 
    
         
             
            	return rb_funcall(oj_date_class, rb_intern("parse"), 1, v);
         
     | 
| 
       156 
167 
     | 
    
         
             
                }
         
     | 
| 
         @@ -160,7 +171,7 @@ date_load(VALUE clas, VALUE args) { 
     | 
|
| 
       160 
171 
     | 
    
         
             
            static VALUE
         
     | 
| 
       161 
172 
     | 
    
         
             
            datetime_load(VALUE clas, VALUE args) {
         
     | 
| 
       162 
173 
     | 
    
         
             
                volatile VALUE	v;
         
     | 
| 
       163 
     | 
    
         
            -
             
     | 
| 
      
 174 
     | 
    
         
            +
             
     | 
| 
       164 
175 
     | 
    
         
             
                if (Qnil != (v = rb_hash_aref(args, rb_str_new2("s")))) {
         
     | 
| 
       165 
176 
     | 
    
         
             
            	return rb_funcall(oj_datetime_class, rb_intern("parse"), 1, v);
         
     | 
| 
       166 
177 
     | 
    
         
             
                }
         
     | 
| 
         @@ -193,23 +204,27 @@ openstruct_load(VALUE clas, VALUE args) { 
     | 
|
| 
       193 
204 
     | 
    
         | 
| 
       194 
205 
     | 
    
         
             
            static void
         
     | 
| 
       195 
206 
     | 
    
         
             
            range_dump(VALUE obj, int depth, Out out) {
         
     | 
| 
       196 
     | 
    
         
            -
                 
     | 
| 
       197 
     | 
    
         
            -
            	 
     | 
| 
       198 
     | 
    
         
            -
             
     | 
| 
       199 
     | 
    
         
            -
             
     | 
| 
       200 
     | 
    
         
            -
             
     | 
| 
       201 
     | 
    
         
            -
             
     | 
| 
       202 
     | 
    
         
            -
             
     | 
| 
       203 
     | 
    
         
            -
             
     | 
| 
       204 
     | 
    
         
            -
             
     | 
| 
      
 207 
     | 
    
         
            +
                if (NULL != out->opts->create_id) {
         
     | 
| 
      
 208 
     | 
    
         
            +
            	struct _attr	attrs[] = {
         
     | 
| 
      
 209 
     | 
    
         
            +
            	    { "begin", 5, Qnil },
         
     | 
| 
      
 210 
     | 
    
         
            +
            	    { "end", 3, Qnil },
         
     | 
| 
      
 211 
     | 
    
         
            +
            	    { "exclude", 7, Qnil },
         
     | 
| 
      
 212 
     | 
    
         
            +
            	    { NULL, 0, Qnil },
         
     | 
| 
      
 213 
     | 
    
         
            +
            	};
         
     | 
| 
      
 214 
     | 
    
         
            +
            	attrs[0].value = rb_funcall(obj, oj_begin_id, 0);
         
     | 
| 
      
 215 
     | 
    
         
            +
            	attrs[1].value = rb_funcall(obj, oj_end_id, 0);
         
     | 
| 
      
 216 
     | 
    
         
            +
            	attrs[2].value = rb_funcall(obj, oj_exclude_end_id, 0);
         
     | 
| 
       205 
217 
     | 
    
         | 
| 
       206 
     | 
    
         
            -
             
     | 
| 
      
 218 
     | 
    
         
            +
            	oj_code_attrs(obj, attrs, depth, out, Yes == out->opts->create_ok);
         
     | 
| 
      
 219 
     | 
    
         
            +
                } else {
         
     | 
| 
      
 220 
     | 
    
         
            +
            	dump_obj_as_str(obj, depth, out);
         
     | 
| 
      
 221 
     | 
    
         
            +
                }
         
     | 
| 
       207 
222 
     | 
    
         
             
            }
         
     | 
| 
       208 
223 
     | 
    
         | 
| 
       209 
224 
     | 
    
         
             
            static VALUE
         
     | 
| 
       210 
225 
     | 
    
         
             
            range_load(VALUE clas, VALUE args) {
         
     | 
| 
       211 
226 
     | 
    
         
             
                VALUE	nargs[3];
         
     | 
| 
       212 
     | 
    
         
            -
             
     | 
| 
      
 227 
     | 
    
         
            +
             
     | 
| 
       213 
228 
     | 
    
         
             
                nargs[0] = rb_hash_aref(args, rb_id2str(oj_begin_id));
         
     | 
| 
       214 
229 
     | 
    
         
             
                nargs[1] = rb_hash_aref(args, rb_id2str(oj_end_id));
         
     | 
| 
       215 
230 
     | 
    
         
             
                nargs[2] = rb_hash_aref(args, rb_id2str(oj_exclude_end_id));
         
     | 
| 
         @@ -222,19 +237,23 @@ static ID	denominator_id = 0; 
     | 
|
| 
       222 
237 
     | 
    
         | 
| 
       223 
238 
     | 
    
         
             
            static void
         
     | 
| 
       224 
239 
     | 
    
         
             
            rational_dump(VALUE obj, int depth, Out out) {
         
     | 
| 
       225 
     | 
    
         
            -
                 
     | 
| 
       226 
     | 
    
         
            -
            	 
     | 
| 
       227 
     | 
    
         
            -
             
     | 
| 
       228 
     | 
    
         
            -
             
     | 
| 
       229 
     | 
    
         
            -
             
     | 
| 
       230 
     | 
    
         
            -
             
     | 
| 
       231 
     | 
    
         
            -
            	 
     | 
| 
       232 
     | 
    
         
            -
             
     | 
| 
       233 
     | 
    
         
            -
             
     | 
| 
       234 
     | 
    
         
            -
             
     | 
| 
       235 
     | 
    
         
            -
             
     | 
| 
      
 240 
     | 
    
         
            +
                if (NULL != out->opts->create_id) {
         
     | 
| 
      
 241 
     | 
    
         
            +
            	struct _attr	attrs[] = {
         
     | 
| 
      
 242 
     | 
    
         
            +
            	    { "numerator", 9, Qnil },
         
     | 
| 
      
 243 
     | 
    
         
            +
            	    { "denominator", 11, Qnil },
         
     | 
| 
      
 244 
     | 
    
         
            +
            	    { NULL, 0, Qnil },
         
     | 
| 
      
 245 
     | 
    
         
            +
            	};
         
     | 
| 
      
 246 
     | 
    
         
            +
            	if (0 == numerator_id) {
         
     | 
| 
      
 247 
     | 
    
         
            +
            	    numerator_id = rb_intern("numerator");
         
     | 
| 
      
 248 
     | 
    
         
            +
            	    denominator_id = rb_intern("denominator");
         
     | 
| 
      
 249 
     | 
    
         
            +
            	}
         
     | 
| 
      
 250 
     | 
    
         
            +
            	attrs[0].value = rb_funcall(obj, numerator_id, 0);
         
     | 
| 
      
 251 
     | 
    
         
            +
            	attrs[1].value = rb_funcall(obj, denominator_id, 0);
         
     | 
| 
       236 
252 
     | 
    
         | 
| 
       237 
     | 
    
         
            -
             
     | 
| 
      
 253 
     | 
    
         
            +
            	oj_code_attrs(obj, attrs, depth, out, Yes == out->opts->create_ok);
         
     | 
| 
      
 254 
     | 
    
         
            +
                } else {
         
     | 
| 
      
 255 
     | 
    
         
            +
            	dump_obj_as_str(obj, depth, out);
         
     | 
| 
      
 256 
     | 
    
         
            +
                }
         
     | 
| 
       238 
257 
     | 
    
         
             
            }
         
     | 
| 
       239 
258 
     | 
    
         | 
| 
       240 
259 
     | 
    
         
             
            static VALUE
         
     | 
| 
         @@ -250,7 +269,7 @@ rational_load(VALUE clas, VALUE args) { 
     | 
|
| 
       250 
269 
     | 
    
         
             
            static VALUE
         
     | 
| 
       251 
270 
     | 
    
         
             
            regexp_load(VALUE clas, VALUE args) {
         
     | 
| 
       252 
271 
     | 
    
         
             
                volatile VALUE	v;
         
     | 
| 
       253 
     | 
    
         
            -
             
     | 
| 
      
 272 
     | 
    
         
            +
             
     | 
| 
       254 
273 
     | 
    
         
             
                if (Qnil != (v = rb_hash_aref(args, rb_str_new2("s")))) {
         
     | 
| 
       255 
274 
     | 
    
         
             
            	return rb_funcall(rb_cRegexp, oj_new_id, 1, v);
         
     | 
| 
       256 
275 
     | 
    
         
             
                }
         
     | 
| 
         @@ -423,7 +442,7 @@ dump_odd(VALUE obj, Odd odd, VALUE clas, int depth, Out out) { 
     | 
|
| 
       423 
442 
     | 
    
         
             
            	v = rb_funcall(obj, *odd->attrs, 0);
         
     | 
| 
       424 
443 
     | 
    
         
             
            	if (Qundef == v || T_STRING != rb_type(v)) {
         
     | 
| 
       425 
444 
     | 
    
         
             
            	    rb_raise(rb_eEncodingError, "Invalid type for raw JSON.\n");
         
     | 
| 
       426 
     | 
    
         
            -
            	} else { 
     | 
| 
      
 445 
     | 
    
         
            +
            	} else {
         
     | 
| 
       427 
446 
     | 
    
         
             
            	    const char	*s = rb_string_value_ptr((VALUE*)&v);
         
     | 
| 
       428 
447 
     | 
    
         
             
            	    int		len = (int)RSTRING_LEN(v);
         
     | 
| 
       429 
448 
     | 
    
         
             
            	    const char	*name = rb_id2name(*odd->attrs);
         
     | 
| 
         @@ -459,7 +478,7 @@ dump_odd(VALUE obj, Odd odd, VALUE clas, int depth, Out out) { 
     | 
|
| 
       459 
478 
     | 
    
         
             
            		char	*n;
         
     | 
| 
       460 
479 
     | 
    
         
             
            		char	*end;
         
     | 
| 
       461 
480 
     | 
    
         
             
            		ID	i;
         
     | 
| 
       462 
     | 
    
         
            -
             
     | 
| 
      
 481 
     | 
    
         
            +
             
     | 
| 
       463 
482 
     | 
    
         
             
            		if (sizeof(nbuf) <= nlen) {
         
     | 
| 
       464 
483 
     | 
    
         
             
            		    if (NULL == (n2 = strdup(name))) {
         
     | 
| 
       465 
484 
     | 
    
         
             
            			rb_raise(rb_eNoMemError, "for attribute name.");
         
     | 
| 
         @@ -497,7 +516,10 @@ dump_odd(VALUE obj, Odd odd, VALUE clas, int depth, Out out) { 
     | 
|
| 
       497 
516 
     | 
    
         
             
            // Return class if still needs dumping.
         
     | 
| 
       498 
517 
     | 
    
         
             
            static VALUE
         
     | 
| 
       499 
518 
     | 
    
         
             
            dump_common(VALUE obj, int depth, Out out) {
         
     | 
| 
       500 
     | 
    
         
            -
             
     | 
| 
      
 519 
     | 
    
         
            +
             
     | 
| 
      
 520 
     | 
    
         
            +
                if (Yes == out->opts->raw_json && rb_respond_to(obj, oj_raw_json_id)) {
         
     | 
| 
      
 521 
     | 
    
         
            +
            	oj_dump_raw_json(obj, depth, out);
         
     | 
| 
      
 522 
     | 
    
         
            +
                } else if (Yes == out->opts->to_json && rb_respond_to(obj, oj_to_json_id)) {
         
     | 
| 
       501 
523 
     | 
    
         
             
            	volatile VALUE	rs;
         
     | 
| 
       502 
524 
     | 
    
         
             
            	const char	*s;
         
     | 
| 
       503 
525 
     | 
    
         
             
            	int		len;
         
     | 
| 
         @@ -608,7 +630,7 @@ dump_attr_cb(ID key, VALUE value, Out out) { 
     | 
|
| 
       608 
630 
     | 
    
         
             
                oj_dump_custom_val(value, depth, out, true);
         
     | 
| 
       609 
631 
     | 
    
         
             
                out->depth = depth;
         
     | 
| 
       610 
632 
     | 
    
         
             
                *out->cur++ = ',';
         
     | 
| 
       611 
     | 
    
         
            -
             
     | 
| 
      
 633 
     | 
    
         
            +
             
     | 
| 
       612 
634 
     | 
    
         
             
                return ST_CONTINUE;
         
     | 
| 
       613 
635 
     | 
    
         
             
            }
         
     | 
| 
       614 
636 
     | 
    
         | 
| 
         @@ -780,7 +802,7 @@ static void 
     | 
|
| 
       780 
802 
     | 
    
         
             
            dump_struct(VALUE obj, int depth, Out out, bool as_ok) {
         
     | 
| 
       781 
803 
     | 
    
         
             
                long	id = oj_check_circular(obj, out);
         
     | 
| 
       782 
804 
     | 
    
         
             
                VALUE	clas;
         
     | 
| 
       783 
     | 
    
         
            -
             
     | 
| 
      
 805 
     | 
    
         
            +
             
     | 
| 
       784 
806 
     | 
    
         
             
                if (0 > id) {
         
     | 
| 
       785 
807 
     | 
    
         
             
            	oj_dump_nil(Qnil, depth, out, false);
         
     | 
| 
       786 
808 
     | 
    
         
             
                } else if (Qnil != (clas = dump_common(obj, depth, out))) {
         
     | 
| 
         @@ -793,7 +815,7 @@ dump_struct(VALUE obj, int depth, Out out, bool as_ok) { 
     | 
|
| 
       793 
815 
     | 
    
         
             
            	size_t		size = d2 * out->indent + d3 * out->indent + 3;
         
     | 
| 
       794 
816 
     | 
    
         
             
            	const char	*name;
         
     | 
| 
       795 
817 
     | 
    
         
             
            	int		cnt;
         
     | 
| 
       796 
     | 
    
         
            -
            	size_t		len; 
     | 
| 
      
 818 
     | 
    
         
            +
            	size_t		len;
         
     | 
| 
       797 
819 
     | 
    
         | 
| 
       798 
820 
     | 
    
         
             
            	assure_size(out, size);
         
     | 
| 
       799 
821 
     | 
    
         
             
            	if (clas == rb_cRange) {
         
     | 
| 
         @@ -871,7 +893,11 @@ dump_data(VALUE obj, int depth, Out out, bool as_ok) { 
     | 
|
| 
       871 
893 
     | 
    
         | 
| 
       872 
894 
     | 
    
         
             
            static void
         
     | 
| 
       873 
895 
     | 
    
         
             
            dump_regexp(VALUE obj, int depth, Out out, bool as_ok) {
         
     | 
| 
       874 
     | 
    
         
            -
                 
     | 
| 
      
 896 
     | 
    
         
            +
                if (NULL != out->opts->create_id) {
         
     | 
| 
      
 897 
     | 
    
         
            +
            	dump_obj_str(obj, depth, out);
         
     | 
| 
      
 898 
     | 
    
         
            +
                } else {
         
     | 
| 
      
 899 
     | 
    
         
            +
            	dump_obj_as_str(obj, depth, out);
         
     | 
| 
      
 900 
     | 
    
         
            +
                }
         
     | 
| 
       875 
901 
     | 
    
         
             
            }
         
     | 
| 
       876 
902 
     | 
    
         | 
| 
       877 
903 
     | 
    
         
             
            static void
         
     | 
| 
         @@ -1043,7 +1069,7 @@ hash_set_num(struct _parseInfo *pi, Val kval, NumInfo ni) { 
     | 
|
| 
       1043 
1069 
     | 
    
         
             
            	oj_set_obj_ivar(parent, kval, rval);
         
     | 
| 
       1044 
1070 
     | 
    
         
             
            	break;
         
     | 
| 
       1045 
1071 
     | 
    
         
             
                case T_HASH:
         
     | 
| 
       1046 
     | 
    
         
            -
            	if (4 == parent->klen && NULL != parent->key && rb_cTime == parent->clas && 0 == strncmp("time", parent->key, 4)) {
         
     | 
| 
      
 1072 
     | 
    
         
            +
            	if (4 == parent->klen && NULL != parent->key && rb_cTime == parent->clas && 0 != ni->div && 0 == strncmp("time", parent->key, 4)) {
         
     | 
| 
       1047 
1073 
     | 
    
         
             
            	    int64_t	nsec = ni->num * 1000000000LL / ni->div;
         
     | 
| 
       1048 
1074 
     | 
    
         | 
| 
       1049 
1075 
     | 
    
         
             
            	    if (ni->neg) {
         
     | 
| 
         @@ -1113,7 +1139,7 @@ static void 
     | 
|
| 
       1113 
1139 
     | 
    
         
             
            array_append_num(ParseInfo pi, NumInfo ni) {
         
     | 
| 
       1114 
1140 
     | 
    
         
             
                Val			parent = stack_peek(&pi->stack);
         
     | 
| 
       1115 
1141 
     | 
    
         
             
                volatile VALUE	rval = oj_num_as_value(ni);
         
     | 
| 
       1116 
     | 
    
         
            -
             
     | 
| 
      
 1142 
     | 
    
         
            +
             
     | 
| 
       1117 
1143 
     | 
    
         
             
                rb_ary_push(parent->val, rval);
         
     | 
| 
       1118 
1144 
     | 
    
         
             
                if (Yes == pi->options.trace) {
         
     | 
| 
       1119 
1145 
     | 
    
         
             
            	oj_trace_parse_call("append_number", pi, __FILE__, __LINE__, rval);
         
     | 
    
        data/ext/oj/dump.c
    CHANGED
    
    | 
         @@ -15,6 +15,7 @@ 
     | 
|
| 
       15 
15 
     | 
    
         
             
            #include "cache8.h"
         
     | 
| 
       16 
16 
     | 
    
         
             
            #include "dump.h"
         
     | 
| 
       17 
17 
     | 
    
         
             
            #include "odd.h"
         
     | 
| 
      
 18 
     | 
    
         
            +
            #include "trace.h"
         
     | 
| 
       18 
19 
     | 
    
         
             
            #include "util.h"
         
     | 
| 
       19 
20 
     | 
    
         | 
| 
       20 
21 
     | 
    
         
             
            // Workaround in case INFINITY is not defined in math.h or if the OS is CentOS
         
     | 
| 
         @@ -166,7 +167,7 @@ hixss_friendly_size(const uint8_t *str, size_t len) { 
     | 
|
| 
       166 
167 
     | 
    
         
             
                size_t	size = 0;
         
     | 
| 
       167 
168 
     | 
    
         
             
                size_t	i = len;
         
     | 
| 
       168 
169 
     | 
    
         
             
                bool	check = false;
         
     | 
| 
       169 
     | 
    
         
            -
             
     | 
| 
      
 170 
     | 
    
         
            +
             
     | 
| 
       170 
171 
     | 
    
         
             
                for (; 0 < i; str++, i--) {
         
     | 
| 
       171 
172 
     | 
    
         
             
            	size += hixss_friendly_chars[*str];
         
     | 
| 
       172 
173 
     | 
    
         
             
            	if (0 != (0x80 & *str)) {
         
     | 
| 
         @@ -201,7 +202,7 @@ rails_friendly_size(const uint8_t *str, size_t len) { 
     | 
|
| 
       201 
202 
     | 
    
         
             
            const char*
         
     | 
| 
       202 
203 
     | 
    
         
             
            oj_nan_str(VALUE obj, int opt, int mode, bool plus, int *lenp) {
         
     | 
| 
       203 
204 
     | 
    
         
             
                const char	*str = NULL;
         
     | 
| 
       204 
     | 
    
         
            -
             
     | 
| 
      
 205 
     | 
    
         
            +
             
     | 
| 
       205 
206 
     | 
    
         
             
                if (AutoNan == opt) {
         
     | 
| 
       206 
207 
     | 
    
         
             
            	switch (mode) {
         
     | 
| 
       207 
208 
     | 
    
         
             
            	case CompatMode:	opt = WordNan;	break;
         
     | 
| 
         @@ -323,7 +324,7 @@ dump_unicode(const char *str, const char *end, Out out, const char *orig) { 
     | 
|
| 
       323 
324 
     | 
    
         
             
                *out->cur++ = 'u';
         
     | 
| 
       324 
325 
     | 
    
         
             
                for (i = 3; 0 <= i; i--) {
         
     | 
| 
       325 
326 
     | 
    
         
             
            	*out->cur++ = hex_chars[(uint8_t)(code >> (i * 4)) & 0x0F];
         
     | 
| 
       326 
     | 
    
         
            -
                } 
     | 
| 
      
 327 
     | 
    
         
            +
                }
         
     | 
| 
       327 
328 
     | 
    
         
             
                return str - 1;
         
     | 
| 
       328 
329 
     | 
    
         
             
            }
         
     | 
| 
       329 
330 
     | 
    
         | 
| 
         @@ -331,7 +332,7 @@ static const char* 
     | 
|
| 
       331 
332 
     | 
    
         
             
            check_unicode(const char *str, const char *end, const char *orig) {
         
     | 
| 
       332 
333 
     | 
    
         
             
                uint8_t	b = *(uint8_t*)str;
         
     | 
| 
       333 
334 
     | 
    
         
             
                int		cnt = 0;
         
     | 
| 
       334 
     | 
    
         
            -
             
     | 
| 
      
 335 
     | 
    
         
            +
             
     | 
| 
       335 
336 
     | 
    
         
             
                if (0xC0 == (0xE0 & b)) {
         
     | 
| 
       336 
337 
     | 
    
         
             
            	cnt = 1;
         
     | 
| 
       337 
338 
     | 
    
         
             
                } else if (0xE0 == (0xF0 & b)) {
         
     | 
| 
         @@ -411,7 +412,7 @@ oj_dump_time(VALUE obj, Out out, int withZone) { 
     | 
|
| 
       411 
412 
     | 
    
         
             
                sec = rb_num2ll(rb_funcall2(obj, oj_tv_sec_id, 0, 0));
         
     | 
| 
       412 
413 
     | 
    
         
             
                nsec = rb_num2ll(rb_funcall2(obj, oj_tv_nsec_id, 0, 0));
         
     | 
| 
       413 
414 
     | 
    
         
             
            #endif
         
     | 
| 
       414 
     | 
    
         
            -
             
     | 
| 
      
 415 
     | 
    
         
            +
             
     | 
| 
       415 
416 
     | 
    
         
             
                *b-- = '\0';
         
     | 
| 
       416 
417 
     | 
    
         
             
                if (withZone) {
         
     | 
| 
       417 
418 
     | 
    
         
             
            	long	tzsecs = NUM2LONG(rb_funcall2(obj, oj_utc_offset_id, 0, 0));
         
     | 
| 
         @@ -740,6 +741,30 @@ debug_raise(const char *orig, size_t cnt, int line) { 
     | 
|
| 
       740 
741 
     | 
    
         
             
                rb_raise(oj_json_generator_error_class, "Partial character in string. %s @ %d", buf, line);
         
     | 
| 
       741 
742 
     | 
    
         
             
            }
         
     | 
| 
       742 
743 
     | 
    
         | 
| 
      
 744 
     | 
    
         
            +
            void
         
     | 
| 
      
 745 
     | 
    
         
            +
            oj_dump_raw_json(VALUE obj, int depth, Out out) {
         
     | 
| 
      
 746 
     | 
    
         
            +
                if (oj_string_writer_class == rb_obj_class(obj)) {
         
     | 
| 
      
 747 
     | 
    
         
            +
            	StrWriter	sw = (StrWriter)DATA_PTR(obj);
         
     | 
| 
      
 748 
     | 
    
         
            +
            	size_t		len = sw->out.cur - sw->out.buf;
         
     | 
| 
      
 749 
     | 
    
         
            +
             
     | 
| 
      
 750 
     | 
    
         
            +
            	if (0 < len) {
         
     | 
| 
      
 751 
     | 
    
         
            +
            	    len--;
         
     | 
| 
      
 752 
     | 
    
         
            +
            	}
         
     | 
| 
      
 753 
     | 
    
         
            +
            	oj_dump_raw(sw->out.buf, len, out);
         
     | 
| 
      
 754 
     | 
    
         
            +
                } else {
         
     | 
| 
      
 755 
     | 
    
         
            +
            	volatile VALUE	jv;
         
     | 
| 
      
 756 
     | 
    
         
            +
             
     | 
| 
      
 757 
     | 
    
         
            +
            	if (Yes == out->opts->trace) {
         
     | 
| 
      
 758 
     | 
    
         
            +
            	    oj_trace("raw_json", obj, __FILE__, __LINE__, depth + 1, TraceRubyIn);
         
     | 
| 
      
 759 
     | 
    
         
            +
            	}
         
     | 
| 
      
 760 
     | 
    
         
            +
            	jv = rb_funcall(obj, oj_raw_json_id, 2, RB_INT2NUM(depth), RB_INT2NUM(out->indent));
         
     | 
| 
      
 761 
     | 
    
         
            +
            	if (Yes == out->opts->trace) {
         
     | 
| 
      
 762 
     | 
    
         
            +
            	    oj_trace("raw_json", obj, __FILE__, __LINE__, depth + 1, TraceRubyOut);
         
     | 
| 
      
 763 
     | 
    
         
            +
            	}
         
     | 
| 
      
 764 
     | 
    
         
            +
            	oj_dump_raw(rb_string_value_ptr((VALUE*)&jv), (size_t)RSTRING_LEN(jv), out);
         
     | 
| 
      
 765 
     | 
    
         
            +
                }
         
     | 
| 
      
 766 
     | 
    
         
            +
            }
         
     | 
| 
      
 767 
     | 
    
         
            +
             
     | 
| 
       743 
768 
     | 
    
         
             
            void
         
     | 
| 
       744 
769 
     | 
    
         
             
            oj_dump_cstr(const char *str, size_t cnt, bool is_sym, bool escape1, Out out) {
         
     | 
| 
       745 
770 
     | 
    
         
             
                size_t	size;
         
     | 
| 
         @@ -801,7 +826,7 @@ oj_dump_cstr(const char *str, size_t cnt, bool is_sym, bool escape1, Out out) { 
     | 
|
| 
       801 
826 
     | 
    
         
             
                } else {
         
     | 
| 
       802 
827 
     | 
    
         
             
            	const char	*end = str + cnt;
         
     | 
| 
       803 
828 
     | 
    
         
             
            	const char	*check_start = str;
         
     | 
| 
       804 
     | 
    
         
            -
             
     | 
| 
      
 829 
     | 
    
         
            +
             
     | 
| 
       805 
830 
     | 
    
         
             
            	if (is_sym) {
         
     | 
| 
       806 
831 
     | 
    
         
             
            	    *out->cur++ = ':';
         
     | 
| 
       807 
832 
     | 
    
         
             
            	}
         
     | 
| 
         @@ -867,13 +892,13 @@ oj_dump_cstr(const char *str, size_t cnt, bool is_sym, bool escape1, Out out) { 
     | 
|
| 
       867 
892 
     | 
    
         
             
            		break; // ignore, should never happen if the table is correct
         
     | 
| 
       868 
893 
     | 
    
         
             
            	    }
         
     | 
| 
       869 
894 
     | 
    
         
             
            	}
         
     | 
| 
       870 
     | 
    
         
            -
            	*out->cur++ = '"'; 
     | 
| 
      
 895 
     | 
    
         
            +
            	*out->cur++ = '"';
         
     | 
| 
       871 
896 
     | 
    
         
             
                }
         
     | 
| 
       872 
897 
     | 
    
         
             
                if ((JXEsc == out->opts->escape_mode || RailsXEsc == out->opts->escape_mode) && 0 < str - orig && 0 != (0x80 & *(str - 1))) {
         
     | 
| 
       873 
898 
     | 
    
         
             
            	uint8_t	c = (uint8_t)*(str - 1);
         
     | 
| 
       874 
899 
     | 
    
         
             
            	int	i;
         
     | 
| 
       875 
900 
     | 
    
         
             
            	int	scnt = (int)(str - orig);
         
     | 
| 
       876 
     | 
    
         
            -
             
     | 
| 
      
 901 
     | 
    
         
            +
             
     | 
| 
       877 
902 
     | 
    
         
             
            	// Last utf-8 characters must be 0x10xxxxxx. The start must be
         
     | 
| 
       878 
903 
     | 
    
         
             
            	// 0x110xxxxx for 2 characters, 0x1110xxxx for 3, and 0x11110xxx for
         
     | 
| 
       879 
904 
     | 
    
         
             
            	// 4.
         
     | 
| 
         @@ -939,7 +964,7 @@ oj_grow_out(Out out, size_t len) { 
     | 
|
| 
       939 
964 
     | 
    
         
             
                size_t  size = out->end - out->buf;
         
     | 
| 
       940 
965 
     | 
    
         
             
                long    pos = out->cur - out->buf;
         
     | 
| 
       941 
966 
     | 
    
         
             
                char    *buf = out->buf;
         
     | 
| 
       942 
     | 
    
         
            -
             
     | 
| 
      
 967 
     | 
    
         
            +
             
     | 
| 
       943 
968 
     | 
    
         
             
                size *= 2;
         
     | 
| 
       944 
969 
     | 
    
         
             
                if (size <= len * 2 + pos) {
         
     | 
| 
       945 
970 
     | 
    
         
             
            	size += len;
         
     | 
| 
         @@ -996,24 +1021,21 @@ oj_dump_fixnum(VALUE obj, int depth, Out out, bool as_ok) { 
     | 
|
| 
       996 
1021 
     | 
    
         
             
                char	*b = buf + sizeof(buf) - 1;
         
     | 
| 
       997 
1022 
     | 
    
         
             
                long long	num = rb_num2ll(obj);
         
     | 
| 
       998 
1023 
     | 
    
         
             
                int		neg = 0;
         
     | 
| 
       999 
     | 
    
         
            -
             
     | 
| 
      
 1024 
     | 
    
         
            +
                bool	dump_as_string = false;
         
     | 
| 
       1000 
1025 
     | 
    
         | 
| 
       1001 
     | 
    
         
            -
             
     | 
| 
       1002 
     | 
    
         
            -
             
     | 
| 
      
 1026 
     | 
    
         
            +
                if (out->opts->integer_range_max != 0 && out->opts->integer_range_min != 0 &&
         
     | 
| 
      
 1027 
     | 
    
         
            +
            	(out->opts->integer_range_max < num || out->opts->integer_range_min > num)) {
         
     | 
| 
       1003 
1028 
     | 
    
         
             
            	dump_as_string = true;
         
     | 
| 
       1004 
     | 
    
         
            -
             
     | 
| 
       1005 
     | 
    
         
            -
             
     | 
| 
      
 1029 
     | 
    
         
            +
                }
         
     | 
| 
       1006 
1030 
     | 
    
         
             
                if (0 > num) {
         
     | 
| 
       1007 
1031 
     | 
    
         
             
            	neg = 1;
         
     | 
| 
       1008 
1032 
     | 
    
         
             
            	num = -num;
         
     | 
| 
       1009 
1033 
     | 
    
         
             
                }
         
     | 
| 
       1010 
     | 
    
         
            -
             
     | 
| 
       1011 
1034 
     | 
    
         
             
                *b-- = '\0';
         
     | 
| 
       1012 
1035 
     | 
    
         | 
| 
       1013 
     | 
    
         
            -
             
     | 
| 
      
 1036 
     | 
    
         
            +
                if (dump_as_string) {
         
     | 
| 
       1014 
1037 
     | 
    
         
             
            	*b-- = '"';
         
     | 
| 
       1015 
     | 
    
         
            -
             
     | 
| 
       1016 
     | 
    
         
            -
             
     | 
| 
      
 1038 
     | 
    
         
            +
                }
         
     | 
| 
       1017 
1039 
     | 
    
         
             
                if (0 < num) {
         
     | 
| 
       1018 
1040 
     | 
    
         
             
            	for (; 0 < num; num /= 10, b--) {
         
     | 
| 
       1019 
1041 
     | 
    
         
             
            	    *b = (num % 10) + '0';
         
     | 
| 
         @@ -1026,11 +1048,9 @@ oj_dump_fixnum(VALUE obj, int depth, Out out, bool as_ok) { 
     | 
|
| 
       1026 
1048 
     | 
    
         
             
                } else {
         
     | 
| 
       1027 
1049 
     | 
    
         
             
            	*b = '0';
         
     | 
| 
       1028 
1050 
     | 
    
         
             
                }
         
     | 
| 
       1029 
     | 
    
         
            -
             
     | 
| 
       1030 
     | 
    
         
            -
            	if (dump_as_string) {
         
     | 
| 
      
 1051 
     | 
    
         
            +
                if (dump_as_string) {
         
     | 
| 
       1031 
1052 
     | 
    
         
             
            	*--b = '"';
         
     | 
| 
       1032 
     | 
    
         
            -
             
     | 
| 
       1033 
     | 
    
         
            -
             
     | 
| 
      
 1053 
     | 
    
         
            +
                }
         
     | 
| 
       1034 
1054 
     | 
    
         
             
                assure_size(out, (sizeof(buf) - (b - buf)));
         
     | 
| 
       1035 
1055 
     | 
    
         
             
                for (; '\0' != *b; b++) {
         
     | 
| 
       1036 
1056 
     | 
    
         
             
            	*out->cur++ = *b;
         
     | 
| 
         @@ -1045,7 +1065,7 @@ oj_dump_bignum(VALUE obj, int depth, Out out, bool as_ok) { 
     | 
|
| 
       1045 
1065 
     | 
    
         
             
            	bool		dump_as_string = false;
         
     | 
| 
       1046 
1066 
     | 
    
         | 
| 
       1047 
1067 
     | 
    
         
             
            	if (out->opts->integer_range_max != 0 || out->opts->integer_range_min != 0) { // Bignum cannot be inside of Fixnum range
         
     | 
| 
       1048 
     | 
    
         
            -
            	dump_as_string = true; 
     | 
| 
      
 1068 
     | 
    
         
            +
            	dump_as_string = true;
         
     | 
| 
       1049 
1069 
     | 
    
         
             
            	assure_size(out, cnt + 2);
         
     | 
| 
       1050 
1070 
     | 
    
         
             
            	*out->cur++ = '"';
         
     | 
| 
       1051 
1071 
     | 
    
         
             
            	} else {
         
     | 
| 
         @@ -1083,7 +1103,7 @@ oj_dump_float(VALUE obj, int depth, Out out, bool as_ok) { 
     | 
|
| 
       1083 
1103 
     | 
    
         
             
            	    cnt = sizeof(inf_val) - 1;
         
     | 
| 
       1084 
1104 
     | 
    
         
             
            	} else {
         
     | 
| 
       1085 
1105 
     | 
    
         
             
            	    NanDump	nd = out->opts->dump_opts.nan_dump;
         
     | 
| 
       1086 
     | 
    
         
            -
             
     | 
| 
      
 1106 
     | 
    
         
            +
             
     | 
| 
       1087 
1107 
     | 
    
         
             
            	    if (AutoNan == nd) {
         
     | 
| 
       1088 
1108 
     | 
    
         
             
            		switch (out->opts->mode) {
         
     | 
| 
       1089 
1109 
     | 
    
         
             
            		case CompatMode:	nd = WordNan;	break;
         
     | 
| 
         @@ -1118,7 +1138,7 @@ oj_dump_float(VALUE obj, int depth, Out out, bool as_ok) { 
     | 
|
| 
       1118 
1138 
     | 
    
         
             
            	    cnt = sizeof(ninf_val) - 1;
         
     | 
| 
       1119 
1139 
     | 
    
         
             
            	} else {
         
     | 
| 
       1120 
1140 
     | 
    
         
             
            	    NanDump	nd = out->opts->dump_opts.nan_dump;
         
     | 
| 
       1121 
     | 
    
         
            -
             
     | 
| 
      
 1141 
     | 
    
         
            +
             
     | 
| 
       1122 
1142 
     | 
    
         
             
            	    if (AutoNan == nd) {
         
     | 
| 
       1123 
1143 
     | 
    
         
             
            		switch (out->opts->mode) {
         
     | 
| 
       1124 
1144 
     | 
    
         
             
            		case CompatMode:	nd = WordNan;	break;
         
     | 
| 
         @@ -1152,7 +1172,7 @@ oj_dump_float(VALUE obj, int depth, Out out, bool as_ok) { 
     | 
|
| 
       1152 
1172 
     | 
    
         
             
            	    cnt = sizeof(ninf_val) - 1;
         
     | 
| 
       1153 
1173 
     | 
    
         
             
            	} else {
         
     | 
| 
       1154 
1174 
     | 
    
         
             
            	    NanDump	nd = out->opts->dump_opts.nan_dump;
         
     | 
| 
       1155 
     | 
    
         
            -
             
     | 
| 
      
 1175 
     | 
    
         
            +
             
     | 
| 
       1156 
1176 
     | 
    
         
             
            	    if (AutoNan == nd) {
         
     | 
| 
       1157 
1177 
     | 
    
         
             
            		switch (out->opts->mode) {
         
     | 
| 
       1158 
1178 
     | 
    
         
             
            		case ObjectMode:	nd = HugeNan;	break;
         
     |