oj 3.13.17 → 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 +77 -0
- data/README.md +4 -2
- data/ext/oj/buf.h +7 -6
- data/ext/oj/cache.c +29 -26
- data/ext/oj/cache.h +3 -2
- data/ext/oj/cache8.c +10 -9
- data/ext/oj/circarray.c +7 -5
- data/ext/oj/circarray.h +2 -2
- data/ext/oj/code.c +5 -12
- data/ext/oj/code.h +2 -2
- data/ext/oj/compat.c +20 -60
- data/ext/oj/custom.c +44 -96
- data/ext/oj/debug.c +3 -9
- data/ext/oj/dump.c +69 -39
- data/ext/oj/dump.h +1 -4
- data/ext/oj/dump_compat.c +557 -592
- data/ext/oj/dump_leaf.c +3 -5
- data/ext/oj/dump_object.c +42 -48
- data/ext/oj/dump_strict.c +10 -22
- data/ext/oj/encoder.c +1 -1
- data/ext/oj/err.c +2 -13
- data/ext/oj/err.h +9 -12
- data/ext/oj/extconf.rb +16 -6
- data/ext/oj/fast.c +76 -106
- data/ext/oj/intern.c +63 -51
- data/ext/oj/intern.h +3 -7
- data/ext/oj/mem.c +318 -0
- data/ext/oj/mem.h +53 -0
- data/ext/oj/mimic_json.c +43 -30
- data/ext/oj/object.c +61 -70
- data/ext/oj/odd.c +8 -6
- data/ext/oj/odd.h +4 -4
- data/ext/oj/oj.c +243 -205
- data/ext/oj/oj.h +82 -78
- data/ext/oj/parse.c +123 -188
- data/ext/oj/parse.h +23 -24
- data/ext/oj/parser.c +103 -63
- data/ext/oj/parser.h +19 -9
- data/ext/oj/rails.c +68 -92
- data/ext/oj/reader.c +10 -15
- data/ext/oj/reader.h +4 -2
- data/ext/oj/resolve.c +3 -4
- data/ext/oj/rxclass.c +6 -5
- data/ext/oj/rxclass.h +1 -1
- data/ext/oj/saj.c +10 -9
- data/ext/oj/saj2.c +74 -92
- data/ext/oj/saj2.h +23 -0
- data/ext/oj/scp.c +3 -14
- data/ext/oj/sparse.c +22 -70
- data/ext/oj/stream_writer.c +43 -35
- data/ext/oj/strict.c +20 -52
- data/ext/oj/string_writer.c +60 -34
- data/ext/oj/trace.h +31 -4
- data/ext/oj/usual.c +125 -150
- data/ext/oj/usual.h +69 -0
- data/ext/oj/util.h +1 -1
- data/ext/oj/val_stack.c +14 -3
- data/ext/oj/val_stack.h +8 -7
- data/ext/oj/wab.c +25 -57
- data/lib/oj/active_support_helper.rb +1 -3
- data/lib/oj/bag.rb +7 -1
- data/lib/oj/easy_hash.rb +4 -5
- data/lib/oj/error.rb +0 -1
- data/lib/oj/json.rb +162 -150
- data/lib/oj/mimic.rb +6 -2
- data/lib/oj/state.rb +9 -6
- data/lib/oj/version.rb +1 -2
- data/lib/oj.rb +2 -0
- data/pages/Compatibility.md +1 -1
- data/pages/InstallOptions.md +20 -0
- data/pages/Options.md +10 -0
- data/test/_test_active.rb +8 -9
- data/test/_test_active_mimic.rb +7 -8
- data/test/_test_mimic_rails.rb +17 -20
- data/test/activerecord/result_test.rb +5 -6
- data/test/files.rb +15 -15
- data/test/foo.rb +9 -72
- data/test/helper.rb +11 -8
- data/test/isolated/shared.rb +3 -2
- data/test/json_gem/json_addition_test.rb +2 -2
- data/test/json_gem/json_common_interface_test.rb +8 -6
- data/test/json_gem/json_encoding_test.rb +0 -0
- data/test/json_gem/json_ext_parser_test.rb +1 -0
- data/test/json_gem/json_fixtures_test.rb +3 -2
- data/test/json_gem/json_generator_test.rb +53 -37
- data/test/json_gem/json_generic_object_test.rb +11 -11
- data/test/json_gem/json_parser_test.rb +47 -47
- data/test/json_gem/json_string_matching_test.rb +9 -9
- data/test/json_gem/test_helper.rb +7 -3
- data/test/mem.rb +13 -12
- data/test/perf.rb +21 -26
- data/test/perf_compat.rb +31 -33
- data/test/perf_dump.rb +28 -28
- data/test/perf_fast.rb +80 -82
- data/test/perf_file.rb +27 -29
- data/test/perf_object.rb +65 -69
- data/test/perf_once.rb +12 -11
- data/test/perf_parser.rb +42 -48
- data/test/perf_saj.rb +46 -54
- data/test/perf_scp.rb +57 -69
- data/test/perf_simple.rb +41 -39
- data/test/perf_strict.rb +68 -70
- data/test/perf_wab.rb +67 -69
- data/test/prec.rb +5 -5
- data/test/sample/change.rb +0 -1
- data/test/sample/dir.rb +0 -1
- data/test/sample/doc.rb +0 -1
- data/test/sample/file.rb +0 -1
- data/test/sample/group.rb +0 -1
- data/test/sample/hasprops.rb +0 -1
- data/test/sample/layer.rb +0 -1
- data/test/sample/rect.rb +0 -1
- data/test/sample/shape.rb +0 -1
- data/test/sample/text.rb +0 -1
- data/test/sample.rb +16 -16
- data/test/sample_json.rb +8 -8
- data/test/test_compat.rb +80 -53
- data/test/test_custom.rb +73 -51
- data/test/test_debian.rb +7 -10
- data/test/test_fast.rb +86 -90
- data/test/test_file.rb +28 -35
- data/test/test_gc.rb +16 -5
- data/test/test_generate.rb +5 -5
- data/test/test_hash.rb +4 -4
- data/test/test_integer_range.rb +9 -9
- data/test/test_null.rb +20 -20
- data/test/test_object.rb +94 -96
- data/test/test_parser.rb +6 -22
- data/test/test_parser_debug.rb +27 -0
- data/test/test_parser_saj.rb +61 -22
- data/test/test_parser_usual.rb +16 -6
- data/test/test_rails.rb +2 -2
- data/test/test_saj.rb +10 -8
- data/test/test_scp.rb +37 -39
- data/test/test_strict.rb +40 -32
- data/test/test_various.rb +148 -100
- data/test/test_wab.rb +48 -44
- data/test/test_writer.rb +47 -47
- data/test/tests.rb +13 -4
- data/test/tests_mimic.rb +12 -3
- data/test/tests_mimic_addition.rb +12 -3
- metadata +36 -27
- data/test/activesupport4/decoding_test.rb +0 -108
- data/test/activesupport4/encoding_test.rb +0 -531
- data/test/activesupport4/test_helper.rb +0 -41
- data/test/activesupport5/abstract_unit.rb +0 -45
- data/test/activesupport5/decoding_test.rb +0 -133
- data/test/activesupport5/encoding_test.rb +0 -500
- data/test/activesupport5/encoding_test_cases.rb +0 -98
- data/test/activesupport5/test_helper.rb +0 -72
- data/test/activesupport5/time_zone_test_helpers.rb +0 -39
- data/test/bar.rb +0 -11
- data/test/baz.rb +0 -16
- data/test/bug.rb +0 -16
- data/test/zoo.rb +0 -13
data/ext/oj/object.c
CHANGED
@@ -67,9 +67,9 @@ static VALUE str_to_value(ParseInfo pi, const char *str, size_t len, const char
|
|
67
67
|
|
68
68
|
// The much faster approach (4x faster)
|
69
69
|
static int parse_num(const char *str, const char *end, int cnt) {
|
70
|
-
int
|
70
|
+
int n = 0;
|
71
71
|
char c;
|
72
|
-
int
|
72
|
+
int i;
|
73
73
|
|
74
74
|
for (i = cnt; 0 < i; i--, str++) {
|
75
75
|
c = *str;
|
@@ -83,9 +83,10 @@ 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
|
87
|
-
const char *end
|
88
|
-
|
86
|
+
VALUE args[7];
|
87
|
+
const char *end = str + len;
|
88
|
+
const char *orig = str;
|
89
|
+
int n;
|
89
90
|
|
90
91
|
// year
|
91
92
|
if (0 > (n = parse_num(str, end, 4))) {
|
@@ -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
|
}
|
@@ -269,19 +277,10 @@ static int hat_num(ParseInfo pi, Val parent, Val kval, NumInfo ni) {
|
|
269
277
|
// match the expected value.
|
270
278
|
parent->val = rb_funcall2(parent->val, oj_utc_id, 0, 0);
|
271
279
|
} else if (ni->has_exp) {
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
sec_as_time(t, &ti);
|
277
|
-
args[0] = LONG2NUM((long)(ti.year));
|
278
|
-
args[1] = LONG2NUM(ti.mon);
|
279
|
-
args[2] = LONG2NUM(ti.day);
|
280
|
-
args[3] = LONG2NUM(ti.hour);
|
281
|
-
args[4] = LONG2NUM(ti.min);
|
282
|
-
args[5] = rb_float_new((double)ti.sec + ((double)nsec + 0.5) / 1000000000.0);
|
283
|
-
args[6] = LONG2NUM(ni->exp);
|
284
|
-
parent->val = rb_funcall2(rb_cTime, oj_new_id, 7, args);
|
280
|
+
struct timespec ts;
|
281
|
+
ts.tv_sec = ni->i;
|
282
|
+
ts.tv_nsec = nsec;
|
283
|
+
parent->val = rb_time_timespec_new(&ts, (int)ni->exp);
|
285
284
|
} else {
|
286
285
|
parent->val = rb_time_nano_new(ni->i, (long)nsec);
|
287
286
|
}
|
@@ -317,7 +316,7 @@ static int hat_value(ParseInfo pi, Val parent, const char *key, size_t klen, vol
|
|
317
316
|
oj_set_error_at(pi, oj_parse_error_class, __FILE__, __LINE__, "Invalid struct data");
|
318
317
|
return 1;
|
319
318
|
}
|
320
|
-
e1 = *
|
319
|
+
e1 = *RARRAY_CONST_PTR(value);
|
321
320
|
// check for anonymous Struct
|
322
321
|
if (T_ARRAY == rb_type(e1)) {
|
323
322
|
VALUE args[1024];
|
@@ -331,40 +330,44 @@ static int hat_value(ParseInfo pi, Val parent, const char *key, size_t klen, vol
|
|
331
330
|
sc = rb_funcall2(rb_cStruct, oj_new_id, cnt, args);
|
332
331
|
} else {
|
333
332
|
// If struct is not defined then we let this fail and raise an exception.
|
334
|
-
sc = oj_name2struct(pi, *
|
333
|
+
sc = oj_name2struct(pi, *RARRAY_CONST_PTR(value), rb_eArgError);
|
335
334
|
}
|
336
|
-
|
337
|
-
|
338
|
-
|
335
|
+
if (sc == rb_cRange) {
|
336
|
+
parent->val = rb_class_new_instance(len - 1, RARRAY_CONST_PTR(value) + 1, rb_cRange);
|
337
|
+
} else {
|
338
|
+
// Create a properly initialized struct instance without calling the initialize method.
|
339
|
+
parent->val = rb_obj_alloc(sc);
|
340
|
+
// If the JSON array has more entries than the struct class allows, we record an error.
|
339
341
|
#ifdef RSTRUCT_LEN
|
340
342
|
#if RSTRUCT_LEN_RETURNS_INTEGER_OBJECT
|
341
|
-
|
343
|
+
slen = (int)NUM2LONG(RSTRUCT_LEN(parent->val));
|
342
344
|
#else // RSTRUCT_LEN_RETURNS_INTEGER_OBJECT
|
343
|
-
|
345
|
+
slen = (int)RSTRUCT_LEN(parent->val);
|
344
346
|
#endif // RSTRUCT_LEN_RETURNS_INTEGER_OBJECT
|
345
347
|
#else
|
346
|
-
|
348
|
+
slen = FIX2INT(rb_funcall2(parent->val, oj_length_id, 0, 0));
|
347
349
|
#endif
|
348
|
-
|
349
|
-
|
350
|
-
|
351
|
-
|
352
|
-
|
350
|
+
// MRI >= 1.9
|
351
|
+
if (len - 1 > slen) {
|
352
|
+
oj_set_error_at(pi, oj_parse_error_class, __FILE__, __LINE__, "Invalid struct data");
|
353
|
+
} else {
|
354
|
+
int i;
|
353
355
|
|
354
|
-
|
355
|
-
|
356
|
+
for (i = 0; i < len - 1; i++) {
|
357
|
+
rb_struct_aset(parent->val, INT2FIX(i), RARRAY_CONST_PTR(value)[i + 1]);
|
358
|
+
}
|
356
359
|
}
|
357
360
|
}
|
358
361
|
return 1;
|
359
362
|
} else if (3 <= klen && '#' == key[1]) {
|
360
|
-
volatile VALUE *a;
|
363
|
+
volatile const VALUE *a;
|
361
364
|
|
362
365
|
if (2 != len) {
|
363
366
|
oj_set_error_at(pi, oj_parse_error_class, __FILE__, __LINE__, "invalid hash pair");
|
364
367
|
return 1;
|
365
368
|
}
|
366
369
|
parent->val = rb_hash_new();
|
367
|
-
a =
|
370
|
+
a = RARRAY_CONST_PTR(value);
|
368
371
|
rb_hash_aset(parent->val, *a, a[1]);
|
369
372
|
|
370
373
|
return 1;
|
@@ -374,11 +377,17 @@ static int hat_value(ParseInfo pi, Val parent, const char *key, size_t klen, vol
|
|
374
377
|
}
|
375
378
|
|
376
379
|
void oj_set_obj_ivar(Val parent, Val kval, VALUE value) {
|
377
|
-
|
380
|
+
if (kval->klen == 5 && strncmp("~mesg", kval->key, 5) == 0 && rb_obj_is_kind_of(parent->val, rb_eException)) {
|
381
|
+
parent->val = rb_funcall(parent->val, rb_intern("exception"), 1, value);
|
382
|
+
} else if (kval->klen == 3 && strncmp("~bt", kval->key, 3) == 0 && rb_obj_is_kind_of(parent->val, rb_eException)) {
|
383
|
+
rb_funcall(parent->val, rb_intern("set_backtrace"), 1, value);
|
384
|
+
} else {
|
385
|
+
rb_ivar_set(parent->val, oj_attr_intern(kval->key, kval->klen), value);
|
386
|
+
}
|
378
387
|
}
|
379
388
|
|
380
389
|
static void hash_set_cstr(ParseInfo pi, Val kval, const char *str, size_t len, const char *orig) {
|
381
|
-
const char
|
390
|
+
const char *key = kval->key;
|
382
391
|
int klen = kval->klen;
|
383
392
|
Val parent = stack_peek(&pi->stack);
|
384
393
|
volatile VALUE rval = Qnil;
|
@@ -445,13 +454,11 @@ WHICH_TYPE:
|
|
445
454
|
rb_class2name(rb_obj_class(parent->val)));
|
446
455
|
return;
|
447
456
|
}
|
448
|
-
|
449
|
-
oj_trace_parse_call("set_string", pi, __FILE__, __LINE__, rval);
|
450
|
-
}
|
457
|
+
TRACE_PARSE_CALL(pi->options.trace, "set_string", pi, rval);
|
451
458
|
}
|
452
459
|
|
453
460
|
static void hash_set_num(ParseInfo pi, Val kval, NumInfo ni) {
|
454
|
-
const char
|
461
|
+
const char *key = kval->key;
|
455
462
|
int klen = kval->klen;
|
456
463
|
Val parent = stack_peek(&pi->stack);
|
457
464
|
volatile VALUE rval = Qnil;
|
@@ -516,9 +523,7 @@ WHICH_TYPE:
|
|
516
523
|
rb_class2name(rb_obj_class(parent->val)));
|
517
524
|
return;
|
518
525
|
}
|
519
|
-
|
520
|
-
oj_trace_parse_call("add_number", pi, __FILE__, __LINE__, rval);
|
521
|
-
}
|
526
|
+
TRACE_PARSE_CALL(pi->options.trace, "add_number", pi, rval);
|
522
527
|
}
|
523
528
|
|
524
529
|
static void hash_set_value(ParseInfo pi, Val kval, VALUE value) {
|
@@ -544,8 +549,8 @@ WHICH_TYPE:
|
|
544
549
|
}
|
545
550
|
} else {
|
546
551
|
if (3 <= klen && '^' == *key && '#' == key[1] && T_ARRAY == rb_type(value)) {
|
547
|
-
long
|
548
|
-
volatile VALUE *a =
|
552
|
+
long len = RARRAY_LEN(value);
|
553
|
+
volatile const VALUE *a = RARRAY_CONST_PTR(value);
|
549
554
|
|
550
555
|
if (2 != len) {
|
551
556
|
oj_set_error_at(pi, oj_parse_error_class, __FILE__, __LINE__, "invalid hash pair");
|
@@ -602,15 +607,11 @@ WHICH_TYPE:
|
|
602
607
|
rb_class2name(rb_obj_class(parent->val)));
|
603
608
|
return;
|
604
609
|
}
|
605
|
-
|
606
|
-
oj_trace_parse_call("add_value", pi, __FILE__, __LINE__, value);
|
607
|
-
}
|
610
|
+
TRACE_PARSE_CALL(pi->options.trace, "add_value", pi, value);
|
608
611
|
}
|
609
612
|
|
610
613
|
static VALUE start_hash(ParseInfo pi) {
|
611
|
-
|
612
|
-
oj_trace_parse_in("start_hash", pi, __FILE__, __LINE__);
|
613
|
-
}
|
614
|
+
TRACE_PARSE_IN(pi->options.trace, "start_hash", pi);
|
614
615
|
return Qnil;
|
615
616
|
}
|
616
617
|
|
@@ -626,9 +627,7 @@ static void end_hash(ParseInfo pi) {
|
|
626
627
|
oj_odd_free(oa);
|
627
628
|
parent->odd_args = NULL;
|
628
629
|
}
|
629
|
-
|
630
|
-
oj_trace_parse_hash_end(pi, __FILE__, __LINE__);
|
631
|
-
}
|
630
|
+
TRACE_PARSE_HASH_END(pi->options.trace, pi);
|
632
631
|
}
|
633
632
|
|
634
633
|
static void array_append_cstr(ParseInfo pi, const char *str, size_t len, const char *orig) {
|
@@ -654,32 +653,24 @@ static void array_append_cstr(ParseInfo pi, const char *str, size_t len, const c
|
|
654
653
|
}
|
655
654
|
rval = str_to_value(pi, str, len, orig);
|
656
655
|
rb_ary_push(stack_peek(&pi->stack)->val, rval);
|
657
|
-
|
658
|
-
oj_trace_parse_call("append_string", pi, __FILE__, __LINE__, rval);
|
659
|
-
}
|
656
|
+
TRACE_PARSE_CALL(pi->options.trace, "append_string", pi, rval);
|
660
657
|
}
|
661
658
|
|
662
659
|
static void array_append_num(ParseInfo pi, NumInfo ni) {
|
663
660
|
volatile VALUE rval = oj_num_as_value(ni);
|
664
661
|
|
665
662
|
rb_ary_push(stack_peek(&pi->stack)->val, rval);
|
666
|
-
|
667
|
-
oj_trace_parse_call("append_number", pi, __FILE__, __LINE__, rval);
|
668
|
-
}
|
663
|
+
TRACE_PARSE_CALL(pi->options.trace, "append_number", pi, rval);
|
669
664
|
}
|
670
665
|
|
671
666
|
static void add_cstr(ParseInfo pi, const char *str, size_t len, const char *orig) {
|
672
667
|
pi->stack.head->val = str_to_value(pi, str, len, orig);
|
673
|
-
|
674
|
-
oj_trace_parse_call("add_string", pi, __FILE__, __LINE__, pi->stack.head->val);
|
675
|
-
}
|
668
|
+
TRACE_PARSE_CALL(pi->options.trace, "add_string", pi, pi->stack.head->val);
|
676
669
|
}
|
677
670
|
|
678
671
|
static void add_num(ParseInfo pi, NumInfo ni) {
|
679
672
|
pi->stack.head->val = oj_num_as_value(ni);
|
680
|
-
|
681
|
-
oj_trace_parse_call("add_num", pi, __FILE__, __LINE__, pi->stack.head->val);
|
682
|
-
}
|
673
|
+
TRACE_PARSE_CALL(pi->options.trace, "add_num", pi, pi->stack.head->val);
|
683
674
|
}
|
684
675
|
|
685
676
|
void oj_set_object_callbacks(ParseInfo pi) {
|
data/ext/oj/odd.c
CHANGED
@@ -5,6 +5,8 @@
|
|
5
5
|
|
6
6
|
#include <string.h>
|
7
7
|
|
8
|
+
#include "mem.h"
|
9
|
+
|
8
10
|
static Odd odds = NULL;
|
9
11
|
static ID sec_id;
|
10
12
|
static ID sec_fraction_id;
|
@@ -68,7 +70,7 @@ void print_all_odds(const char *label) {
|
|
68
70
|
}
|
69
71
|
|
70
72
|
static Odd odd_create(void) {
|
71
|
-
Odd odd =
|
73
|
+
Odd odd = OJ_R_ALLOC(struct _odd);
|
72
74
|
|
73
75
|
memset(odd, 0, sizeof(struct _odd));
|
74
76
|
odd->next = odds;
|
@@ -172,7 +174,7 @@ Odd oj_get_oddc(const char *classname, size_t len) {
|
|
172
174
|
}
|
173
175
|
|
174
176
|
OddArgs oj_odd_alloc_args(Odd odd) {
|
175
|
-
OddArgs oa =
|
177
|
+
OddArgs oa = OJ_R_ALLOC_N(struct _oddArgs, 1);
|
176
178
|
VALUE *a;
|
177
179
|
int i;
|
178
180
|
|
@@ -184,7 +186,7 @@ OddArgs oj_odd_alloc_args(Odd odd) {
|
|
184
186
|
}
|
185
187
|
|
186
188
|
void oj_odd_free(OddArgs args) {
|
187
|
-
|
189
|
+
OJ_R_FREE(args);
|
188
190
|
}
|
189
191
|
|
190
192
|
int oj_odd_set_arg(OddArgs args, const char *key, size_t klen, VALUE value) {
|
@@ -210,7 +212,7 @@ void oj_reg_odd(VALUE clas, VALUE create_object, VALUE create_method, int mcnt,
|
|
210
212
|
odd = odd_create();
|
211
213
|
odd->clas = clas;
|
212
214
|
rb_gc_register_mark_object(odd->clas);
|
213
|
-
if (NULL == (odd->classname =
|
215
|
+
if (NULL == (odd->classname = OJ_STRDUP(rb_class2name(clas)))) {
|
214
216
|
rb_raise(rb_eNoMemError, "for class name.");
|
215
217
|
}
|
216
218
|
odd->clen = strlen(odd->classname);
|
@@ -224,13 +226,13 @@ void oj_reg_odd(VALUE clas, VALUE create_object, VALUE create_method, int mcnt,
|
|
224
226
|
*fp = 0;
|
225
227
|
switch (rb_type(*members)) {
|
226
228
|
case T_STRING:
|
227
|
-
if (NULL == (*np =
|
229
|
+
if (NULL == (*np = OJ_STRDUP(RSTRING_PTR(*members)))) {
|
228
230
|
rb_raise(rb_eNoMemError, "for attribute name.");
|
229
231
|
}
|
230
232
|
break;
|
231
233
|
case T_SYMBOL:
|
232
234
|
// The symbol can move and invalidate the name so make a copy.
|
233
|
-
if (NULL == (*np =
|
235
|
+
if (NULL == (*np = OJ_STRDUP(rb_id2name(SYM2ID(*members))))) {
|
234
236
|
rb_raise(rb_eNoMemError, "for attribute name.");
|
235
237
|
}
|
236
238
|
break;
|
data/ext/oj/odd.h
CHANGED
@@ -14,7 +14,7 @@ typedef VALUE (*AttrGetFunc)(VALUE obj);
|
|
14
14
|
|
15
15
|
typedef struct _odd {
|
16
16
|
struct _odd *next;
|
17
|
-
const char
|
17
|
+
const char *classname;
|
18
18
|
size_t clen;
|
19
19
|
VALUE clas; // Ruby class or module
|
20
20
|
VALUE create_obj;
|
@@ -22,15 +22,15 @@ typedef struct _odd {
|
|
22
22
|
int attr_cnt;
|
23
23
|
bool is_module;
|
24
24
|
bool raw;
|
25
|
-
const char
|
25
|
+
const char *attr_names[MAX_ODD_ARGS]; // NULL terminated attr names
|
26
26
|
ID attrs[MAX_ODD_ARGS]; // 0 terminated attr IDs
|
27
27
|
AttrGetFunc attrFuncs[MAX_ODD_ARGS];
|
28
|
-
} *
|
28
|
+
} *Odd;
|
29
29
|
|
30
30
|
typedef struct _oddArgs {
|
31
31
|
Odd odd;
|
32
32
|
VALUE args[MAX_ODD_ARGS];
|
33
|
-
} *
|
33
|
+
} *OddArgs;
|
34
34
|
|
35
35
|
extern void oj_odd_init(void);
|
36
36
|
extern Odd oj_get_odd(VALUE clas);
|