oj 3.15.0 → 3.16.3
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/CHANGELOG.md +29 -0
 - data/ext/oj/cache.c +4 -2
 - data/ext/oj/cache.h +3 -2
 - data/ext/oj/code.c +3 -10
 - data/ext/oj/compat.c +5 -18
 - data/ext/oj/custom.c +5 -13
 - data/ext/oj/dump.c +30 -22
 - data/ext/oj/dump.h +1 -4
 - data/ext/oj/dump_compat.c +16 -16
 - data/ext/oj/extconf.rb +4 -2
 - data/ext/oj/fast.c +10 -12
 - data/ext/oj/intern.c +23 -6
 - data/ext/oj/mimic_json.c +3 -6
 - data/ext/oj/object.c +13 -5
 - data/ext/oj/oj.c +155 -132
 - data/ext/oj/oj.h +26 -33
 - data/ext/oj/parse.c +7 -5
 - data/ext/oj/parse.h +16 -14
 - data/ext/oj/parser.c +61 -50
 - data/ext/oj/parser.h +2 -2
 - data/ext/oj/rails.c +23 -7
 - data/ext/oj/reader.c +1 -3
 - data/ext/oj/saj.c +1 -1
 - data/ext/oj/stream_writer.c +35 -15
 - data/ext/oj/string_writer.c +50 -17
 - data/ext/oj/usual.c +20 -0
 - data/ext/oj/usual.h +1 -0
 - data/ext/oj/val_stack.c +13 -2
 - data/lib/oj/active_support_helper.rb +2 -3
 - data/lib/oj/json.rb +159 -149
 - data/lib/oj/mimic.rb +3 -1
 - data/lib/oj/version.rb +1 -1
 - data/test/foo.rb +3 -4
 - data/test/json_gem/json_common_interface_test.rb +4 -2
 - data/test/json_gem/json_generator_test.rb +7 -1
 - data/test/perf_dump.rb +3 -3
 - data/test/prec.rb +4 -4
 - data/test/test_compat.rb +19 -1
 - data/test/test_custom.rb +2 -1
 - data/test/test_object.rb +14 -0
 - data/test/test_parser_debug.rb +1 -1
 - data/test/test_parser_usual.rb +10 -0
 - data/test/test_strict.rb +10 -0
 - data/test/test_various.rb +6 -0
 - metadata +17 -3
 
    
        checksums.yaml
    CHANGED
    
    | 
         @@ -1,7 +1,7 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            ---
         
     | 
| 
       2 
2 
     | 
    
         
             
            SHA256:
         
     | 
| 
       3 
     | 
    
         
            -
              metadata.gz:  
     | 
| 
       4 
     | 
    
         
            -
              data.tar.gz:  
     | 
| 
      
 3 
     | 
    
         
            +
              metadata.gz: 3a6b15904386e7010fa071ecc27b8f3a6d5023c8162ea7042fc39e29c373a20a
         
     | 
| 
      
 4 
     | 
    
         
            +
              data.tar.gz: b862e59cff0ba3a15eadec34fe807d5893c9c1d1e9fcce01ced66ab28e642181
         
     | 
| 
       5 
5 
     | 
    
         
             
            SHA512:
         
     | 
| 
       6 
     | 
    
         
            -
              metadata.gz:  
     | 
| 
       7 
     | 
    
         
            -
              data.tar.gz:  
     | 
| 
      
 6 
     | 
    
         
            +
              metadata.gz: f186fb40ebcc3792b4949f81ce3b2efb22bee9dce9b44785eeca37cc27e25b79e8afa4fc5872232001d28a3d0b279fc222d5f7d2f8aaa091fe3a135246139b64
         
     | 
| 
      
 7 
     | 
    
         
            +
              data.tar.gz: 9c1536bfc15eb3fe02e92d803417ef1ccce5084036aaf8df5ae2b61995a429ab8ae00be5e9b7c79e11839d781c67523ed5bc534df36a40b59dcc61db6551158f
         
     | 
    
        data/CHANGELOG.md
    CHANGED
    
    | 
         @@ -1,5 +1,34 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            # CHANGELOG
         
     | 
| 
       2 
2 
     | 
    
         | 
| 
      
 3 
     | 
    
         
            +
            ## 3.16.3 - 2023-12-11
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
            - Fixed the gemspec to allow earlier versions of the bigdecimal gem.
         
     | 
| 
      
 6 
     | 
    
         
            +
             
     | 
| 
      
 7 
     | 
    
         
            +
            ## 3.16.2 - 2023-12-06
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
            - Fixed documentation formatting.
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
            - Added option to the "usual" parser to raise an error on an empty input string.
         
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
      
 13 
     | 
    
         
            +
            ## 3.16.1 - 2023-09-01
         
     | 
| 
      
 14 
     | 
    
         
            +
             
     | 
| 
      
 15 
     | 
    
         
            +
            - Fixed exception type on number parsing. (thank you @jasonpenny)
         
     | 
| 
      
 16 
     | 
    
         
            +
             
     | 
| 
      
 17 
     | 
    
         
            +
            ## 3.16.0 - 2023-08-16
         
     | 
| 
      
 18 
     | 
    
         
            +
             
     | 
| 
      
 19 
     | 
    
         
            +
            - Added the `float_format` option.
         
     | 
| 
      
 20 
     | 
    
         
            +
             
     | 
| 
      
 21 
     | 
    
         
            +
            - Expanded the `max_nesting` option to allow integer values as well as
         
     | 
| 
      
 22 
     | 
    
         
            +
              the previous boolean (true or nil).
         
     | 
| 
      
 23 
     | 
    
         
            +
             
     | 
| 
      
 24 
     | 
    
         
            +
            - Skip nesting tests with Truffle Ruby in the json gem tests.
         
     | 
| 
      
 25 
     | 
    
         
            +
             
     | 
| 
      
 26 
     | 
    
         
            +
            ## 3.15.1 - 2023-07-30
         
     | 
| 
      
 27 
     | 
    
         
            +
             
     | 
| 
      
 28 
     | 
    
         
            +
            - Add protection against some using `require 'oj/json`, an internal file.
         
     | 
| 
      
 29 
     | 
    
         
            +
             
     | 
| 
      
 30 
     | 
    
         
            +
            - Fixed non-json errors when in compat mode.
         
     | 
| 
      
 31 
     | 
    
         
            +
             
     | 
| 
       3 
32 
     | 
    
         
             
            ## 3.15.0 - 2023-06-02
         
     | 
| 
       4 
33 
     | 
    
         | 
| 
       5 
34 
     | 
    
         
             
            - Added `omit_null_byte` option when dumping.
         
     | 
    
        data/ext/oj/cache.c
    CHANGED
    
    | 
         @@ -260,7 +260,8 @@ void cache_set_expunge_rate(Cache c, int rate) { 
     | 
|
| 
       260 
260 
     | 
    
         
             
                c->xrate = (uint8_t)rate;
         
     | 
| 
       261 
261 
     | 
    
         
             
            }
         
     | 
| 
       262 
262 
     | 
    
         | 
