oj 3.13.11 → 3.13.23
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 +50 -0
- data/README.md +2 -0
- data/ext/oj/buf.h +4 -0
- data/ext/oj/circarray.c +1 -1
- data/ext/oj/code.c +15 -22
- data/ext/oj/compat.c +10 -10
- data/ext/oj/custom.c +62 -108
- data/ext/oj/dump.c +85 -97
- data/ext/oj/dump.h +12 -8
- data/ext/oj/dump_compat.c +46 -88
- data/ext/oj/dump_leaf.c +14 -58
- data/ext/oj/dump_object.c +33 -156
- data/ext/oj/dump_strict.c +17 -29
- data/ext/oj/extconf.rb +5 -4
- data/ext/oj/fast.c +24 -22
- data/ext/oj/intern.c +15 -11
- data/ext/oj/intern.h +1 -1
- data/ext/oj/mimic_json.c +44 -32
- data/ext/oj/object.c +42 -41
- data/ext/oj/odd.c +83 -63
- data/ext/oj/odd.h +13 -13
- data/ext/oj/oj.c +57 -22
- data/ext/oj/oj.h +24 -3
- data/ext/oj/parse.c +114 -78
- data/ext/oj/parse.h +2 -0
- data/ext/oj/parser.c +77 -21
- data/ext/oj/parser.h +12 -0
- data/ext/oj/rails.c +41 -65
- data/ext/oj/rails.h +1 -1
- data/ext/oj/reader.c +2 -0
- data/ext/oj/saj.c +11 -23
- data/ext/oj/saj2.c +333 -85
- data/ext/oj/saj2.h +23 -0
- data/ext/oj/sparse.c +4 -0
- data/ext/oj/stream_writer.c +3 -1
- data/ext/oj/strict.c +13 -13
- data/ext/oj/string_writer.c +12 -5
- data/ext/oj/usual.c +82 -129
- data/ext/oj/usual.h +68 -0
- data/ext/oj/val_stack.c +1 -1
- data/ext/oj/validate.c +21 -26
- data/ext/oj/wab.c +21 -26
- data/lib/oj/saj.rb +20 -6
- data/lib/oj/state.rb +1 -1
- data/lib/oj/version.rb +1 -1
- data/pages/Compatibility.md +1 -1
- data/pages/Options.md +6 -0
- data/test/activesupport7/abstract_unit.rb +49 -0
- data/test/activesupport7/decoding_test.rb +125 -0
- data/test/activesupport7/encoding_test.rb +486 -0
- data/test/activesupport7/encoding_test_cases.rb +104 -0
- data/test/activesupport7/time_zone_test_helpers.rb +47 -0
- data/test/bar.rb +3 -8
- data/test/foo.rb +3 -3
- data/test/helper.rb +8 -2
- data/test/json_gem/json_generator_test.rb +5 -4
- data/test/json_gem/json_parser_test.rb +8 -1
- data/test/json_gem/test_helper.rb +7 -3
- data/test/perf_dump.rb +50 -0
- data/test/test_compat.rb +25 -0
- data/test/test_custom.rb +13 -2
- data/test/test_file.rb +23 -7
- data/test/test_gc.rb +11 -0
- data/test/test_object.rb +8 -10
- data/test/test_parser.rb +3 -19
- data/test/test_parser_debug.rb +27 -0
- data/test/test_parser_saj.rb +92 -2
- data/test/test_scp.rb +2 -4
- data/test/test_strict.rb +2 -0
- data/test/test_various.rb +8 -3
- data/test/test_wab.rb +2 -0
- data/test/tests.rb +9 -0
- data/test/tests_mimic.rb +9 -0
- data/test/tests_mimic_addition.rb +9 -0
- metadata +13 -116
    
        data/ext/oj/odd.c
    CHANGED
    
    | @@ -5,28 +5,27 @@ | |
| 5 5 |  | 
| 6 6 | 
             
            #include <string.h>
         | 
| 7 7 |  | 
| 8 | 
            -
            static  | 
| 9 | 
            -
            static  | 
| 10 | 
            -
            static  | 
| 11 | 
            -
            static ID | 
| 12 | 
            -
            static ID | 
| 13 | 
            -
            static ID | 
| 14 | 
            -
            static ID | 
| 15 | 
            -
            static ID           denominator_id;
         | 
| 16 | 
            -
            static ID           rational_id;
         | 
| 17 | 
            -
            static VALUE        rational_class;
         | 
| 8 | 
            +
            static Odd odds = NULL;
         | 
| 9 | 
            +
            static ID  sec_id;
         | 
| 10 | 
            +
            static ID  sec_fraction_id;
         | 
| 11 | 
            +
            static ID  to_f_id;
         | 
| 12 | 
            +
            static ID  numerator_id;
         | 
| 13 | 
            +
            static ID  denominator_id;
         | 
| 14 | 
            +
            static ID  rational_id;
         | 
