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.
Files changed (156) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +77 -0
  3. data/README.md +4 -2
  4. data/ext/oj/buf.h +7 -6
  5. data/ext/oj/cache.c +29 -26
  6. data/ext/oj/cache.h +3 -2
  7. data/ext/oj/cache8.c +10 -9
  8. data/ext/oj/circarray.c +7 -5
  9. data/ext/oj/circarray.h +2 -2
  10. data/ext/oj/code.c +5 -12
  11. data/ext/oj/code.h +2 -2
  12. data/ext/oj/compat.c +20 -60
  13. data/ext/oj/custom.c +44 -96
  14. data/ext/oj/debug.c +3 -9
  15. data/ext/oj/dump.c +69 -39
  16. data/ext/oj/dump.h +1 -4
  17. data/ext/oj/dump_compat.c +557 -592
  18. data/ext/oj/dump_leaf.c +3 -5
  19. data/ext/oj/dump_object.c +42 -48
  20. data/ext/oj/dump_strict.c +10 -22
  21. data/ext/oj/encoder.c +1 -1
  22. data/ext/oj/err.c +2 -13
  23. data/ext/oj/err.h +9 -12
  24. data/ext/oj/extconf.rb +16 -6
  25. data/ext/oj/fast.c +76 -106
  26. data/ext/oj/intern.c +63 -51
  27. data/ext/oj/intern.h +3 -7
  28. data/ext/oj/mem.c +318 -0
  29. data/ext/oj/mem.h +53 -0
  30. data/ext/oj/mimic_json.c +43 -30
  31. data/ext/oj/object.c +61 -70
  32. data/ext/oj/odd.c +8 -6
  33. data/ext/oj/odd.h +4 -4
  34. data/ext/oj/oj.c +243 -205
  35. data/ext/oj/oj.h +82 -78
  36. data/ext/oj/parse.c +123 -188
  37. data/ext/oj/parse.h +23 -24
  38. data/ext/oj/parser.c +103 -63
  39. data/ext/oj/parser.h +19 -9
  40. data/ext/oj/rails.c +68 -92
  41. data/ext/oj/reader.c +10 -15
  42. data/ext/oj/reader.h +4 -2
  43. data/ext/oj/resolve.c +3 -4
  44. data/ext/oj/rxclass.c +6 -5
  45. data/ext/oj/rxclass.h +1 -1
  46. data/ext/oj/saj.c +10 -9
  47. data/ext/oj/saj2.c +74 -92
  48. data/ext/oj/saj2.h +23 -0
  49. data/ext/oj/scp.c +3 -14
  50. data/ext/oj/sparse.c +22 -70
  51. data/ext/oj/stream_writer.c +43 -35
  52. data/ext/oj/strict.c +20 -52
  53. data/ext/oj/string_writer.c +60 -34
  54. data/ext/oj/trace.h +31 -4
  55. data/ext/oj/usual.c +125 -150
  56. data/ext/oj/usual.h +69 -0
  57. data/ext/oj/util.h +1 -1
  58. data/ext/oj/val_stack.c +14 -3
  59. data/ext/oj/val_stack.h +8 -7
  60. data/ext/oj/wab.c +25 -57
  61. data/lib/oj/active_support_helper.rb +1 -3
  62. data/lib/oj/bag.rb +7 -1
  63. data/lib/oj/easy_hash.rb +4 -5
  64. data/lib/oj/error.rb +0 -1
  65. data/lib/oj/json.rb +162 -150
  66. data/lib/oj/mimic.rb +6 -2
  67. data/lib/oj/state.rb +9 -6
  68. data/lib/oj/version.rb +1 -2
  69. data/lib/oj.rb +2 -0
  70. data/pages/Compatibility.md +1 -1
  71. data/pages/InstallOptions.md +20 -0
  72. data/pages/Options.md +10 -0
  73. data/test/_test_active.rb +8 -9
  74. data/test/_test_active_mimic.rb +7 -8
  75. data/test/_test_mimic_rails.rb +17 -20
  76. data/test/activerecord/result_test.rb +5 -6
  77. data/test/files.rb +15 -15
  78. data/test/foo.rb +9 -72
  79. data/test/helper.rb +11 -8
  80. data/test/isolated/shared.rb +3 -2
  81. data/test/json_gem/json_addition_test.rb +2 -2
  82. data/test/json_gem/json_common_interface_test.rb +8 -6
  83. data/test/json_gem/json_encoding_test.rb +0 -0
  84. data/test/json_gem/json_ext_parser_test.rb +1 -0
  85. data/test/json_gem/json_fixtures_test.rb +3 -2
  86. data/test/json_gem/json_generator_test.rb +53 -37
  87. data/test/json_gem/json_generic_object_test.rb +11 -11
  88. data/test/json_gem/json_parser_test.rb +47 -47
  89. data/test/json_gem/json_string_matching_test.rb +9 -9
  90. data/test/json_gem/test_helper.rb +7 -3
  91. data/test/mem.rb +13 -12
  92. data/test/perf.rb +21 -26
  93. data/test/perf_compat.rb +31 -33
  94. data/test/perf_dump.rb +28 -28
  95. data/test/perf_fast.rb +80 -82
  96. data/test/perf_file.rb +27 -29
  97. data/test/perf_object.rb +65 -69
  98. data/test/perf_once.rb +12 -11
  99. data/test/perf_parser.rb +42 -48
  100. data/test/perf_saj.rb +46 -54
  101. data/test/perf_scp.rb +57 -69
  102. data/test/perf_simple.rb +41 -39
  103. data/test/perf_strict.rb +68 -70
  104. data/test/perf_wab.rb +67 -69
  105. data/test/prec.rb +5 -5
  106. data/test/sample/change.rb +0 -1
  107. data/test/sample/dir.rb +0 -1
  108. data/test/sample/doc.rb +0 -1
  109. data/test/sample/file.rb +0 -1
  110. data/test/sample/group.rb +0 -1
  111. data/test/sample/hasprops.rb +0 -1
  112. data/test/sample/layer.rb +0 -1
  113. data/test/sample/rect.rb +0 -1
  114. data/test/sample/shape.rb +0 -1
  115. data/test/sample/text.rb +0 -1
  116. data/test/sample.rb +16 -16
  117. data/test/sample_json.rb +8 -8
  118. data/test/test_compat.rb +80 -53
  119. data/test/test_custom.rb +73 -51
  120. data/test/test_debian.rb +7 -10
  121. data/test/test_fast.rb +86 -90
  122. data/test/test_file.rb +28 -35
  123. data/test/test_gc.rb +16 -5
  124. data/test/test_generate.rb +5 -5
  125. data/test/test_hash.rb +4 -4
  126. data/test/test_integer_range.rb +9 -9
  127. data/test/test_null.rb +20 -20
  128. data/test/test_object.rb +94 -96
  129. data/test/test_parser.rb +6 -22
  130. data/test/test_parser_debug.rb +27 -0
  131. data/test/test_parser_saj.rb +61 -22
  132. data/test/test_parser_usual.rb +16 -6
  133. data/test/test_rails.rb +2 -2
  134. data/test/test_saj.rb +10 -8
  135. data/test/test_scp.rb +37 -39
  136. data/test/test_strict.rb +40 -32
  137. data/test/test_various.rb +148 -100
  138. data/test/test_wab.rb +48 -44
  139. data/test/test_writer.rb +47 -47
  140. data/test/tests.rb +13 -4
  141. data/test/tests_mimic.rb +12 -3
  142. data/test/tests_mimic_addition.rb +12 -3
  143. metadata +36 -27
  144. data/test/activesupport4/decoding_test.rb +0 -108
  145. data/test/activesupport4/encoding_test.rb +0 -531
  146. data/test/activesupport4/test_helper.rb +0 -41
  147. data/test/activesupport5/abstract_unit.rb +0 -45
  148. data/test/activesupport5/decoding_test.rb +0 -133
  149. data/test/activesupport5/encoding_test.rb +0 -500
  150. data/test/activesupport5/encoding_test_cases.rb +0 -98
  151. data/test/activesupport5/test_helper.rb +0 -72
  152. data/test/activesupport5/time_zone_test_helpers.rb +0 -39
  153. data/test/bar.rb +0 -11
  154. data/test/baz.rb +0 -16
  155. data/test/bug.rb +0 -16
  156. 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 n = 0;