| 
       263 
     | 
    
         
            -
            void cache_free( 
     | 
| 
      
 263 
     | 
    
         
            +
            void cache_free(void *data) {
         
     | 
| 
      
 264 
     | 
    
         
            +
                Cache    c = (Cache)data;
         
     | 
| 
       264 
265 
     | 
    
         
             
                uint64_t i;
         
     | 
| 
       265 
266 
     | 
    
         | 
| 
       266 
267 
     | 
    
         
             
                for (i = 0; i < c->size; i++) {
         
     | 
| 
         @@ -276,7 +277,8 @@ void cache_free(Cache c) { 
     | 
|
| 
       276 
277 
     | 
    
         
             
                OJ_FREE(c);
         
     | 
| 
       277 
278 
     | 
    
         
             
            }
         
     | 
| 
       278 
279 
     | 
    
         | 
| 
       279 
     | 
    
         
            -
            void cache_mark( 
     | 
| 
      
 280 
     | 
    
         
            +
            void cache_mark(void *data) {
         
     | 
| 
      
 281 
     | 
    
         
            +
                Cache    c = (Cache)data;
         
     | 
| 
       280 
282 
     | 
    
         
             
                uint64_t i;
         
     | 
| 
       281 
283 
     | 
    
         | 
| 
       282 
284 
     | 
    
         
             
            #if !HAVE_PTHREAD_MUTEX_INIT
         
     | 
    
        data/ext/oj/cache.h
    CHANGED
    
    | 
         @@ -10,10 +10,11 @@ 
     | 
|
| 
       10 
10 
     | 
    
         
             
            #define CACHE_MAX_KEY 35
         
     | 
| 
       11 
11 
     | 
    
         | 
| 
       12 
12 
     | 
    
         
             
            struct _cache;
         
     | 
| 
      
 13 
     | 
    
         
            +
            typedef struct _cache *Cache;
         
     | 
| 
       13 
14 
     | 
    
         | 
| 
       14 
15 
     | 
    
         
             
            extern struct _cache *cache_create(size_t size, VALUE (*form)(const char *str, size_t len), bool mark, bool locking);
         
     | 
| 
       15 
     | 
    
         
            -
            extern void           cache_free( 
     | 
| 
       16 
     | 
    
         
            -
            extern void           cache_mark( 
     | 
| 
      
 16 
     | 
    
         
            +
            extern void           cache_free(void *data);
         
     | 
| 
      
 17 
     | 
    
         
            +
            extern void           cache_mark(void *data);
         
     | 
| 
       17 
18 
     | 
    
         
             
            extern void           cache_set_form(struct _cache *c, VALUE (*form)(const char *str, size_t len));
         
     | 
| 
       18 
19 
     | 
    
         
             
            extern VALUE          cache_intern(struct _cache *c, const char *key, size_t len);
         
     | 
| 
       19 
20 
     | 
    
         
             
            extern void           cache_set_expunge_rate(struct _cache *c, int rate);
         
     | 
    
        data/ext/oj/code.c
    CHANGED
    
    | 
         @@ -185,24 +185,17 @@ void oj_code_attrs(VALUE obj, Attr attrs, int depth, Out out, bool with_class) { 
     | 
|
| 
       185 
185 
     | 
    
         
             
                        } else {
         
     | 
| 
       186 
186 
     | 
    
         
             
                            char   buf[32];
         
     | 
| 
       187 
187 
     | 
    
         
             
                            char  *b   = buf + sizeof(buf) - 1;
         
     | 
| 
       188 
     | 
    
         
            -
                             
     | 
| 
      
 188 
     | 
    
         
            +
                            bool   neg = false;
         
     | 
| 
       189 
189 
     | 
    
         
             
                            long   num = attrs->num;
         
     | 
| 
       190 
190 
     | 
    
         
             
                            size_t cnt = 0;
         
     | 
| 
       191 
191 
     | 
    
         | 
| 
       192 
192 
     | 
    
         
             
                            if (0 > num) {
         
     | 
| 
       193 
     | 
    
         
            -
                                neg =  
     | 
| 
      
 193 
     | 
    
         
            +
                                neg = true;
         
     | 
| 
       194 
194 
     | 
    
         
             
                                num = -num;
         
     | 
| 
       195 
195 
     | 
    
         
             
                            }
         
     | 
| 
       196 
196 
     | 
    
         
             
                            *b-- = '\0';
         
     | 
| 
       197 
197 
     | 
    
         
             
                            if (0 < num) {
         
     | 
| 
       198 
     | 
    
         
            -
                                 
     | 
| 
       199 
     | 
    
         
            -
                                    *b = (num % 10) + '0';
         
     | 
| 
       200 
     | 
    
         
            -
                                }
         
     | 
| 
       201 
     | 
    
         
            -
                                if (neg) {
         
     | 
| 
       202 
     | 
    
         
            -
                                    *b = '-';
         
     | 
| 
       203 
     | 
    
         
            -
                                } else {
         
     | 
| 
       204 
     | 
    
         
            -
                                    b++;
         
     | 
| 
       205 
     | 
    
         
            -
                                }
         
     | 
| 
      
 198 
     | 
    
         
            +
                                b = oj_longlong_to_string(num, neg, b);
         
     | 
| 
       206 
199 
     | 
    
         
             
                            } else {
         
     | 
| 
       207 
200 
     | 
    
         
             
                                *b = '0';
         
     | 
| 
       208 
201 
     | 
    
         
             
                            }
         
     | 
    
        data/ext/oj/compat.c
    CHANGED
    
    | 
         @@ -13,32 +13,19 @@ 
     | 
|
| 
       13 
13 
     | 
    
         
             
            #include "trace.h"
         
     | 
| 
       14 
14 
     | 
    
         | 
| 
       15 
15 
     | 
    
         
             
            static void hash_set_cstr(ParseInfo pi, Val kval, const char *str, size_t len, const char *orig) {
         
     | 
| 
       16 
     | 
    
         
            -
                const char 
     | 
| 
       17 
     | 
    
         
            -
                int 
     | 
| 
       18 
     | 
    
         
            -
                Val 
     | 
| 
       19 
     | 
    
         
            -
                volatile VALUE rkey   = kval->key_val;
         
     | 
| 
      
 16 
     | 
    
         
            +
                const char *key    = kval->key;
         
     | 
| 
      
 17 
     | 
    
         
            +
                int         klen   = kval->klen;
         
     | 
| 
      
 18 
     | 
    
         
            +
                Val         parent = stack_peek(&pi->stack);
         
     | 
| 
       20 
19 
     | 
    
         | 
| 
       21 
     | 
    
         
            -
                if (Qundef ==  
     | 
| 
      
 20 
     | 
    
         
            +
                if (Qundef == kval->key_val && Yes == pi->options.create_ok && NULL != pi->options.create_id &&
         
     | 
| 
       22 
21 
     | 
    
         
             
                    *pi->options.create_id == *key && (int)pi->options.create_id_len == klen &&
         
     | 
| 
       23 
22 
     | 
    
         
             
                    0 == strncmp(pi->options.create_id, key, klen)) {
         
     | 
| 
       24 
23 
     | 
    
         
             
                    parent->classname = oj_strndup(str, len);
         
     | 
| 
       25 
24 
     | 
    
         
             
                    parent->clen      = len;
         
     | 
| 
       26 
25 
     | 
    
         
             
                } else {
         
     | 
| 
       27 
26 
     | 
    
         
             
                    volatile VALUE rstr = oj_cstr_to_value(str, len, (size_t)pi->options.cache_str);
         
     | 
| 
      
 27 
     | 
    
         
            +
                    volatile VALUE rkey = oj_calc_hash_key(pi, kval);
         
     | 
| 
       28 
28 
     | 
    
         | 
| 
       29 
     | 
    
         
            -
                    if (Qundef == rkey) {
         
     | 
| 
       30 
     | 
    
         
            -
                        if (Yes != pi->options.cache_keys) {
         
     | 
| 
       31 
     | 
    
         
            -
                            if (Yes == pi->options.sym_key) {
         
     | 
| 
       32 
     | 
    
         
            -
                                rkey = ID2SYM(rb_intern3(key, klen, oj_utf8_encoding));
         
     | 
| 
       33 
     | 
    
         
            -
                            } else {
         
     | 
| 
       34 
     | 
    
         
            -
                                rkey = rb_utf8_str_new(key, klen);
         
     | 
| 
       35 
     | 
    
         
            -
                            }
         
     | 
| 
       36 
     | 
    
         
            -
                        } else if (Yes == pi->options.sym_key) {
         
     | 
| 
       37 
     | 
    
         
            -
                            rkey = oj_sym_intern(key, klen);
         
     | 
| 
       38 
     | 
    
         
            -
                        } else {
         
     | 
| 
       39 
     | 
    
         
            -
                            rkey = oj_str_intern(key, klen);
         
     | 
| 
       40 
     | 
    
         
            -
                        }
         
     | 
| 
       41 
     | 
    
         
            -
                    }
         
     | 
| 
       42 
29 
     | 
    
         
             
                    if (Yes == pi->options.create_ok && NULL != pi->options.str_rx.head) {
         
     | 
| 
       43 
30 
     | 
    
         
             
                        VALUE clas = oj_rxclass_match(&pi->options.str_rx, str, (int)len);
         
     | 
| 
       44 
31 
     | 
    
         | 
    
        data/ext/oj/custom.c
    CHANGED
    
    | 
         @@ -889,12 +889,11 @@ void oj_dump_custom_val(VALUE obj, int depth, Out out, bool as_ok) { 
     | 
|
| 
       889 
889 
     | 
    
         
             
            ///// load functions /////
         
     | 
| 
       890 
890 
     | 
    
         | 
| 
       891 
891 
     | 
    
         
             
            static void hash_set_cstr(ParseInfo pi, Val kval, const char *str, size_t len, const char *orig) {
         
     | 
| 
       892 
     | 
    
         
            -
                const char 
     | 
| 
       893 
     | 
    
         
            -
                int 
     | 
| 
       894 
     | 
    
         
            -
                Val 
     | 
| 
       895 
     | 
    
         
            -
                volatile VALUE rkey   = kval->key_val;
         
     | 
| 
      
 892 
     | 
    
         
            +
                const char *key    = kval->key;
         
     | 
| 
      
 893 
     | 
    
         
            +
                int         klen   = kval->klen;
         
     | 
| 
      
 894 
     | 
    
         
            +
                Val         parent = stack_peek(&pi->stack);
         
     | 
| 
       896 
895 
     | 
    
         | 
| 
       897 
     | 
    
         
            -
                if (Qundef ==  
     | 
| 
      
 896 
     | 
    
         
            +
                if (Qundef == kval->key_val && Yes == pi->options.create_ok && NULL != pi->options.create_id &&
         
     | 
| 
       898 
897 
     | 
    
         
             
                    *pi->options.create_id == *key && (int)pi->options.create_id_len == klen &&
         
     | 
| 
       899 
898 
     | 
    
         
             
                    0 == strncmp(pi->options.create_id, key, klen)) {
         
     | 
| 
       900 
899 
     | 
    
         
             
                    parent->clas = oj_name2class(pi, str, len, false, rb_eArgError);
         
     | 
| 
         @@ -907,15 +906,8 @@ static void hash_set_cstr(ParseInfo pi, Val kval, const char *str, size_t len, c 
     | 
|
| 
       907 
906 
     | 
    
         
             
                    }
         
     | 
| 
       908 
907 
     | 
    
         
             
                } else {
         
     | 
| 
       909 
908 
     | 
    
         
             
                    volatile VALUE rstr = oj_cstr_to_value(str, len, (size_t)pi->options.cache_str);
         
     | 
| 
       910 
     | 
    
         
            -
                     
     | 
| 
      
 909 
     | 
    
         
            +
                    volatile VALUE rkey = oj_calc_hash_key(pi, kval);
         
     | 
| 
       911 
910 
     | 
    
         | 
| 
       912 
     | 
    
         
            -
                    if (Qundef == rkey) {
         
     | 
| 
       913 
     | 
    
         
            -
                        if (Yes == pi->options.sym_key) {
         
     | 
| 
       914 
     | 
    
         
            -
                            rkey = ID2SYM(rb_intern3(key, klen, oj_utf8_encoding));
         
     | 
| 
       915 
     | 
    
         
            -
                        } else {
         
     | 
| 
       916 
     | 
    
         
            -
                            rkey = rb_utf8_str_new(key, klen);
         
     | 
| 
       917 
     | 
    
         
            -
                        }
         
     | 
| 
       918 
     | 
    
         
            -
                    }
         
     | 
| 
       919 
911 
     | 
    
         
             
                    if (Yes == pi->options.create_ok && NULL != pi->options.str_rx.head) {
         
     | 
| 
       920 
912 
     | 
    
         
             
                        VALUE clas = oj_rxclass_match(&pi->options.str_rx, str, (int)len);
         
     | 
| 
       921 
913 
     | 
    
         | 
    
        data/ext/oj/dump.c
    CHANGED
    
    | 
         @@ -727,8 +727,11 @@ static void debug_raise(const char *orig, size_t cnt, int line) { 
     | 
|
| 
       727 
727 
     | 
    
         | 
| 
       728 
728 
     | 
    
         
             
            void oj_dump_raw_json(VALUE obj, int depth, Out out) {
         
     | 
| 
       729 
729 
     | 
    
         
             
                if (oj_string_writer_class == rb_obj_class(obj)) {
         
     | 
| 
       730 
     | 
    
         
            -
                    StrWriter sw 
     | 
| 
       731 
     | 
    
         
            -
                    size_t    len 
     | 
| 
      
 730 
     | 
    
         
            +
                    StrWriter sw;
         
     | 
| 
      
 731 
     | 
    
         
            +
                    size_t    len;
         
     | 
| 
      
 732 
     | 
    
         
            +
             
     | 
| 
      
 733 
     | 
    
         
            +
                    sw  = oj_str_writer_unwrap(obj);
         
     | 
| 
      
 734 
     | 
    
         
            +
                    len = sw->out.cur - sw->out.buf;
         
     | 
| 
       732 
735 
     | 
    
         | 
| 
       733 
736 
     | 
    
         
             
                    if (0 < len) {
         
     | 
| 
       734 
737 
     | 
    
         
             
                        len--;
         
     | 
| 
         @@ -1010,11 +1013,33 @@ static const char digits_table[] = "\ 
     | 
|
| 
       1010 
1013 
     | 
    
         
             
            80818283848586878889\
         
     | 
| 
       1011 
1014 
     | 
    
         
             
            90919293949596979899";
         
     | 
| 
       1012 
1015 
     | 
    
         | 
| 
      
 1016 
     | 
    
         
            +
            char *oj_longlong_to_string(long long num, bool negative, char *buf) {
         
     | 
| 
      
 1017 
     | 
    
         
            +
                while (100 <= num) {
         
     | 
| 
      
 1018 
     | 
    
         
            +
                    unsigned idx = num % 100 * 2;
         
     | 
| 
      
 1019 
     | 
    
         
            +
                    *buf--       = digits_table[idx + 1];
         
     | 
| 
      
 1020 
     | 
    
         
            +
                    *buf--       = digits_table[idx];
         
     | 
| 
      
 1021 
     | 
    
         
            +
                    num /= 100;
         
     | 
| 
      
 1022 
     | 
    
         
            +
                }
         
     | 
| 
      
 1023 
     | 
    
         
            +
                if (num < 10) {
         
     | 
| 
      
 1024 
     | 
    
         
            +
                    *buf-- = num + '0';
         
     | 
| 
      
 1025 
     | 
    
         
            +
                } else {
         
     | 
| 
      
 1026 
     | 
    
         
            +
                    *buf-- = digits_table[num * 2 + 1];
         
     | 
| 
      
 1027 
     | 
    
         
            +
                    *buf-- = digits_table[num * 2];
         
     | 
| 
      
 1028 
     | 
    
         
            +
                }
         
     | 
| 
      
 1029 
     | 
    
         
            +
             
     | 
| 
      
 1030 
     | 
    
         
            +
                if (negative) {
         
     | 
| 
      
 1031 
     | 
    
         
            +
                    *buf = '-';
         
     | 
| 
      
 1032 
     | 
    
         
            +
                } else {
         
     | 
| 
      
 1033 
     | 
    
         
            +
                    buf++;
         
     | 
| 
      
 1034 
     | 
    
         
            +
                }
         
     | 
| 
      
 1035 
     | 
    
         
            +
                return buf;
         
     | 
| 
      
 1036 
     | 
    
         
            +
            }
         
     | 
| 
      
 1037 
     | 
    
         
            +
             
     | 
| 
       1013 
1038 
     | 
    
         
             
            void oj_dump_fixnum(VALUE obj, int depth, Out out, bool as_ok) {
         
     | 
| 
       1014 
1039 
     | 
    
         
             
                char      buf[32];
         
     | 
| 
       1015 
1040 
     | 
    
         
             
                char     *b              = buf + sizeof(buf) - 1;
         
     | 
| 
       1016 
1041 
     | 
    
         
             
                long long num            = NUM2LL(obj);
         
     | 
| 
       1017 
     | 
    
         
            -
                 
     | 
| 
      
 1042 
     | 
    
         
            +
                bool      neg            = false;
         
     | 
| 
       1018 
1043 
     | 
    
         
             
                size_t    cnt            = 0;
         
     | 
| 
       1019 
1044 
     | 
    
         
             
                bool      dump_as_string = false;
         
     | 
| 
       1020 
1045 
     | 
    
         | 
| 
         @@ -1023,7 +1048,7 @@ void oj_dump_fixnum(VALUE obj, int depth, Out out, bool as_ok) { 
     | 
|
| 
       1023 
1048 
     | 
    
         
             
                    dump_as_string = true;
         
     | 
| 
       1024 
1049 
     | 
    
         
             
                }
         
     | 
| 
       1025 
1050 
     | 
    
         
             
                if (0 > num) {
         
     | 
| 
       1026 
     | 
    
         
            -
                    neg =  
     | 
| 
      
 1051 
     | 
    
         
            +
                    neg = true;
         
     | 
| 
       1027 
1052 
     | 
    
         
             
                    num = -num;
         
     | 
| 
       1028 
1053 
     | 
    
         
             
                }
         
     | 
| 
       1029 
1054 
     | 
    
         
             
                *b-- = '\0';
         
     | 
| 
         @@ -1032,24 +1057,7 @@ void oj_dump_fixnum(VALUE obj, int depth, Out out, bool as_ok) { 
     | 
|
| 
       1032 
1057 
     | 
    
         
             
                    *b-- = '"';
         
     | 
| 
       1033 
1058 
     | 
    
         
             
                }
         
     | 
| 
       1034 
1059 
     | 
    
         
             
                if (0 < num) {
         
     | 
| 
       1035 
     | 
    
         
            -
                     
     | 
| 
       1036 
     | 
    
         
            -
                        unsigned idx = num % 100 * 2;
         
     | 
| 
       1037 
     | 
    
         
            -
                        *b--         = digits_table[idx + 1];
         
     | 
| 
       1038 
     | 
    
         
            -
                        *b--         = digits_table[idx];
         
     | 
| 
       1039 
     | 
    
         
            -
                        num /= 100;
         
     | 
| 
       1040 
     | 
    
         
            -
                    }
         
     | 
| 
       1041 
     | 
    
         
            -
                    if (num < 10) {
         
     | 
| 
       1042 
     | 
    
         
            -
                        *b-- = num + '0';
         
     | 
| 
       1043 
     | 
    
         
            -
                    } else {
         
     | 
| 
       1044 
     | 
    
         
            -
                        *b-- = digits_table[num * 2 + 1];
         
     | 
| 
       1045 
     | 
    
         
            -
                        *b-- = digits_table[num * 2];
         
     | 
| 
       1046 
     | 
    
         
            -
                    }
         
     | 
| 
       1047 
     | 
    
         
            -
             
     | 
| 
       1048 
     | 
    
         
            -
                    if (neg) {
         
     | 
| 
       1049 
     | 
    
         
            -
                        *b = '-';
         
     | 
| 
       1050 
     | 
    
         
            -
                    } else {
         
     | 
| 
       1051 
     | 
    
         
            -
                        b++;
         
     | 
| 
       1052 
     | 
    
         
            -
                    }
         
     | 
| 
      
 1060 
     | 
    
         
            +
                    b = oj_longlong_to_string(num, neg, b);
         
     | 
| 
       1053 
1061 
     | 
    
         
             
                } else {
         
     | 
| 
       1054 
1062 
     | 
    
         
             
                    *b = '0';
         
     | 
| 
       1055 
1063 
     | 
    
         
             
                }
         
     | 
    
        data/ext/oj/dump.h
    CHANGED
    
    | 
         @@ -93,10 +93,7 @@ inline static void dump_ulong(unsigned long num, Out out) { 
     | 
|
| 
       93 
93 
     | 
    
         | 
| 
       94 
94 
     | 
    
         
             
                *b-- = '\0';
         
     | 
| 
       95 
95 
     | 
    
         
             
                if (0 < num) {
         
     | 
| 
       96 
     | 
    
         
            -
                     
     | 
| 
       97 
     | 
    
         
            -
                        *b = (num % 10) + '0';
         
     | 
| 
       98 
     | 
    
         
            -
                    }
         
     | 
| 
       99 
     | 
    
         
            -
                    b++;
         
     | 
| 
      
 96 
     | 
    
         
            +
                    b = oj_longlong_to_string((long long)num, false, b);
         
     | 
| 
       100 
97 
     | 
    
         
             
                } else {
         
     | 
| 
       101 
98 
     | 
    
         
             
                    *b = '0';
         
     | 
| 
       102 
99 
     | 
    
         
             
                }
         
     | 
    
        data/ext/oj/dump_compat.c
    CHANGED
    
    | 
         @@ -851,13 +851,18 @@ static DumpFunc compat_funcs[] = { 
     | 
|
| 
       851 
851 
     | 
    
         
             
            };
         
     | 
| 
       852 
852 
     | 
    
         | 
| 
       853 
853 
     | 
    
         
             
            static void set_state_depth(VALUE state, int depth) {
         
     | 
| 
       854 
     | 
    
         
            -
                 
     | 
| 
       855 
     | 
    
         
            -
             
     | 
| 
       856 
     | 
    
         
            -
                 
     | 
| 
       857 
     | 
    
         
            -
                 
     | 
| 
      
 854 
     | 
    
         
            +
                if (0 == rb_const_defined(rb_cObject, rb_intern("JSON"))) {
         
     | 
| 
      
 855 
     | 
    
         
            +
                    rb_require("oj/json");
         
     | 
| 
      
 856 
     | 
    
         
            +
                }
         
     | 
| 
      
 857 
     | 
    
         
            +
                {
         
     | 
| 
      
 858 
     | 
    
         
            +
                    VALUE json_module = rb_const_get_at(rb_cObject, rb_intern("JSON"));
         
     | 
| 
      
 859 
     | 
    
         
            +
                    VALUE ext         = rb_const_get(json_module, rb_intern("Ext"));
         
     | 
| 
      
 860 
     | 
    
         
            +
                    VALUE generator   = rb_const_get(ext, rb_intern("Generator"));
         
     | 
| 
      
 861 
     | 
    
         
            +
                    VALUE state_class = rb_const_get(generator, rb_intern("State"));
         
     | 
| 
       858 
862 
     | 
    
         | 
| 
       859 
     | 
    
         
            -
             
     | 
| 
       860 
     | 
    
         
            -
             
     | 
| 
      
 863 
     | 
    
         
            +
                    if (state_class == rb_obj_class(state)) {
         
     | 
| 
      
 864 
     | 
    
         
            +
                        rb_funcall(state, rb_intern("depth="), 1, INT2NUM(depth));
         
     | 
| 
      
 865 
     | 
    
         
            +
                    }
         
     | 
| 
       861 
866 
     | 
    
         
             
                }
         
     | 
| 
       862 
867 
     | 
    
         
             
            }
         
     | 
| 
       863 
868 
     | 
    
         | 
| 
         @@ -865,20 +870,15 @@ void oj_dump_compat_val(VALUE obj, int depth, Out out, bool as_ok) { 
     | 
|
| 
       865 
870 
     | 
    
         
             
                int type = rb_type(obj);
         
     | 
| 
       866 
871 
     | 
    
         | 
| 
       867 
872 
     | 
    
         
             
                TRACE(out->opts->trace, "dump", obj, depth, TraceIn);
         
     | 
| 
      
 873 
     | 
    
         
            +
                // The max_nesting logic is that an empty Array or Hash is assumed to have
         
     | 
| 
      
 874 
     | 
    
         
            +
                // content so the max_nesting should fail but a non-collection value is
         
     | 
| 
      
 875 
     | 
    
         
            +
                // okay. That means a check for a collectable value is needed before
         
     | 
| 
      
 876 
     | 
    
         
            +
                // raising.
         
     | 
| 
       868 
877 
     | 
    
         
             
                if (out->opts->dump_opts.max_depth <= depth) {
         
     | 
| 
       869 
     | 
    
         
            -
                     
     | 
| 
       870 
     | 
    
         
            -
                    // limit is the depth inclusive. If JSON.generate is called then a
         
     | 
| 
       871 
     | 
    
         
            -
                    // NestingError is expected and the limit is inclusive. Worse than
         
     | 
| 
       872 
     | 
    
         
            -
                    // that there are unit tests for both.
         
     | 
| 
       873 
     | 
    
         
            -
                    if (CALLER_DUMP == out->caller) {
         
     | 
| 
      
 878 
     | 
    
         
            +
                    if (RUBY_T_ARRAY == type || RUBY_T_HASH == type) {
         
     | 
| 
       874 
879 
     | 
    
         
             
                        if (0 < out->argc) {
         
     | 
| 
       875 
880 
     | 
    
         
             
                            set_state_depth(*out->argv, depth);
         
     | 
| 
       876 
881 
     | 
    
         
             
                        }
         
     | 
| 
       877 
     | 
    
         
            -
                        rb_raise(rb_eArgError, "Too deeply nested.");
         
     | 
| 
       878 
     | 
    
         
            -
                    } else if (out->opts->dump_opts.max_depth < depth) {
         
     | 
| 
       879 
     | 
    
         
            -
                        if (0 < out->argc) {
         
     | 
| 
       880 
     | 
    
         
            -
                            set_state_depth(*out->argv, depth - 1);
         
     | 
| 
       881 
     | 
    
         
            -
                        }
         
     | 
| 
       882 
882 
     | 
    
         
             
                        raise_json_err("Too deeply nested", "NestingError");
         
     | 
| 
       883 
883 
     | 
    
         
             
                    }
         
     | 
| 
       884 
884 
     | 
    
         
             
                }
         
     | 
    
        data/ext/oj/extconf.rb
    CHANGED
    
    | 
         @@ -1,3 +1,5 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
       1 
3 
     | 
    
         
             
            require 'mkmf'
         
     | 
| 
       2 
4 
     | 
    
         
             
            require 'rbconfig'
         
     | 
| 
       3 
5 
     | 
    
         | 
| 
         @@ -6,7 +8,7 @@ dir_config(extension_name) 
     | 
|
| 
       6 
8 
     | 
    
         | 
| 
       7 
9 
     | 
    
         
             
            parts = RUBY_DESCRIPTION.split(' ')
         
     | 
| 
       8 
10 
     | 
    
         
             
            type = parts[0]
         
     | 
| 
       9 
     | 
    
         
            -
            type = type[4 
     | 
| 
      
 11 
     | 
    
         
            +
            type = type[4..] if type.start_with?('tcs-')
         
     | 
| 
       10 
12 
     | 
    
         
             
            is_windows = RbConfig::CONFIG['host_os'] =~ /(mingw|mswin)/
         
     | 
| 
       11 
13 
     | 
    
         
             
            platform = RUBY_PLATFORM
         
     | 
| 
       12 
14 
     | 
    
         
             
            version = RUBY_VERSION.split('.')
         
     | 
| 
         @@ -56,7 +58,7 @@ dflags.each do |k, v| 
     | 
|
| 
       56 
58 
     | 
    
         
             
            end
         
     | 
| 
       57 
59 
     | 
    
         | 
| 
       58 
60 
     | 
    
         
             
            $CPPFLAGS += ' -Wall'
         
     | 
| 
       59 
     | 
    
         
            -
            #puts "*** $CPPFLAGS: #{$CPPFLAGS}"
         
     | 
| 
      
 61 
     | 
    
         
            +
            # puts "*** $CPPFLAGS: #{$CPPFLAGS}"
         
     | 
| 
       60 
62 
     | 
    
         
             
            # Adding the __attribute__ flag only works with gcc compilers and even then it
         
     | 
| 
       61 
63 
     | 
    
         
             
            # does not work to check args with varargs so just remove the check.
         
     | 
| 
       62 
64 
     | 
    
         
             
            CONFIG['warnflags'].slice!(/ -Wsuggest-attribute=format/)
         
     | 
    
        data/ext/oj/fast.c
    CHANGED
    
    | 
         @@ -40,7 +40,7 @@ typedef struct _doc { 
     | 
|
| 
       40 
40 
     | 
    
         
             
                Leaf         *where;                  // points to current location
         
     | 
| 
       41 
41 
     | 
    
         
             
                Leaf          where_path[MAX_STACK];  // points to head of path
         
     | 
| 
       42 
42 
     | 
    
         
             
                char         *json;
         
     | 
| 
       43 
     | 
    
         
            -
                unsigned long size; 
     | 
| 
      
 43 
     | 
    
         
            +
                unsigned long size;                   // number of leaves/branches in the doc
         
     | 
| 
       44 
44 
     | 
    
         
             
                VALUE         self;
         
     | 
| 
       45 
45 
     | 
    
         
             
                Batch         batches;
         
     | 
| 
       46 
46 
     | 
    
         
             
                struct _batch batch0;
         
     | 
| 
         @@ -114,10 +114,7 @@ inline static char *ulong_fill(char *s, size_t num) { 
     | 
|
| 
       114 
114 
     | 
    
         
             
                char *b = buf + sizeof(buf) - 1;
         
     | 
| 
       115 
115 
     | 
    
         | 
| 
       116 
116 
     | 
    
         
             
                *b-- = '\0';
         
     | 
| 
       117 
     | 
    
         
            -
                 
     | 
| 
       118 
     | 
    
         
            -
                    *b = (num % 10) + '0';
         
     | 
| 
       119 
     | 
    
         
            -
                }
         
     | 
| 
       120 
     | 
    
         
            -
                b++;
         
     | 
| 
      
 117 
     | 
    
         
            +
                b    = oj_longlong_to_string((long long)num, false, b);
         
     | 
| 
       121 
118 
     | 
    
         
             
                if ('\0' == *b) {
         
     | 
| 
       122 
119 
     | 
    
         
             
                    b--;
         
     | 
| 
       123 
120 
     | 
    
         
             
                    *b = '0';
         
     | 
| 
         @@ -576,7 +573,7 @@ static char *read_quoted_value(ParseInfo pi) { 
     | 
|
| 
       576 
573 
     | 
    
         
             
                char *h     = pi->s;  // head
         
     | 
| 
       577 
574 
     | 
    
         
             
                char *t     = h;      // tail
         
     | 
| 
       578 
575 
     | 
    
         | 
| 
       579 
     | 
    
         
            -
                h++; 
     | 
| 
      
 576 
     | 
    
         
            +
                h++;                  // skip quote character
         
     | 
| 
       580 
577 
     | 
    
         
             
                t++;
         
     | 
| 
       581 
578 
     | 
    
         
             
                value = h;
         
     | 
| 
       582 
579 
     | 
    
         
             
                for (; '"' != *h; h++, t++) {
         
     | 
| 
         @@ -783,11 +780,10 @@ static VALUE parse_json(VALUE clas, char *json, bool given) { 
     | 
|
| 
       783 
780 
     | 
    
         
             
                    }
         
     | 
| 
       784 
781 
     | 
    
         
             
                }
         
     | 
| 
       785 
782 
     | 
    
         
             
            #endif
         
     | 
| 
       786 
     | 
    
         
            -
                doc->json 
     | 
| 
       787 
     | 
    
         
            -
                self 
     | 
| 
       788 
     | 
    
         
            -
                doc->self 
     | 
| 
       789 
     | 
    
         
            -
                 
     | 
| 
       790 
     | 
    
         
            -
                result              = rb_protect(protect_open_proc, (VALUE)&pi, &ex);
         
     | 
| 
      
 783 
     | 
    
         
            +
                doc->json = json;
         
     | 
| 
      
 784 
     | 
    
         
            +
                self      = TypedData_Wrap_Struct(clas, &oj_doc_type, doc);
         
     | 
| 
      
 785 
     | 
    
         
            +
                doc->self = self;
         
     | 
| 
      
 786 
     | 
    
         
            +
                result    = rb_protect(protect_open_proc, (VALUE)&pi, &ex);
         
     | 
| 
       791 
787 
     | 
    
         
             
                if (given || 0 != ex) {
         
     | 
| 
       792 
788 
     | 
    
         
             
                    DATA_PTR(doc->self) = NULL;
         
     | 
| 
       793 
789 
     | 
    
         
             
                    // TBD is this needed?
         
     | 
| 
         @@ -1612,7 +1608,9 @@ static VALUE doc_dump(int argc, VALUE *argv, VALUE self) { 
     | 
|
| 
       1612 
1608 
     | 
    
         
             
             *   Oj::Doc.open('[1,2,3]') { |doc| doc.size() }  #=> 4
         
     | 
| 
       1613 
1609 
     | 
    
         
             
             */
         
     | 
| 
       1614 
1610 
     | 
    
         
             
            static VALUE doc_size(VALUE self) {
         
     | 
| 
       1615 
     | 
    
         
            -
                 
     | 
| 
      
 1611 
     | 
    
         
            +
                Doc d;
         
     | 
| 
      
 1612 
     | 
    
         
            +
                TypedData_Get_Struct(self, struct _doc, &oj_doc_type, d);
         
     | 
| 
      
 1613 
     | 
    
         
            +
                return ULONG2NUM(d->size);
         
     | 
| 
       1616 
1614 
     | 
    
         
             
            }
         
     | 
| 
       1617 
1615 
     | 
    
         | 
| 
       1618 
1616 
     | 
    
         
             
            /* @overload close() => nil
         
     | 
    
        data/ext/oj/intern.c
    CHANGED
    
    | 
         @@ -85,20 +85,31 @@ static VALUE form_attr(const char *str, size_t len) { 
     | 
|
| 
       85 
85 
     | 
    
         
             
                return (VALUE)rb_intern3(buf, len + 1, oj_utf8_encoding);
         
     | 
| 
       86 
86 
     | 
    
         
             
            }
         
     | 
| 
       87 
87 
     | 
    
         | 
| 
      
 88 
     | 
    
         
            +
            static const rb_data_type_t oj_cache_type = {
         
     | 
| 
      
 89 
     | 
    
         
            +
                "Oj/cache",
         
     | 
| 
      
 90 
     | 
    
         
            +
                {
         
     | 
| 
      
 91 
     | 
    
         
            +
                    cache_mark,
         
     | 
| 
      
 92 
     | 
    
         
            +
                    cache_free,
         
     | 
| 
      
 93 
     | 
    
         
            +
                    NULL,
         
     | 
| 
      
 94 
     | 
    
         
            +
                },
         
     | 
| 
      
 95 
     | 
    
         
            +
                0,
         
     | 
| 
      
 96 
     | 
    
         
            +
                0,
         
     | 
| 
      
 97 
     | 
    
         
            +
            };
         
     | 
| 
      
 98 
     | 
    
         
            +
             
     | 
| 
       88 
99 
     | 
    
         
             
            void oj_hash_init(void) {
         
     | 
| 
       89 
100 
     | 
    
         
             
                VALUE cache_class = rb_define_class_under(Oj, "Cache", rb_cObject);
         
     | 
| 
       90 
101 
     | 
    
         
             
                rb_undef_alloc_func(cache_class);
         
     | 
| 
       91 
102 
     | 
    
         | 
| 
       92 
103 
     | 
    
         
             
                struct _cache *str_cache = cache_create(0, form_str, true, true);
         
     | 
| 
       93 
     | 
    
         
            -
                str_cache_obj            =  
     | 
| 
      
 104 
     | 
    
         
            +
                str_cache_obj            = TypedData_Wrap_Struct(cache_class, &oj_cache_type, str_cache);
         
     | 
| 
       94 
105 
     | 
    
         
             
                rb_gc_register_address(&str_cache_obj);
         
     | 
| 
       95 
106 
     | 
    
         | 
| 
       96 
107 
     | 
    
         
             
                struct _cache *sym_cache = cache_create(0, form_sym, true, true);
         
     | 
| 
       97 
     | 
    
         
            -
                sym_cache_obj            =  
     | 
| 
      
 108 
     | 
    
         
            +
                sym_cache_obj            = TypedData_Wrap_Struct(cache_class, &oj_cache_type, sym_cache);
         
     | 
| 
       98 
109 
     | 
    
         
             
                rb_gc_register_address(&sym_cache_obj);
         
     | 
| 
       99 
110 
     | 
    
         | 
| 
       100 
111 
     | 
    
         
             
                struct _cache *attr_cache = cache_create(0, form_attr, false, true);
         
     | 
| 
       101 
     | 
    
         
            -
                attr_cache_obj            =  
     | 
| 
      
 112 
     | 
    
         
            +
                attr_cache_obj            = TypedData_Wrap_Struct(cache_class, &oj_cache_type, attr_cache);
         
     | 
| 
       102 
113 
     | 
    
         
             
                rb_gc_register_address(&attr_cache_obj);
         
     | 
| 
       103 
114 
     | 
    
         | 
| 
       104 
115 
     | 
    
         
             
                memset(class_hash.slots, 0, sizeof(class_hash.slots));
         
     | 
| 
         @@ -118,17 +129,23 @@ oj_str_intern(const char *key, size_t len) { 
     | 
|
| 
       118 
129 
     | 
    
         
             
            #if HAVE_RB_ENC_INTERNED_STR && 0
         
     | 
| 
       119 
130 
     | 
    
         
             
                return rb_enc_interned_str(key, len, rb_utf8_encoding());
         
     | 
| 
       120 
131 
     | 
    
         
             
            #else
         
     | 
| 
       121 
     | 
    
         
            -
                 
     | 
| 
      
 132 
     | 
    
         
            +
                Cache c;
         
     | 
| 
      
 133 
     | 
    
         
            +
                TypedData_Get_Struct(str_cache_obj, struct _cache, &oj_cache_type, c);
         
     | 
| 
      
 134 
     | 
    
         
            +
                return cache_intern(c, key, len);
         
     | 
| 
       122 
135 
     | 
    
         
             
            #endif
         
     | 
| 
       123 
136 
     | 
    
         
             
            }
         
     | 
| 
       124 
137 
     | 
    
         | 
| 
       125 
138 
     | 
    
         
             
            VALUE
         
     | 
| 
       126 
139 
     | 
    
         
             
            oj_sym_intern(const char *key, size_t len) {
         
     | 
| 
       127 
     | 
    
         
            -
                 
     | 
| 
      
 140 
     | 
    
         
            +
                Cache c;
         
     | 
| 
      
 141 
     | 
    
         
            +
                TypedData_Get_Struct(sym_cache_obj, struct _cache, &oj_cache_type, c);
         
     | 
| 
      
 142 
     | 
    
         
            +
                return cache_intern(c, key, len);
         
     | 
| 
       128 
143 
     | 
    
         
             
            }
         
     | 
| 
       129 
144 
     | 
    
         | 
| 
       130 
145 
     | 
    
         
             
            ID oj_attr_intern(const char *key, size_t len) {
         
     | 
| 
       131 
     | 
    
         
            -
                 
     | 
| 
      
 146 
     | 
    
         
            +
                Cache c;
         
     | 
| 
      
 147 
     | 
    
         
            +
                TypedData_Get_Struct(attr_cache_obj, struct _cache, &oj_cache_type, c);
         
     | 
| 
      
 148 
     | 
    
         
            +
                return cache_intern(c, key, len);
         
     | 
| 
       132 
149 
     | 
    
         
             
            }
         
     | 
| 
       133 
150 
     | 
    
         | 
| 
       134 
151 
     | 
    
         
             
            static uint64_t hash_calc(const uint8_t *key, size_t len) {
         
     | 
    
        data/ext/oj/mimic_json.c
    CHANGED
    
    | 
         @@ -209,7 +209,6 @@ static VALUE mimic_dump(int argc, VALUE *argv, VALUE self) { 
     | 
|
| 
       209 
209 
     | 
    
         | 
| 
       210 
210 
     | 
    
         
             
                oj_out_init(&out);
         
     | 
| 
       211 
211 
     | 
    
         | 
| 
       212 
     | 
    
         
            -
                out.caller        = CALLER_DUMP;
         
     | 
| 
       213 
212 
     | 
    
         
             
                copts.escape_mode = JXEsc;
         
     | 
| 
       214 
213 
     | 
    
         
             
                copts.mode        = CompatMode;
         
     | 
| 
       215 
214 
     | 
    
         | 
| 
         @@ -368,7 +367,6 @@ static VALUE mimic_generate_core(int argc, VALUE *argv, Options copts) { 
     | 
|
| 
       368 
367 
     | 
    
         
             
                oj_out_init(&out);
         
     | 
| 
       369 
368 
     | 
    
         | 
| 
       370 
369 
     | 
    
         
             
                out.omit_nil = copts->dump_opts.omit_nil;
         
     | 
| 
       371 
     | 
    
         
            -
                out.caller   = CALLER_GENERATE;
         
     | 
| 
       372 
370 
     | 
    
         
             
                // For obj.to_json or generate nan is not allowed but if called from dump
         
     | 
| 
       373 
371 
     | 
    
         
             
                // it is.
         
     | 
| 
       374 
372 
     | 
    
         
             
                copts->dump_opts.nan_dump = RaiseNan;
         
     | 
| 
         @@ -427,7 +425,7 @@ static VALUE mimic_generate_core(int argc, VALUE *argv, Options copts) { 
     | 
|
| 
       427 
425 
     | 
    
         
             
             *   - *:object_nl* [_String_] String placed after a JSON object
         
     | 
| 
       428 
426 
     | 
    
         
             
             *   - *:array_nl* [_String_] String placed after a JSON array
         
     | 
| 
       429 
427 
     | 
    
         
             
             *   - *:ascii_only* [_Boolean_] if not nil or false then use only ascii characters in the output.
         
     | 
| 
       430 
     | 
    
         
            -
             * 
     | 
| 
      
 428 
     | 
    
         
            +
             *     Note JSON.generate does support this even if it is not documented.
         
     | 
| 
       431 
429 
     | 
    
         
             
             *
         
     | 
| 
       432 
430 
     | 
    
         
             
             * Returns [_String_] generated JSON.
         
     | 
| 
       433 
431 
     | 
    
         
             
             */
         
     | 
| 
         @@ -574,7 +572,6 @@ static VALUE mimic_parse_core(int argc, VALUE *argv, VALUE self, bool bang) { 
     | 
|
| 
       574 
572 
     | 
    
         
             
                    if (T_HASH != rb_type(ropts)) {
         
     | 
| 
       575 
573 
     | 
    
         
             
                        rb_raise(rb_eArgError, "options must be a hash.");
         
     | 
| 
       576 
574 
     | 
    
         
             
                    }
         
     | 
| 
       577 
     | 
    
         
            -
             
     | 
| 
       578 
575 
     | 
    
         
             
                    rb_hash_foreach(ropts, parse_options_cb, (VALUE)&pi);
         
     | 
| 
       579 
576 
     | 
    
         
             
                    v = rb_hash_lookup(ropts, oj_max_nesting_sym);
         
     | 
| 
       580 
577 
     | 
    
         
             
                    if (Qtrue == v) {
         
     | 
| 
         @@ -608,9 +605,9 @@ static VALUE mimic_parse_core(int argc, VALUE *argv, VALUE self, bool bang) { 
     | 
|
| 
       608 
605 
     | 
    
         
             
             * - *source* [_String_|IO] source to parse
         
     | 
| 
       609 
606 
     | 
    
         
             
             * - *opts* [_Hash_] options
         
     | 
| 
       610 
607 
     | 
    
         
             
             *   - *:symbolize* [Boolean] _names flag indicating JSON object keys should be Symbols instead of
         
     | 
| 
       611 
     | 
    
         
            -
             * 
     | 
| 
      
 608 
     | 
    
         
            +
             *     Strings
         
     | 
| 
       612 
609 
     | 
    
         
             
             *   - *:create_additions* [Boolean] flag indicating a key matching +create_id+ in a JSON object
         
     | 
| 
       613 
     | 
    
         
            -
             * 
     | 
| 
      
 610 
     | 
    
         
            +
             *     should trigger the creation of Ruby Object
         
     | 
| 
       614 
611 
     | 
    
         
             
             *
         
     | 
| 
       615 
612 
     | 
    
         
             
             * Returns [Object]
         
     | 
| 
       616 
613 
     | 
    
         
             
             * @see create_id=
         
     | 
    
        data/ext/oj/object.c
    CHANGED
    
    | 
         @@ -83,8 +83,9 @@ static int parse_num(const char *str, const char *end, int cnt) { 
     | 
|
| 
       83 
83 
     | 
    
         | 
| 
       84 
84 
     | 
    
         
             
            VALUE
         
     | 
| 
       85 
85 
     | 
    
         
             
            oj_parse_xml_time(const char *str, int len) {
         
     | 
| 
       86 
     | 
    
         
            -
                VALUE       args[ 
     | 
| 
       87 
     | 
    
         
            -
                const char *end 
     | 
| 
      
 86 
     | 
    
         
            +
                VALUE       args[7];
         
     | 
| 
      
 87 
     | 
    
         
            +
                const char *end  = str + len;
         
     | 
| 
      
 88 
     | 
    
         
            +
                const char *orig = str;
         
     | 
| 
       88 
89 
     | 
    
         
             
                int         n;
         
     | 
| 
       89 
90 
     | 
    
         | 
| 
       90 
91 
     | 
    
         
             
                // year
         
     | 
| 
         @@ -144,7 +145,9 @@ oj_parse_xml_time(const char *str, int len) { 
     | 
|
| 
       144 
145 
     | 
    
         
             
                    char c = *str++;
         
     | 
| 
       145 
146 
     | 
    
         | 
| 
       146 
147 
     | 
    
         
             
                    if ('.' == c) {
         
     | 
| 
       147 
     | 
    
         
            -
                        long long 
     | 
| 
      
 148 
     | 
    
         
            +
                        unsigned long long       num            = 0;
         
     | 
| 
      
 149 
     | 
    
         
            +
                        unsigned long long       den            = 1;
         
     | 
| 
      
 150 
     | 
    
         
            +
                        const unsigned long long last_den_limit = ULLONG_MAX / 10;
         
     | 
| 
       148 
151 
     | 
    
         | 
| 
       149 
152 
     | 
    
         
             
                        for (; str < end; str++) {
         
     | 
| 
       150 
153 
     | 
    
         
             
                            c = *str;
         
     | 
| 
         @@ -152,9 +155,14 @@ oj_parse_xml_time(const char *str, int len) { 
     | 
|
| 
       152 
155 
     | 
    
         
             
                                str++;
         
     | 
| 
       153 
156 
     | 
    
         
             
                                break;
         
     | 
| 
       154 
157 
     | 
    
         
             
                            }
         
     | 
| 
       155 
     | 
    
         
            -
                             
     | 
| 
      
 158 
     | 
    
         
            +
                            if (den > last_den_limit) {
         
     | 
| 
      
 159 
     | 
    
         
            +
                                // bail to Time.parse if there are more fractional digits than a ULLONG rational can hold
         
     | 
| 
      
 160 
     | 
    
         
            +
                                return rb_funcall(rb_cTime, oj_parse_id, 1, rb_str_new(orig, len));
         
     | 
| 
      
 161 
     | 
    
         
            +
                            }
         
     | 
| 
      
 162 
     | 
    
         
            +
                            num = num * 10 + (c - '0');
         
     | 
| 
      
 163 
     | 
    
         
            +
                            den *= 10;
         
     | 
| 
       156 
164 
     | 
    
         
             
                        }
         
     | 
| 
       157 
     | 
    
         
            -
                        args[5] =  
     | 
| 
      
 165 
     | 
    
         
            +
                        args[5] = rb_funcall(INT2NUM(n), oj_plus_id, 1, rb_rational_new(ULL2NUM(num), ULL2NUM(den)));
         
     | 
| 
       158 
166 
     | 
    
         
             
                    } else {
         
     | 
| 
       159 
167 
     | 
    
         
             
                        args[5] = rb_ll2inum(n);
         
     | 
| 
       160 
168 
     | 
    
         
             
                    }
         
     |