| 18 15 |  | 
| 19 16 | 
             
            static void set_class(Odd odd, const char *classname) {
         | 
| 20 17 | 
             
                const char **np;
         | 
| 21 | 
            -
                ID | 
| 18 | 
            +
                ID          *idp;
         | 
| 22 19 |  | 
| 23 | 
            -
                odd->classname | 
| 24 | 
            -
                odd->clen | 
| 25 | 
            -
                odd->clas | 
| 20 | 
            +
                odd->classname = classname;
         | 
| 21 | 
            +
                odd->clen      = strlen(classname);
         | 
| 22 | 
            +
                odd->clas      = rb_const_get(rb_cObject, rb_intern(classname));
         | 
| 23 | 
            +
                rb_gc_register_mark_object(odd->clas);
         | 
| 26 24 | 
             
                odd->create_obj = odd->clas;
         | 
| 27 | 
            -
                odd-> | 
| 28 | 
            -
                odd-> | 
| 29 | 
            -
                odd-> | 
| 25 | 
            +
                rb_gc_register_mark_object(odd->create_obj);
         | 
| 26 | 
            +
                odd->create_op = rb_intern("new");
         | 
| 27 | 
            +
                odd->is_module = (T_MODULE == rb_type(odd->clas));
         | 
| 28 | 
            +
                odd->raw       = 0;
         | 
| 30 29 | 
             
                for (np = odd->attr_names, idp = odd->attrs; 0 != *np; np++, idp++) {
         | 
| 31 30 | 
             
                    *idp = rb_intern(*np);
         | 
| 32 31 | 
             
                }
         | 
| @@ -37,15 +36,48 @@ static VALUE get_datetime_secs(VALUE obj) { | |
| 37 36 | 
             
                volatile VALUE rsecs = rb_funcall(obj, sec_id, 0);
         | 
| 38 37 | 
             
                volatile VALUE rfrac = rb_funcall(obj, sec_fraction_id, 0);
         | 
| 39 38 | 
             
                long           sec   = NUM2LONG(rsecs);
         | 
| 40 | 
            -
                long long      num   =  | 
| 41 | 
            -
                long long      den   =  | 
| 39 | 
            +
                long long      num   = NUM2LL(rb_funcall(rfrac, numerator_id, 0));
         | 
| 40 | 
            +
                long long      den   = NUM2LL(rb_funcall(rfrac, denominator_id, 0));
         | 
| 42 41 |  | 
| 43 42 | 
             
                num += sec * den;
         | 
| 44 43 |  | 
| 45 44 | 
             
                return rb_funcall(rb_cObject, rational_id, 2, rb_ll2inum(num), rb_ll2inum(den));
         | 
| 46 45 | 
             
            }
         | 
| 47 46 |  | 
| 48 | 
            -
            void  | 
| 47 | 
            +
            static void print_odd(Odd odd) {
         | 
| 48 | 
            +
                const char **np;
         | 
| 49 | 
            +
                int          i;
         | 
| 50 | 
            +
             | 
| 51 | 
            +
                printf("  %s {\n", odd->classname);
         | 
| 52 | 
            +
                printf("    attr_cnt: %d %p\n", odd->attr_cnt, (void *)odd->attr_names);
         | 
| 53 | 
            +
                printf("    attr_names: %p\n", (void *)*odd->attr_names);
         | 
| 54 | 
            +
                printf("    attr_names: %c\n", **odd->attr_names);
         | 
| 55 | 
            +
                for (i = odd->attr_cnt, np = odd->attr_names; 0 < i; i--, np++) {
         | 
| 56 | 
            +
                    printf("    %d %s\n", i, *np);
         | 
| 57 | 
            +
                }
         | 
| 58 | 
            +
                printf("  }\n");
         | 
| 59 | 
            +
            }
         | 
| 60 | 
            +
             | 
| 61 | 
            +
            void print_all_odds(const char *label) {
         | 
| 62 | 
            +
                Odd odd;
         | 
| 63 | 
            +
                printf("@ %s {\n", label);
         | 
| 64 | 
            +
                for (odd = odds; NULL != odd; odd = odd->next) {
         | 
| 65 | 
            +
                    print_odd(odd);
         | 
| 66 | 
            +
                }
         | 
| 67 | 
            +
                printf("}\n");
         | 
| 68 | 
            +
            }
         | 
| 69 | 
            +
             | 
| 70 | 
            +
            static Odd odd_create(void) {
         | 
| 71 | 
            +
                Odd odd = ALLOC(struct _odd);
         | 
| 72 | 
            +
             | 
| 73 | 
            +
                memset(odd, 0, sizeof(struct _odd));
         | 
| 74 | 
            +
                odd->next = odds;
         | 
| 75 | 
            +
                odds      = odd;
         | 
| 76 | 
            +
             | 
| 77 | 
            +
                return odd;
         | 
| 78 | 
            +
            }
         | 
| 79 | 
            +
             | 
| 80 | 
            +
            void oj_odd_init(void) {
         | 
| 49 81 | 
             
                Odd          odd;
         | 
| 50 82 | 
             
                const char **np;
         | 
| 51 83 |  | 
| @@ -55,11 +87,9 @@ void oj_odd_init() { | |
| 55 87 | 
             
                numerator_id    = rb_intern("numerator");
         | 
| 56 88 | 
             
                denominator_id  = rb_intern("denominator");
         | 
| 57 89 | 
             
                rational_id     = rb_intern("Rational");
         | 
| 58 | 
            -
                rational_class  = rb_const_get(rb_cObject, rational_id);
         | 
| 59 90 |  | 
| 60 | 
            -
                memset(_odds, 0, sizeof(_odds));
         | 
| 61 | 
            -
                odd = odds;
         | 
| 62 91 | 
             
                // Rational
         | 
| 92 | 
            +
                odd   = odd_create();
         | 
| 63 93 | 
             
                np    = odd->attr_names;
         | 
| 64 94 | 
             
                *np++ = "numerator";
         | 
| 65 95 | 
             
                *np++ = "denominator";
         | 
| @@ -68,8 +98,9 @@ void oj_odd_init() { | |
| 68 98 | 
             
                odd->create_obj = rb_cObject;
         | 
| 69 99 | 
             
                odd->create_op  = rational_id;
         | 
| 70 100 | 
             
                odd->attr_cnt   = 2;
         | 
| 101 | 
            +
             | 
| 71 102 | 
             
                // Date
         | 
| 72 | 
            -
                odd | 
| 103 | 
            +
                odd   = odd_create();
         | 
| 73 104 | 
             
                np    = odd->attr_names;
         | 
| 74 105 | 
             
                *np++ = "year";
         | 
| 75 106 | 
             
                *np++ = "month";
         | 
| @@ -78,8 +109,9 @@ void oj_odd_init() { | |
| 78 109 | 
             
                *np++ = 0;
         | 
| 79 110 | 
             
                set_class(odd, "Date");
         | 
| 80 111 | 
             
                odd->attr_cnt = 4;
         | 
| 112 | 
            +
             | 
| 81 113 | 
             
                // DateTime
         | 
| 82 | 
            -
                odd | 
| 114 | 
            +
                odd   = odd_create();
         | 
| 83 115 | 
             
                np    = odd->attr_names;
         | 
| 84 116 | 
             
                *np++ = "year";
         | 
| 85 117 | 
             
                *np++ = "month";
         | 
| @@ -93,8 +125,9 @@ void oj_odd_init() { | |
| 93 125 | 
             
                set_class(odd, "DateTime");
         | 
| 94 126 | 
             
                odd->attr_cnt     = 8;
         | 
| 95 127 | 
             
                odd->attrFuncs[5] = get_datetime_secs;
         | 
| 128 | 
            +
             | 
| 96 129 | 
             
                // Range
         | 
| 97 | 
            -
                odd | 
| 130 | 
            +
                odd   = odd_create();
         | 
| 98 131 | 
             
                np    = odd->attr_names;
         | 
| 99 132 | 
             
                *np++ = "begin";
         | 
| 100 133 | 
             
                *np++ = "end";
         | 
| @@ -102,15 +135,13 @@ void oj_odd_init() { | |
| 102 135 | 
             
                *np++ = 0;
         | 
| 103 136 | 
             
                set_class(odd, "Range");
         | 
| 104 137 | 
             
                odd->attr_cnt = 3;
         | 
| 105 | 
            -
             | 
| 106 | 
            -
                odd_cnt = odd - odds + 1;
         | 
| 107 138 | 
             
            }
         | 
| 108 139 |  | 
| 109 140 | 
             
            Odd oj_get_odd(VALUE clas) {
         | 
| 110 141 | 
             
                Odd         odd;
         | 
| 111 142 | 
             
                const char *classname = NULL;
         | 
| 112 143 |  | 
| 113 | 
            -
                for (odd = odds  | 
| 144 | 
            +
                for (odd = odds; NULL != odd; odd = odd->next) {
         | 
| 114 145 | 
             
                    if (clas == odd->clas) {
         | 
| 115 146 | 
             
                        return odd;
         | 
| 116 147 | 
             
                    }
         | 
| @@ -129,21 +160,20 @@ Odd oj_get_odd(VALUE clas) { | |
| 129 160 | 
             
            Odd oj_get_oddc(const char *classname, size_t len) {
         | 
| 130 161 | 
             
                Odd odd;
         | 
| 131 162 |  | 
| 132 | 
            -
                for (odd = odds  | 
| 163 | 
            +
                for (odd = odds; NULL != odd; odd = odd->next) {
         | 
| 133 164 | 
             
                    if (len == odd->clen && 0 == strncmp(classname, odd->classname, len)) {
         | 
| 134 165 | 
             
                        return odd;
         | 
| 135 166 | 
             
                    }
         | 
| 136 | 
            -
                    if (odd->is_module && 0 == strncmp(odd->classname, classname, odd->clen) &&
         | 
| 137 | 
            -
                        ':' == classname[odd->clen]) {
         | 
| 167 | 
            +
                    if (odd->is_module && 0 == strncmp(odd->classname, classname, odd->clen) && ':' == classname[odd->clen]) {
         | 
| 138 168 | 
             
                        return odd;
         | 
| 139 169 | 
             
                    }
         | 
| 140 170 | 
             
                }
         | 
| 141 | 
            -
                return  | 
| 171 | 
            +
                return NULL;
         | 
| 142 172 | 
             
            }
         | 
| 143 173 |  | 
| 144 174 | 
             
            OddArgs oj_odd_alloc_args(Odd odd) {
         | 
| 145 175 | 
             
                OddArgs oa = ALLOC_N(struct _oddArgs, 1);
         | 
| 146 | 
            -
                VALUE | 
| 176 | 
            +
                VALUE  *a;
         | 
| 147 177 | 
             
                int     i;
         | 
| 148 178 |  | 
| 149 179 | 
             
                oa->odd = odd;
         | 
| @@ -159,11 +189,10 @@ void oj_odd_free(OddArgs args) { | |
| 159 189 |  | 
| 160 190 | 
             
            int oj_odd_set_arg(OddArgs args, const char *key, size_t klen, VALUE value) {
         | 
| 161 191 | 
             
                const char **np;
         | 
| 162 | 
            -
                VALUE | 
| 192 | 
            +
                VALUE       *vp;
         | 
| 163 193 | 
             
                int          i;
         | 
| 164 194 |  | 
| 165 | 
            -
                for (i = args->odd->attr_cnt, np = args->odd->attr_names, vp = args->args; 0 < i;
         | 
| 166 | 
            -
                     i--, np++, vp++) {
         | 
| 195 | 
            +
                for (i = args->odd->attr_cnt, np = args->odd->attr_names, vp = args->args; 0 < i; i--, np++, vp++) {
         | 
| 167 196 | 
             
                    if (0 == strncmp(key, *np, klen) && '\0' == *((*np) + klen)) {
         | 
| 168 197 | 
             
                        *vp = value;
         | 
| 169 198 | 
             
                        return 0;
         | 
| @@ -172,37 +201,26 @@ int oj_odd_set_arg(OddArgs args, const char *key, size_t klen, VALUE value) { | |
| 172 201 | 
             
                return -1;
         | 
| 173 202 | 
             
            }
         | 
| 174 203 |  | 
| 175 | 
            -
            void oj_reg_odd(VALUE | 
| 176 | 
            -
                            VALUE  create_object,
         | 
| 177 | 
            -
                            VALUE  create_method,
         | 
| 178 | 
            -
                            int    mcnt,
         | 
| 179 | 
            -
                            VALUE *members,
         | 
| 180 | 
            -
                            bool   raw) {
         | 
| 204 | 
            +
            void oj_reg_odd(VALUE clas, VALUE create_object, VALUE create_method, int mcnt, VALUE *members, bool raw) {
         | 
| 181 205 | 
             
                Odd          odd;
         | 
| 182 206 | 
             
                const char **np;
         | 
| 183 | 
            -
                ID | 
| 207 | 
            +
                ID          *ap;
         | 
| 184 208 | 
             
                AttrGetFunc *fp;
         | 
| 185 209 |  | 
| 186 | 
            -
                 | 
| 187 | 
            -
                    odds = ALLOC_N(struct _odd, odd_cnt + 1);
         | 
| 188 | 
            -
             | 
| 189 | 
            -
                    memcpy(odds, _odds, sizeof(struct _odd) * odd_cnt);
         | 
| 190 | 
            -
                } else {
         | 
| 191 | 
            -
                    REALLOC_N(odds, struct _odd, odd_cnt + 1);
         | 
| 192 | 
            -
                }
         | 
| 193 | 
            -
                odd       = odds + odd_cnt;
         | 
| 210 | 
            +
                odd       = odd_create();
         | 
| 194 211 | 
             
                odd->clas = clas;
         | 
| 212 | 
            +
                rb_gc_register_mark_object(odd->clas);
         | 
| 195 213 | 
             
                if (NULL == (odd->classname = strdup(rb_class2name(clas)))) {
         | 
| 196 | 
            -
                    rb_raise(rb_eNoMemError, "for  | 
| 214 | 
            +
                    rb_raise(rb_eNoMemError, "for class name.");
         | 
| 197 215 | 
             
                }
         | 
| 198 216 | 
             
                odd->clen       = strlen(odd->classname);
         | 
| 199 217 | 
             
                odd->create_obj = create_object;
         | 
| 200 | 
            -
                odd-> | 
| 201 | 
            -
                odd-> | 
| 202 | 
            -
                odd-> | 
| 203 | 
            -
                odd-> | 
| 204 | 
            -
                 | 
| 205 | 
            -
             | 
| 218 | 
            +
                rb_gc_register_mark_object(odd->create_obj);
         | 
| 219 | 
            +
                odd->create_op = SYM2ID(create_method);
         | 
| 220 | 
            +
                odd->attr_cnt  = mcnt;
         | 
| 221 | 
            +
                odd->is_module = (T_MODULE == rb_type(clas));
         | 
| 222 | 
            +
                odd->raw       = raw;
         | 
| 223 | 
            +
                for (ap = odd->attrs, np = odd->attr_names, fp = odd->attrFuncs; 0 < mcnt; mcnt--, ap++, np++, members++, fp++) {
         | 
| 206 224 | 
             
                    *fp = 0;
         | 
| 207 225 | 
             
                    switch (rb_type(*members)) {
         | 
| 208 226 | 
             
                    case T_STRING:
         | 
| @@ -210,14 +228,16 @@ void oj_reg_odd(VALUE  clas, | |
| 210 228 | 
             
                            rb_raise(rb_eNoMemError, "for attribute name.");
         | 
| 211 229 | 
             
                        }
         | 
| 212 230 | 
             
                        break;
         | 
| 213 | 
            -
                    case T_SYMBOL: | 
| 214 | 
            -
             | 
| 215 | 
            -
                         | 
| 231 | 
            +
                    case T_SYMBOL:
         | 
| 232 | 
            +
                        // The symbol can move and invalidate the name so make a copy.
         | 
| 233 | 
            +
                        if (NULL == (*np = strdup(rb_id2name(SYM2ID(*members))))) {
         | 
| 234 | 
            +
                            rb_raise(rb_eNoMemError, "for attribute name.");
         | 
| 235 | 
            +
                        }
         | 
| 216 236 | 
             
                        break;
         | 
| 237 | 
            +
                    default: rb_raise(rb_eArgError, "registered member identifiers must be Strings or Symbols."); break;
         | 
| 217 238 | 
             
                    }
         | 
| 218 239 | 
             
                    *ap = rb_intern(*np);
         | 
| 219 240 | 
             
                }
         | 
| 220 241 | 
             
                *np = 0;
         | 
| 221 242 | 
             
                *ap = 0;
         | 
| 222 | 
            -
                odd_cnt++;
         | 
| 223 243 | 
             
            }
         | 
    
        data/ext/oj/odd.h
    CHANGED
    
    | @@ -13,17 +13,18 @@ | |
| 13 13 | 
             
            typedef VALUE (*AttrGetFunc)(VALUE obj);
         | 
| 14 14 |  | 
| 15 15 | 
             
            typedef struct _odd {
         | 
| 16 | 
            -
                 | 
| 17 | 
            -
                 | 
| 18 | 
            -
                 | 
| 19 | 
            -
                VALUE | 
| 20 | 
            -
                 | 
| 21 | 
            -
                 | 
| 22 | 
            -
                 | 
| 23 | 
            -
                bool | 
| 24 | 
            -
                 | 
| 25 | 
            -
                 | 
| 26 | 
            -
                 | 
| 16 | 
            +
                struct _odd *next;
         | 
| 17 | 
            +
                const char * classname;
         | 
| 18 | 
            +
                size_t       clen;
         | 
| 19 | 
            +
                VALUE        clas;  // Ruby class or module
         | 
| 20 | 
            +
                VALUE        create_obj;
         | 
| 21 | 
            +
                ID           create_op;
         | 
| 22 | 
            +
                int          attr_cnt;
         | 
| 23 | 
            +
                bool         is_module;
         | 
| 24 | 
            +
                bool         raw;
         | 
| 25 | 
            +
                const char * attr_names[MAX_ODD_ARGS];  // NULL terminated attr names
         | 
| 26 | 
            +
                ID           attrs[MAX_ODD_ARGS];       // 0 terminated attr IDs
         | 
| 27 | 
            +
                AttrGetFunc  attrFuncs[MAX_ODD_ARGS];
         | 
| 27 28 | 
             
            } * Odd;
         | 
| 28 29 |  | 
| 29 30 | 
             
            typedef struct _oddArgs {
         | 
| @@ -37,7 +38,6 @@ extern Odd     oj_get_oddc(const char *classname, size_t len); | |
| 37 38 | 
             
            extern OddArgs oj_odd_alloc_args(Odd odd);
         | 
| 38 39 | 
             
            extern void    oj_odd_free(OddArgs args);
         | 
| 39 40 | 
             
            extern int     oj_odd_set_arg(OddArgs args, const char *key, size_t klen, VALUE value);
         | 
| 40 | 
            -
            extern void
         | 
| 41 | 
            -
            oj_reg_odd(VALUE clas, VALUE create_object, VALUE create_method, int mcnt, VALUE *members, bool raw);
         | 
| 41 | 
            +
            extern void    oj_reg_odd(VALUE clas, VALUE create_object, VALUE create_method, int mcnt, VALUE *members, bool raw);
         | 
| 42 42 |  | 
| 43 43 | 
             
            #endif /* OJ_ODD_H */
         | 
    
        data/ext/oj/oj.c
    CHANGED
    
    | @@ -32,6 +32,7 @@ ID oj_array_append_id; | |
| 32 32 | 
             
            ID oj_array_end_id;
         | 
| 33 33 | 
             
            ID oj_array_start_id;
         | 
| 34 34 | 
             
            ID oj_as_json_id;
         | 
| 35 | 
            +
            ID oj_at_id;
         | 
| 35 36 | 
             
            ID oj_begin_id;
         | 
| 36 37 | 
             
            ID oj_bigdecimal_id;
         | 
| 37 38 | 
             
            ID oj_end_id;
         | 
| @@ -45,7 +46,6 @@ ID oj_hash_key_id; | |
| 45 46 | 
             
            ID oj_hash_set_id;
         | 
| 46 47 | 
             
            ID oj_hash_start_id;
         | 
| 47 48 | 
             
            ID oj_iconv_id;
         | 
| 48 | 
            -
            ID oj_instance_variables_id;
         | 
| 49 49 | 
             
            ID oj_json_create_id;
         | 
| 50 50 | 
             
            ID oj_length_id;
         | 
| 51 51 | 
             
            ID oj_new_id;
         | 
| @@ -90,7 +90,9 @@ VALUE oj_array_class_sym; | |
| 90 90 | 
             
            VALUE oj_create_additions_sym;
         | 
| 91 91 | 
             
            VALUE oj_decimal_class_sym;
         | 
| 92 92 | 
             
            VALUE oj_hash_class_sym;
         | 
| 93 | 
            +
            VALUE oj_in_sym;
         | 
| 93 94 | 
             
            VALUE oj_indent_sym;
         | 
| 95 | 
            +
            VALUE oj_nanosecond_sym;
         | 
| 94 96 | 
             
            VALUE oj_object_class_sym;
         | 
| 95 97 | 
             
            VALUE oj_quirks_mode_sym;
         | 
| 96 98 | 
             
            VALUE oj_safe_sym;
         | 
| @@ -137,6 +139,7 @@ static VALUE rails_sym; | |
| 137 139 | 
             
            static VALUE raise_sym;
         | 
| 138 140 | 
             
            static VALUE ruby_sym;
         | 
| 139 141 | 
             
            static VALUE sec_prec_sym;
         | 
| 142 | 
            +
            static VALUE slash_sym;
         | 
| 140 143 | 
             
            static VALUE strict_sym;
         | 
| 141 144 | 
             
            static VALUE symbol_keys_sym;
         | 
| 142 145 | 
             
            static VALUE time_format_sym;
         | 
| @@ -153,6 +156,7 @@ static VALUE xmlschema_sym; | |
| 153 156 | 
             
            static VALUE xss_safe_sym;
         | 
| 154 157 |  | 
| 155 158 | 
             
            rb_encoding *oj_utf8_encoding = 0;
         | 
| 159 | 
            +
            int oj_utf8_encoding_index = 0;
         | 
| 156 160 |  | 
| 157 161 | 
             
            #ifdef HAVE_PTHREAD_MUTEX_INIT
         | 
| 158 162 | 
             
            pthread_mutex_t oj_cache_mutex;
         | 
| @@ -239,7 +243,7 @@ struct _options oj_default_options = { | |
| 239 243 | 
             
             *references
         | 
| 240 244 | 
             
             * - *:auto_define* [_Boolean_|_nil_] automatically define classes if they do not exist
         | 
| 241 245 | 
             
             * - *:symbol_keys* [_Boolean_|_nil_] use symbols instead of strings for hash keys
         | 
| 242 | 
            -
             * - *:escape_mode* [_:newline_|_:json_|_:xss_safe_|_:ascii_| | 
| 246 | 
            +
             * - *:escape_mode* [_:newline_|_:json_|_:slash_|_:xss_safe_|_:ascii_|_:unicode_xss_|_nil_] determines the
         | 
| 243 247 | 
             
             *characters to escape
         | 
| 244 248 | 
             
             * - *:class_cache* [_Boolean_|_nil_] cache classes for faster parsing (if dynamically modifying
         | 
| 245 249 | 
             
             *classes or reloading classes then don't use this)
         | 
| @@ -247,7 +251,7 @@ struct _options oj_default_options = { | |
| 247 251 | 
             
             *to use for JSON
         | 
| 248 252 | 
             
             * - *:time_format* [_:unix_|_:unix_zone_|_:xmlschema_|_:ruby_] time format when dumping
         | 
| 249 253 | 
             
             * - *:bigdecimal_as_decimal* [_Boolean_|_nil_] dump BigDecimal as a decimal number or as a String
         | 
| 250 | 
            -
             * - *:bigdecimal_load* [_:bigdecimal_|_:float_|_:auto_|_:fast_] load decimals as BigDecimal instead
         | 
| 254 | 
            +
             * - *:bigdecimal_load* [_:bigdecimal_|_:float_|_:auto_|_:fast_|_:ruby_] load decimals as BigDecimal instead
         | 
| 251 255 | 
             
             *of as a Float. :auto pick the most precise for the number of digits. :float should be the same as
         | 
| 252 256 | 
             
             *ruby. :fast may require rounding but is must faster.
         | 
| 253 257 | 
             
             * - *:compat_bigdecimal* [_true_|_false_] load decimals as BigDecimal instead of as a Float when in
         | 
| @@ -404,6 +408,7 @@ static VALUE get_def_opts(VALUE self) { | |
| 404 408 | 
             
                switch (oj_default_options.escape_mode) {
         | 
| 405 409 | 
             
                case NLEsc: rb_hash_aset(opts, escape_mode_sym, newline_sym); break;
         | 
| 406 410 | 
             
                case JSONEsc: rb_hash_aset(opts, escape_mode_sym, json_sym); break;
         | 
| 411 | 
            +
                case SlashEsc: rb_hash_aset(opts, escape_mode_sym, slash_sym); break;
         | 
| 407 412 | 
             
                case XSSEsc: rb_hash_aset(opts, escape_mode_sym, xss_safe_sym); break;
         | 
| 408 413 | 
             
                case ASCIIEsc: rb_hash_aset(opts, escape_mode_sym, ascii_sym); break;
         | 
| 409 414 | 
             
                case JXEsc: rb_hash_aset(opts, escape_mode_sym, unicode_xss_sym); break;
         | 
| @@ -733,6 +738,8 @@ static int parse_options_cb(VALUE k, VALUE v, VALUE opts) { | |
| 733 738 | 
             
                        copts->escape_mode = NLEsc;
         | 
| 734 739 | 
             
                    } else if (json_sym == v) {
         | 
| 735 740 | 
             
                        copts->escape_mode = JSONEsc;
         | 
| 741 | 
            +
                    } else if (slash_sym == v) {
         | 
| 742 | 
            +
                        copts->escape_mode = SlashEsc;
         | 
| 736 743 | 
             
                    } else if (xss_safe_sym == v) {
         | 
| 737 744 | 
             
                        copts->escape_mode = XSSEsc;
         | 
| 738 745 | 
             
                    } else if (ascii_sym == v) {
         | 
| @@ -925,7 +932,7 @@ static int parse_options_cb(VALUE k, VALUE v, VALUE opts) { | |
| 925 932 | 
             
                    if (Qnil == v) {
         | 
| 926 933 | 
             
                        return ST_CONTINUE;
         | 
| 927 934 | 
             
                    }
         | 
| 928 | 
            -
                    if ( | 
| 935 | 
            +
                    if (rb_obj_class(v) == rb_cRange) {
         | 
| 929 936 | 
             
                        VALUE min = rb_funcall(v, oj_begin_id, 0);
         | 
| 930 937 | 
             
                        VALUE max = rb_funcall(v, oj_end_id, 0);
         | 
| 931 938 |  | 
| @@ -1147,7 +1154,17 @@ static VALUE load_file(int argc, VALUE *argv, VALUE self) { | |
| 1147 1154 | 
             
                    }
         | 
| 1148 1155 | 
             
                }
         | 
| 1149 1156 | 
             
                path = StringValuePtr(*argv);
         | 
| 1150 | 
            -
             | 
| 1157 | 
            +
            #ifdef _WIN32
         | 
| 1158 | 
            +
                {
         | 
| 1159 | 
            +
                    WCHAR *wide_path;
         | 
| 1160 | 
            +
                    wide_path = rb_w32_mbstr_to_wstr(CP_UTF8, path, -1, NULL);
         | 
| 1161 | 
            +
                    fd = rb_w32_wopen(wide_path, O_RDONLY);
         | 
| 1162 | 
            +
                    free(wide_path);
         | 
| 1163 | 
            +
                }
         | 
| 1164 | 
            +
            #else
         | 
| 1165 | 
            +
                fd = open(path, O_RDONLY);
         | 
| 1166 | 
            +
            #endif
         | 
| 1167 | 
            +
                if (0 == fd) {
         | 
| 1151 1168 | 
             
                    rb_raise(rb_eIOError, "%s", strerror(errno));
         | 
| 1152 1169 | 
             
                }
         | 
| 1153 1170 | 
             
                switch (mode) {
         | 
| @@ -1243,9 +1260,8 @@ static VALUE dump_body(VALUE a) { | |
| 1243 1260 | 
             
            static VALUE dump_ensure(VALUE a) {
         | 
| 1244 1261 | 
             
                volatile struct dump_arg *arg = (void *)a;
         | 
| 1245 1262 |  | 
| 1246 | 
            -
                 | 
| 1247 | 
            -
             | 
| 1248 | 
            -
                }
         | 
| 1263 | 
            +
                oj_out_free(arg->out);
         | 
| 1264 | 
            +
             | 
| 1249 1265 | 
             
                return Qnil;
         | 
| 1250 1266 | 
             
            }
         | 
| 1251 1267 |  | 
| @@ -1257,7 +1273,6 @@ static VALUE dump_ensure(VALUE a) { | |
| 1257 1273 | 
             
             * - *options* [_Hash_] same as default_options
         | 
| 1258 1274 | 
             
             */
         | 
| 1259 1275 | 
             
            static VALUE dump(int argc, VALUE *argv, VALUE self) {
         | 
| 1260 | 
            -
                char            buf[4096];
         | 
| 1261 1276 | 
             
                struct dump_arg arg;
         | 
| 1262 1277 | 
             
                struct _out     out;
         | 
| 1263 1278 | 
             
                struct _options copts = oj_default_options;
         | 
| @@ -1279,9 +1294,8 @@ static VALUE dump(int argc, VALUE *argv, VALUE self) { | |
| 1279 1294 | 
             
                arg.argc  = argc;
         | 
| 1280 1295 | 
             
                arg.argv  = argv;
         | 
| 1281 1296 |  | 
| 1282 | 
            -
                arg.out | 
| 1283 | 
            -
             | 
| 1284 | 
            -
                arg.out->allocated = false;
         | 
| 1297 | 
            +
                oj_out_init(arg.out);
         | 
| 1298 | 
            +
             | 
| 1285 1299 | 
             
                arg.out->omit_nil  = copts.dump_opts.omit_nil;
         | 
| 1286 1300 | 
             
                arg.out->caller    = CALLER_DUMP;
         | 
| 1287 1301 |  | 
| @@ -1313,7 +1327,6 @@ static VALUE dump(int argc, VALUE *argv, VALUE self) { | |
| 1313 1327 | 
             
             * Returns [_String_] the encoded JSON.
         | 
| 1314 1328 | 
             
             */
         | 
| 1315 1329 | 
             
            static VALUE to_json(int argc, VALUE *argv, VALUE self) {
         | 
| 1316 | 
            -
                char            buf[4096];
         | 
| 1317 1330 | 
             
                struct _out     out;
         | 
| 1318 1331 | 
             
                struct _options copts = oj_default_options;
         | 
| 1319 1332 | 
             
                VALUE           rstr;
         | 
| @@ -1328,9 +1341,9 @@ static VALUE to_json(int argc, VALUE *argv, VALUE self) { | |
| 1328 1341 | 
             
                }
         | 
| 1329 1342 | 
             
                copts.mode    = CompatMode;
         | 
| 1330 1343 | 
             
                copts.to_json = Yes;
         | 
| 1331 | 
            -
             | 
| 1332 | 
            -
                out | 
| 1333 | 
            -
             | 
| 1344 | 
            +
             | 
| 1345 | 
            +
                oj_out_init(&out);
         | 
| 1346 | 
            +
             | 
| 1334 1347 | 
             
                out.omit_nil  = copts.dump_opts.omit_nil;
         | 
| 1335 1348 | 
             
                // For obj.to_json or generate nan is not allowed but if called from dump
         | 
| 1336 1349 | 
             
                // it is.
         | 
| @@ -1341,9 +1354,9 @@ static VALUE to_json(int argc, VALUE *argv, VALUE self) { | |
| 1341 1354 | 
             
                }
         | 
| 1342 1355 | 
             
                rstr = rb_str_new2(out.buf);
         | 
| 1343 1356 | 
             
                rstr = oj_encode(rstr);
         | 
| 1344 | 
            -
             | 
| 1345 | 
            -
             | 
| 1346 | 
            -
             | 
| 1357 | 
            +
             | 
| 1358 | 
            +
                oj_out_free(&out);
         | 
| 1359 | 
            +
             | 
| 1347 1360 | 
             
                return rstr;
         | 
| 1348 1361 | 
             
            }
         | 
| 1349 1362 |  | 
| @@ -1703,6 +1716,15 @@ static VALUE protect_require(VALUE x) { | |
| 1703 1716 | 
             
                return Qnil;
         | 
| 1704 1717 | 
             
            }
         | 
| 1705 1718 |  | 
| 1719 | 
            +
            extern void print_all_odds(const char *label);
         | 
| 1720 | 
            +
             | 
| 1721 | 
            +
            static VALUE
         | 
| 1722 | 
            +
            debug_odd(VALUE self, VALUE label) {
         | 
| 1723 | 
            +
                print_all_odds(RSTRING_PTR(label));
         | 
| 1724 | 
            +
                return Qnil;
         | 
| 1725 | 
            +
            }
         | 
| 1726 | 
            +
             | 
| 1727 | 
            +
             | 
| 1706 1728 | 
             
            /* Document-module: Oj
         | 
| 1707 1729 | 
             
             *
         | 
| 1708 1730 | 
             
             * Optimized JSON (Oj), as the name implies was written to provide speed
         | 
| @@ -1731,15 +1753,19 @@ static VALUE protect_require(VALUE x) { | |
| 1731 1753 | 
             
             *
         | 
| 1732 1754 | 
             
             * - *:wab* specifically for WAB data exchange.
         | 
| 1733 1755 | 
             
             */
         | 
| 1734 | 
            -
            void Init_oj() {
         | 
| 1756 | 
            +
            void Init_oj(void) {
         | 
| 1735 1757 | 
             
                int err = 0;
         | 
| 1736 1758 |  | 
| 1737 1759 | 
             
            #if HAVE_RB_EXT_RACTOR_SAFE
         | 
| 1738 1760 | 
             
                rb_ext_ractor_safe(true);
         | 
| 1739 1761 | 
             
            #endif
         | 
| 1740 1762 | 
             
                Oj = rb_define_module("Oj");
         | 
| 1763 | 
            +
                rb_gc_register_address(&Oj);
         | 
| 1741 1764 |  | 
| 1742 1765 | 
             
                oj_cstack_class = rb_define_class_under(Oj, "CStack", rb_cObject);
         | 
| 1766 | 
            +
                rb_gc_register_address(&oj_cstack_class);
         | 
| 1767 | 
            +
             | 
| 1768 | 
            +
                rb_undef_alloc_func(oj_cstack_class);
         | 
| 1743 1769 |  | 
| 1744 1770 | 
             
                oj_string_writer_init();
         | 
| 1745 1771 | 
             
                oj_stream_writer_init();
         | 
| @@ -1748,9 +1774,11 @@ void Init_oj() { | |
| 1748 1774 | 
             
                // On Rubinius the require fails but can be done from a ruby file.
         | 
| 1749 1775 | 
             
                rb_protect(protect_require, Qnil, &err);
         | 
| 1750 1776 | 
             
                rb_require("stringio");
         | 
| 1751 | 
            -
                 | 
| 1777 | 
            +
                oj_utf8_encoding_index = rb_enc_find_index("UTF-8");
         | 
| 1778 | 
            +
                oj_utf8_encoding = rb_enc_from_index(oj_utf8_encoding_index);
         | 
| 1752 1779 |  | 
| 1753 1780 | 
             
                // rb_define_module_function(Oj, "hash_test", hash_test, 0);
         | 
| 1781 | 
            +
                rb_define_module_function(Oj, "debug_odd", debug_odd, 1);
         | 
| 1754 1782 |  | 
| 1755 1783 | 
             
                rb_define_module_function(Oj, "default_options", get_def_opts, 0);
         | 
| 1756 1784 | 
             
                rb_define_module_function(Oj, "default_options=", set_def_opts, 1);
         | 
| @@ -1789,6 +1817,7 @@ void Init_oj() { | |
| 1789 1817 | 
             
                oj_array_end_id          = rb_intern("array_end");
         | 
| 1790 1818 | 
             
                oj_array_start_id        = rb_intern("array_start");
         | 
| 1791 1819 | 
             
                oj_as_json_id            = rb_intern("as_json");
         | 
| 1820 | 
            +
                oj_at_id                 = rb_intern("at");
         | 
| 1792 1821 | 
             
                oj_begin_id              = rb_intern("begin");
         | 
| 1793 1822 | 
             
                oj_bigdecimal_id         = rb_intern("BigDecimal");
         | 
| 1794 1823 | 
             
                oj_end_id                = rb_intern("end");
         | 
| @@ -1802,7 +1831,6 @@ void Init_oj() { | |
| 1802 1831 | 
             
                oj_hash_set_id           = rb_intern("hash_set");
         | 
| 1803 1832 | 
             
                oj_hash_start_id         = rb_intern("hash_start");
         | 
| 1804 1833 | 
             
                oj_iconv_id              = rb_intern("iconv");
         | 
| 1805 | 
            -
                oj_instance_variables_id = rb_intern("instance_variables");
         | 
| 1806 1834 | 
             
                oj_json_create_id        = rb_intern("json_create");
         | 
| 1807 1835 | 
             
                oj_length_id             = rb_intern("length");
         | 
| 1808 1836 | 
             
                oj_new_id                = rb_intern("new");
         | 
| @@ -1937,10 +1965,14 @@ void Init_oj() { | |
| 1937 1965 | 
             
                rb_gc_register_address(&oj_decimal_class_sym);
         | 
| 1938 1966 | 
             
                oj_hash_class_sym = ID2SYM(rb_intern("hash_class"));
         | 
| 1939 1967 | 
             
                rb_gc_register_address(&oj_hash_class_sym);
         | 
| 1968 | 
            +
                oj_in_sym = ID2SYM(rb_intern("in"));
         | 
| 1969 | 
            +
                rb_gc_register_address(&oj_in_sym);
         | 
| 1940 1970 | 
             
                oj_indent_sym = ID2SYM(rb_intern("indent"));
         | 
| 1941 1971 | 
             
                rb_gc_register_address(&oj_indent_sym);
         | 
| 1942 1972 | 
             
                oj_max_nesting_sym = ID2SYM(rb_intern("max_nesting"));
         | 
| 1943 1973 | 
             
                rb_gc_register_address(&oj_max_nesting_sym);
         | 
| 1974 | 
            +
                oj_nanosecond_sym = ID2SYM(rb_intern("nanosecond"));
         | 
| 1975 | 
            +
                rb_gc_register_address(&oj_nanosecond_sym);
         | 
| 1944 1976 | 
             
                oj_object_class_sym = ID2SYM(rb_intern("object_class"));
         | 
| 1945 1977 | 
             
                rb_gc_register_address(&oj_object_class_sym);
         | 
| 1946 1978 | 
             
                oj_object_nl_sym = ID2SYM(rb_intern("object_nl"));
         | 
| @@ -1965,6 +1997,8 @@ void Init_oj() { | |
| 1965 1997 | 
             
                rb_gc_register_address(&ruby_sym);
         | 
| 1966 1998 | 
             
                sec_prec_sym = ID2SYM(rb_intern("second_precision"));
         | 
| 1967 1999 | 
             
                rb_gc_register_address(&sec_prec_sym);
         | 
| 2000 | 
            +
                slash_sym = ID2SYM(rb_intern("slash"));
         | 
| 2001 | 
            +
                rb_gc_register_address(&slash_sym);
         | 
| 1968 2002 | 
             
                strict_sym = ID2SYM(rb_intern("strict"));
         | 
| 1969 2003 | 
             
                rb_gc_register_address(&strict_sym);
         | 
| 1970 2004 | 
             
                symbol_keys_sym = ID2SYM(rb_intern("symbol_keys"));
         | 
| @@ -2017,4 +2051,5 @@ void Init_oj() { | |
| 2017 2051 | 
             
                oj_init_doc();
         | 
| 2018 2052 |  | 
| 2019 2053 | 
             
                oj_parser_init();
         | 
| 2054 | 
            +
                oj_scanner_init();
         | 
| 2020 2055 | 
             
            }
         | 
    
        data/ext/oj/oj.h
    CHANGED
    
    | @@ -39,6 +39,16 @@ enum st_retval { ST_CONTINUE = 0, ST_STOP = 1, ST_DELETE = 2, ST_CHECK }; | |
| 39 39 | 
             
            #define NINF_VAL "-3.0e14159265358979323846"
         | 
| 40 40 | 
             
            #define NAN_VAL "3.3e14159265358979323846"
         | 
| 41 41 |  | 
| 42 | 
            +
            #if __STDC_VERSION__ >= 199901L
         | 
| 43 | 
            +
                // To avoid using ruby_snprintf with C99.
         | 
| 44 | 
            +
                #undef snprintf
         | 
| 45 | 
            +
                #include <stdio.h>
         | 
| 46 | 
            +
            #endif
         | 
| 47 | 
            +
             | 
| 48 | 
            +
            // To avoid using ruby_nonempty_memcpy().
         | 
| 49 | 
            +
            #undef memcpy
         | 
| 50 | 
            +
            #include <string.h>
         | 
| 51 | 
            +
             | 
| 42 52 | 
             
            typedef enum { Yes = 'y', No = 'n', NotSet = 0 } YesNo;
         | 
| 43 53 |  | 
| 44 54 | 
             
            typedef enum {
         | 
| @@ -56,6 +66,7 @@ typedef enum { UnixTime = 'u', UnixZTime = 'z', XmlTime = 'x', RubyTime = 'r' } | |
| 56 66 | 
             
            typedef enum {
         | 
| 57 67 | 
             
                NLEsc     = 'n',
         | 
| 58 68 | 
             
                JSONEsc   = 'j',
         | 
| 69 | 
            +
                SlashEsc  = 's',
         | 
| 59 70 | 
             
                XSSEsc    = 'x',
         | 
| 60 71 | 
             
                ASCIIEsc  = 'a',
         | 
| 61 72 | 
             
                JXEsc     = 'g',  // json gem
         | 
| @@ -176,6 +187,7 @@ typedef struct _rOptTable { | |
| 176 187 | 
             
            } * ROptTable;
         | 
| 177 188 |  | 
| 178 189 | 
             
            typedef struct _out {
         | 
| 190 | 
            +
                char       stack_buffer[4096];
         | 
| 179 191 | 
             
                char *     buf;
         | 
| 180 192 | 
             
                char *     end;
         | 
| 181 193 | 
             
                char *     cur;
         | 
| @@ -265,8 +277,8 @@ extern void oj_str_writer_pop(StrWriter sw); | |
| 265 277 | 
             
            extern void oj_str_writer_pop_all(StrWriter sw);
         | 
| 266 278 |  | 
| 267 279 | 
             
            extern void  oj_init_doc(void);
         | 
| 268 | 
            -
            extern void  oj_string_writer_init();
         | 
| 269 | 
            -
            extern void  oj_stream_writer_init();
         | 
| 280 | 
            +
            extern void  oj_string_writer_init(void);
         | 
| 281 | 
            +
            extern void  oj_stream_writer_init(void);
         | 
| 270 282 | 
             
            extern void  oj_str_writer_init(StrWriter sw, int buf_size);
         | 
| 271 283 | 
             
            extern VALUE oj_define_mimic_json(int argc, VALUE *argv, VALUE self);
         | 
| 272 284 | 
             
            extern VALUE oj_mimic_generate(int argc, VALUE *argv, VALUE self);
         | 
| @@ -282,6 +294,7 @@ extern VALUE oj_rails_encode(int argc, VALUE *argv, VALUE self); | |
| 282 294 | 
             
            extern VALUE           Oj;
         | 
| 283 295 | 
             
            extern struct _options oj_default_options;
         | 
| 284 296 | 
             
            extern rb_encoding *   oj_utf8_encoding;
         | 
| 297 | 
            +
            extern int             oj_utf8_encoding_index;
         | 
| 285 298 |  | 
| 286 299 | 
             
            extern VALUE oj_bag_class;
         | 
| 287 300 | 
             
            extern VALUE oj_bigdecimal_class;
         | 
| @@ -304,7 +317,9 @@ extern VALUE oj_ascii_only_sym; | |
| 304 317 | 
             
            extern VALUE oj_create_additions_sym;
         | 
| 305 318 | 
             
            extern VALUE oj_decimal_class_sym;
         | 
| 306 319 | 
             
            extern VALUE oj_hash_class_sym;
         | 
| 320 | 
            +
            extern VALUE oj_in_sym;
         | 
| 307 321 | 
             
            extern VALUE oj_indent_sym;
         | 
| 322 | 
            +
            extern VALUE oj_nanosecond_sym;
         | 
| 308 323 | 
             
            extern VALUE oj_max_nesting_sym;
         | 
| 309 324 | 
             
            extern VALUE oj_object_class_sym;
         | 
| 310 325 | 
             
            extern VALUE oj_object_nl_sym;
         | 
| @@ -321,6 +336,7 @@ extern ID oj_array_append_id; | |
| 321 336 | 
             
            extern ID oj_array_end_id;
         | 
| 322 337 | 
             
            extern ID oj_array_start_id;
         | 
| 323 338 | 
             
            extern ID oj_as_json_id;
         | 
| 339 | 
            +
            extern ID oj_at_id;
         | 
| 324 340 | 
             
            extern ID oj_begin_id;
         | 
| 325 341 | 
             
            extern ID oj_bigdecimal_id;
         | 
| 326 342 | 
             
            extern ID oj_end_id;
         | 
| @@ -334,7 +350,6 @@ extern ID oj_hash_key_id; | |
| 334 350 | 
             
            extern ID oj_hash_set_id;
         | 
| 335 351 | 
             
            extern ID oj_hash_start_id;
         | 
| 336 352 | 
             
            extern ID oj_iconv_id;
         | 
| 337 | 
            -
            extern ID oj_instance_variables_id;
         | 
| 338 353 | 
             
            extern ID oj_json_create_id;
         | 
| 339 354 | 
             
            extern ID oj_length_id;
         | 
| 340 355 | 
             
            extern ID oj_new_id;
         | 
| @@ -364,6 +379,12 @@ extern bool oj_use_hash_alt; | |
| 364 379 | 
             
            extern bool oj_use_array_alt;
         | 
| 365 380 | 
             
            extern bool string_writer_optimized;
         | 
| 366 381 |  | 
| 382 | 
            +
            #define APPEND_CHARS(buffer, chars, size) \
         | 
| 383 | 
            +
                { \
         | 
| 384 | 
            +
                    memcpy(buffer, chars, size); \
         | 
| 385 | 
            +
                    buffer += size; \
         | 
| 386 | 
            +
                }
         | 
| 387 | 
            +
             | 
| 367 388 | 
             
            #ifdef HAVE_PTHREAD_MUTEX_INIT
         | 
| 368 389 | 
             
            extern pthread_mutex_t oj_cache_mutex;
         | 
| 369 390 | 
             
            #else
         |