70
+ int n = 0;
71
71
  char c;
72
- int i;
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 args[8];
87
- const char *end = str + len;
88
- int n;
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 nsec = 0;
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
- nsec = nsec * 10 + (c - '0');
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] = rb_float_new((double)n + ((double)nsec + 0.5) / 1000000000.0);
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
- int64_t t = (int64_t)(ni->i + ni->exp);
273
- struct _timeInfo ti;
274
- VALUE args[8];
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 = *RARRAY_PTR(value);
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, *RARRAY_PTR(value), rb_eArgError);
333
+ sc = oj_name2struct(pi, *RARRAY_CONST_PTR(value), rb_eArgError);
335
334
  }
336
- // Create a properly initialized struct instance without calling the initialize method.
337
- parent->val = rb_obj_alloc(sc);
338
- // If the JSON array has more entries than the struct class allows, we record an error.
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
- slen = (int)NUM2LONG(RSTRUCT_LEN(parent->val));
343
+ slen = (int)NUM2LONG(RSTRUCT_LEN(parent->val));
342
344
  #else // RSTRUCT_LEN_RETURNS_INTEGER_OBJECT
343
- slen = (int)RSTRUCT_LEN(parent->val);
345
+ slen = (int)RSTRUCT_LEN(parent->val);
344
346
  #endif // RSTRUCT_LEN_RETURNS_INTEGER_OBJECT
345
347
  #else
346
- slen = FIX2INT(rb_funcall2(parent->val, oj_length_id, 0, 0));
348
+ slen = FIX2INT(rb_funcall2(parent->val, oj_length_id, 0, 0));
347
349
  #endif
348
- // MRI >= 1.9
349
- if (len - 1 > slen) {
350
- oj_set_error_at(pi, oj_parse_error_class, __FILE__, __LINE__, "Invalid struct data");
351
- } else {
352
- int i;
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
- for (i = 0; i < len - 1; i++) {
355
- rb_struct_aset(parent->val, INT2FIX(i), RARRAY_PTR(value)[i + 1]);
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 = RARRAY_PTR(value);
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
- rb_ivar_set(parent->val, oj_attr_intern(kval->key, kval->klen), value);
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 * key = kval->key;
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
- if (RB_UNLIKELY(Yes == pi->options.trace)) {
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 * key = kval->key;
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
- if (RB_UNLIKELY(Yes == pi->options.trace)) {
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 len = RARRAY_LEN(value);
548
- volatile VALUE *a = RARRAY_PTR(value);
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
- if (RB_UNLIKELY(Yes == pi->options.trace)) {
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
- if (RB_UNLIKELY(Yes == pi->options.trace)) {
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
- if (RB_UNLIKELY(Yes == pi->options.trace)) {
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
- if (RB_UNLIKELY(Yes == pi->options.trace)) {
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
- if (RB_UNLIKELY(Yes == pi->options.trace)) {
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
- if (RB_UNLIKELY(Yes == pi->options.trace)) {
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
- if (RB_UNLIKELY(Yes == pi->options.trace)) {
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 = ALLOC(struct _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 = ALLOC_N(struct _oddArgs, 1);
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
- xfree(args);
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 = strdup(rb_class2name(clas)))) {
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 = strdup(RSTRING_PTR(*members)))) {
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 = strdup(rb_id2name(SYM2ID(*members))))) {
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 * classname;
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 * attr_names[MAX_ODD_ARGS]; // NULL terminated attr names
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
- } * Odd;
28
+ } *Odd;
29
29
 
30
30
  typedef struct _oddArgs {
31
31
  Odd odd;
32
32
  VALUE args[MAX_ODD_ARGS];
33
- } * OddArgs;
33
+ } *OddArgs;
34
34
 
35
35
  extern void oj_odd_init(void);
36
36
  extern Odd oj_get_odd(VALUE clas);