oj 3.13.9 → 3.16.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (161) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +101 -0
  3. data/README.md +13 -2
  4. data/ext/oj/buf.h +11 -6
  5. data/ext/oj/cache.c +25 -24
  6. data/ext/oj/cache8.c +10 -9
  7. data/ext/oj/circarray.c +8 -6
  8. data/ext/oj/circarray.h +2 -2
  9. data/ext/oj/code.c +19 -33
  10. data/ext/oj/code.h +2 -2
  11. data/ext/oj/compat.c +20 -60
  12. data/ext/oj/custom.c +76 -155
  13. data/ext/oj/debug.c +3 -9
  14. data/ext/oj/dump.c +203 -213
  15. data/ext/oj/dump.h +26 -12
  16. data/ext/oj/dump_compat.c +565 -642
  17. data/ext/oj/dump_leaf.c +17 -63
  18. data/ext/oj/dump_object.c +59 -181
  19. data/ext/oj/dump_strict.c +24 -48
  20. data/ext/oj/encoder.c +43 -0
  21. data/ext/oj/err.c +2 -13
  22. data/ext/oj/err.h +9 -12
  23. data/ext/oj/extconf.rb +18 -7
  24. data/ext/oj/fast.c +83 -108
  25. data/ext/oj/intern.c +52 -50
  26. data/ext/oj/intern.h +4 -8
  27. data/ext/oj/mem.c +318 -0
  28. data/ext/oj/mem.h +53 -0
  29. data/ext/oj/mimic_json.c +104 -81
  30. data/ext/oj/object.c +50 -67
  31. data/ext/oj/odd.c +89 -67
  32. data/ext/oj/odd.h +15 -15
  33. data/ext/oj/oj.c +171 -106
  34. data/ext/oj/oj.h +96 -74
  35. data/ext/oj/parse.c +169 -189
  36. data/ext/oj/parse.h +23 -24
  37. data/ext/oj/parser.c +89 -34
  38. data/ext/oj/parser.h +20 -9
  39. data/ext/oj/rails.c +86 -151
  40. data/ext/oj/rails.h +1 -1
  41. data/ext/oj/reader.c +12 -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 +21 -32
  47. data/ext/oj/saj2.c +329 -93
  48. data/ext/oj/saj2.h +23 -0
  49. data/ext/oj/scp.c +3 -14
  50. data/ext/oj/sparse.c +26 -70
  51. data/ext/oj/stream_writer.c +12 -22
  52. data/ext/oj/strict.c +20 -52
  53. data/ext/oj/string_writer.c +21 -22
  54. data/ext/oj/trace.h +31 -4
  55. data/ext/oj/usual.c +105 -150
  56. data/ext/oj/usual.h +68 -0
  57. data/ext/oj/util.h +1 -1
  58. data/ext/oj/val_stack.c +1 -1
  59. data/ext/oj/val_stack.h +8 -7
  60. data/ext/oj/validate.c +21 -26
  61. data/ext/oj/wab.c +32 -69
  62. data/lib/oj/active_support_helper.rb +1 -3
  63. data/lib/oj/bag.rb +7 -1
  64. data/lib/oj/easy_hash.rb +4 -5
  65. data/lib/oj/error.rb +0 -1
  66. data/lib/oj/json.rb +162 -150
  67. data/lib/oj/mimic.rb +6 -2
  68. data/lib/oj/saj.rb +20 -6
  69. data/lib/oj/state.rb +9 -6
  70. data/lib/oj/version.rb +1 -2
  71. data/lib/oj.rb +2 -0
  72. data/pages/Compatibility.md +1 -1
  73. data/pages/InstallOptions.md +20 -0
  74. data/pages/JsonGem.md +15 -0
  75. data/pages/Modes.md +6 -3
  76. data/pages/Options.md +10 -0
  77. data/pages/Rails.md +12 -0
  78. data/test/_test_active.rb +8 -9
  79. data/test/_test_active_mimic.rb +7 -8
  80. data/test/_test_mimic_rails.rb +17 -20
  81. data/test/activerecord/result_test.rb +5 -6
  82. data/test/{activesupport5 → activesupport7}/abstract_unit.rb +16 -12
  83. data/test/{activesupport5 → activesupport7}/decoding_test.rb +2 -10
  84. data/test/{activesupport5 → activesupport7}/encoding_test.rb +20 -34
  85. data/test/{activesupport5 → activesupport7}/encoding_test_cases.rb +6 -0
  86. data/test/{activesupport5 → activesupport7}/time_zone_test_helpers.rb +8 -0
  87. data/test/files.rb +15 -15
  88. data/test/foo.rb +15 -15
  89. data/test/helper.rb +11 -8
  90. data/test/isolated/shared.rb +3 -2
  91. data/test/json_gem/json_addition_test.rb +2 -2
  92. data/test/json_gem/json_common_interface_test.rb +8 -6
  93. data/test/json_gem/json_encoding_test.rb +0 -0
  94. data/test/json_gem/json_ext_parser_test.rb +1 -0
  95. data/test/json_gem/json_fixtures_test.rb +3 -2
  96. data/test/json_gem/json_generator_test.rb +49 -37
  97. data/test/json_gem/json_generic_object_test.rb +11 -11
  98. data/test/json_gem/json_parser_test.rb +54 -47
  99. data/test/json_gem/json_string_matching_test.rb +9 -9
  100. data/test/json_gem/test_helper.rb +7 -3
  101. data/test/mem.rb +13 -12
  102. data/test/perf.rb +21 -26
  103. data/test/perf_compat.rb +31 -33
  104. data/test/perf_dump.rb +50 -0
  105. data/test/perf_fast.rb +80 -82
  106. data/test/perf_file.rb +27 -29
  107. data/test/perf_object.rb +65 -69
  108. data/test/perf_once.rb +12 -11
  109. data/test/perf_parser.rb +42 -48
  110. data/test/perf_saj.rb +46 -54
  111. data/test/perf_scp.rb +57 -69
  112. data/test/perf_simple.rb +41 -39
  113. data/test/perf_strict.rb +68 -70
  114. data/test/perf_wab.rb +67 -69
  115. data/test/prec.rb +3 -3
  116. data/test/sample/change.rb +0 -1
  117. data/test/sample/dir.rb +0 -1
  118. data/test/sample/doc.rb +0 -1
  119. data/test/sample/file.rb +0 -1
  120. data/test/sample/group.rb +0 -1
  121. data/test/sample/hasprops.rb +0 -1
  122. data/test/sample/layer.rb +0 -1
  123. data/test/sample/rect.rb +0 -1
  124. data/test/sample/shape.rb +0 -1
  125. data/test/sample/text.rb +0 -1
  126. data/test/sample.rb +16 -16
  127. data/test/sample_json.rb +8 -8
  128. data/test/test_compat.rb +95 -43
  129. data/test/test_custom.rb +72 -51
  130. data/test/test_debian.rb +7 -10
  131. data/test/test_fast.rb +102 -87
  132. data/test/test_file.rb +41 -30
  133. data/test/test_gc.rb +16 -5
  134. data/test/test_generate.rb +5 -5
  135. data/test/test_hash.rb +4 -4
  136. data/test/test_integer_range.rb +9 -9
  137. data/test/test_null.rb +20 -20
  138. data/test/test_object.rb +85 -96
  139. data/test/test_parser.rb +6 -22
  140. data/test/test_parser_debug.rb +27 -0
  141. data/test/test_parser_saj.rb +115 -23
  142. data/test/test_parser_usual.rb +6 -6
  143. data/test/test_rails.rb +2 -2
  144. data/test/test_saj.rb +10 -8
  145. data/test/test_scp.rb +37 -39
  146. data/test/test_strict.rb +40 -32
  147. data/test/test_various.rb +163 -84
  148. data/test/test_wab.rb +48 -44
  149. data/test/test_writer.rb +47 -47
  150. data/test/tests.rb +13 -5
  151. data/test/tests_mimic.rb +12 -3
  152. data/test/tests_mimic_addition.rb +12 -3
  153. metadata +34 -144
  154. data/test/activesupport4/decoding_test.rb +0 -108
  155. data/test/activesupport4/encoding_test.rb +0 -531
  156. data/test/activesupport4/test_helper.rb +0 -41
  157. data/test/activesupport5/test_helper.rb +0 -72
  158. data/test/bar.rb +0 -16
  159. data/test/baz.rb +0 -16
  160. data/test/bug.rb +0 -16
  161. data/test/zoo.rb +0 -13
data/ext/oj/rails.c CHANGED
@@ -5,6 +5,7 @@
5
5
 
6
6
  #include "code.h"
7
7
  #include "encode.h"
8
+ #include "mem.h"
8
9
  #include "trace.h"
9
10
  #include "util.h"
10
11
 
@@ -15,7 +16,7 @@ typedef struct _encoder {
15
16
  struct _rOptTable ropts;
16
17
  struct _options opts;
17
18
  VALUE arg;
18
- } * Encoder;
19
+ } *Encoder;
19
20
 
20
21
  bool oj_rails_hash_opt = false;
21
22
  bool oj_rails_array_opt = false;
@@ -76,7 +77,7 @@ static ROptTable copy_opts(ROptTable src, ROptTable dest) {
76
77
  if (NULL == src->table) {
77
78
  dest->table = NULL;
78
79
  } else {
79
- dest->table = ALLOC_N(struct _rOpt, dest->alen);
80
+ dest->table = OJ_R_ALLOC_N(struct _rOpt, dest->alen);
80
81
  memcpy(dest->table, src->table, sizeof(struct _rOpt) * dest->alen);
81
82
  }
82
83
  return NULL;
@@ -140,7 +141,7 @@ static void dump_struct(VALUE obj, int depth, Out out, bool as_ok) {
140
141
  int cnt;
141
142
  int i;
142
143
  int len;
143
- const char * name;
144
+ const char *name;
144
145
 
145
146
  #ifdef RSTRUCT_LEN
146
147
  #if RSTRUCT_LEN_RETURNS_INTEGER_OBJECT
@@ -157,7 +158,7 @@ static void dump_struct(VALUE obj, int depth, Out out, bool as_ok) {
157
158
  assure_size(out, 2);
158
159
  *out->cur++ = '{';
159
160
  for (i = 0; i < cnt; i++) {
160
- volatile VALUE s = rb_sym2str(rb_ary_entry(ma, i));
161
+ volatile VALUE s = rb_sym2str(RARRAY_AREF(ma, i));
161
162
 
162
163
  name = RSTRING_PTR(s);
163
164
  len = (int)RSTRING_LEN(s);
@@ -167,17 +168,14 @@ static void dump_struct(VALUE obj, int depth, Out out, bool as_ok) {
167
168
  }
168
169
  fill_indent(out, d3);
169
170
  *out->cur++ = '"';
170
- memcpy(out->cur, name, len);
171
- out->cur += len;
171
+ APPEND_CHARS(out->cur, name, len);
172
172
  *out->cur++ = '"';
173
173
  if (0 < out->opts->dump_opts.before_size) {
174
- strcpy(out->cur, out->opts->dump_opts.before_sep);
175
- out->cur += out->opts->dump_opts.before_size;
174
+ APPEND_CHARS(out->cur, out->opts->dump_opts.before_sep, out->opts->dump_opts.before_size);
176
175
  }
177
176
  *out->cur++ = ':';
178
177
  if (0 < out->opts->dump_opts.after_size) {
179
- strcpy(out->cur, out->opts->dump_opts.after_sep);
180
- out->cur += out->opts->dump_opts.after_size;
178
+ APPEND_CHARS(out->cur, out->opts->dump_opts.after_sep, out->opts->dump_opts.after_size);
181
179
  }
182
180
  #ifdef RSTRUCT_LEN
183
181
  v = RSTRUCT_GET(obj, i);
@@ -201,8 +199,8 @@ static void dump_enumerable(VALUE obj, int depth, Out out, bool as_ok) {
201
199
  }
202
200
 
203
201
  static void dump_bigdecimal(VALUE obj, int depth, Out out, bool as_ok) {
204
- volatile VALUE rstr = rb_funcall(obj, oj_to_s_id, 0);
205
- const char * str = RSTRING_PTR(rstr);
202
+ volatile VALUE rstr = oj_safe_string_convert(obj);
203
+ const char *str = RSTRING_PTR(rstr);
206
204
 
207
205
  if ('I' == *str || 'N' == *str || ('-' == *str && 'I' == str[1])) {
208
206
  oj_dump_nil(Qnil, depth, out, false);
@@ -265,14 +263,7 @@ static void dump_sec_nano(VALUE obj, int64_t sec, long nsec, Out out) {
265
263
  tzmin);
266
264
  } else if (0 == out->opts->sec_prec) {
267
265
  if (0 == tzsecs && rb_funcall2(obj, oj_utcq_id, 0, 0)) {
268
- len = sprintf(buf,
269
- "%04d-%02d-%02dT%02d:%02d:%02dZ",
270
- ti.year,
271
- ti.mon,
272
- ti.day,
273
- ti.hour,
274
- ti.min,
275
- ti.sec);
266
+ len = sprintf(buf, "%04d-%02d-%02dT%02d:%02d:%02dZ", ti.year, ti.mon, ti.day, ti.hour, ti.min, ti.sec);
276
267
  } else {
277
268
  len = sprintf(buf,
278
269
  "%04d-%02d-%02dT%02d:%02d:%02d%c%02d:%02d",
@@ -303,18 +294,7 @@ static void dump_sec_nano(VALUE obj, int64_t sec, long nsec, Out out) {
303
294
  format[32] = '0' + out->opts->sec_prec;
304
295
  len -= 9 - out->opts->sec_prec;
305
296
  }
306
- len = sprintf(buf,
307
- format,
308
- ti.year,
309
- ti.mon,
310
- ti.day,
311
- ti.hour,
312
- ti.min,
313
- ti.sec,
314
- nsec,
315
- tzsign,
316
- tzhour,
317
- tzmin);
297
+ len = sprintf(buf, format, ti.year, ti.mon, ti.day, ti.hour, ti.min, ti.sec, nsec, tzsign, tzhour, tzmin);
318
298
  }
319
299
  oj_dump_cstr(buf, len, 0, 0, out);
320
300
  }
@@ -323,20 +303,15 @@ static void dump_time(VALUE obj, int depth, Out out, bool as_ok) {
323
303
  long long sec;
324
304
  long long nsec;
325
305
 
326
- #ifdef HAVE_RB_TIME_TIMESPEC
327
306
  if (16 <= sizeof(struct timespec)) {
328
307
  struct timespec ts = rb_time_timespec(obj);
329
308
 
330
309
  sec = (long long)ts.tv_sec;
331
310
  nsec = ts.tv_nsec;
332
311
  } else {
333
- sec = rb_num2ll(rb_funcall2(obj, oj_tv_sec_id, 0, 0));
334
- nsec = rb_num2ll(rb_funcall2(obj, oj_tv_nsec_id, 0, 0));
312
+ sec = NUM2LL(rb_funcall2(obj, oj_tv_sec_id, 0, 0));
313
+ nsec = NUM2LL(rb_funcall2(obj, oj_tv_nsec_id, 0, 0));
335
314
  }
336
- #else
337
- sec = rb_num2ll(rb_funcall2(obj, oj_tv_sec_id, 0, 0));
338
- nsec = rb_num2ll(rb_funcall2(obj, oj_tv_nsec_id, 0, 0));
339
- #endif
340
315
  dump_sec_nano(obj, sec, nsec, out);
341
316
  }
342
317
 
@@ -345,15 +320,15 @@ static void dump_timewithzone(VALUE obj, int depth, Out out, bool as_ok) {
345
320
  long long nsec = 0;
346
321
 
347
322
  if (rb_respond_to(obj, oj_tv_nsec_id)) {
348
- nsec = rb_num2ll(rb_funcall2(obj, oj_tv_nsec_id, 0, 0));
323
+ nsec = NUM2LL(rb_funcall2(obj, oj_tv_nsec_id, 0, 0));
349
324
  } else if (rb_respond_to(obj, oj_tv_usec_id)) {
350
- nsec = rb_num2ll(rb_funcall2(obj, oj_tv_usec_id, 0, 0)) * 1000;
325
+ nsec = NUM2LL(rb_funcall2(obj, oj_tv_usec_id, 0, 0)) * 1000;
351
326
  }
352
327
  dump_sec_nano(obj, sec, nsec, out);
353
328
  }
354
329
 
355
330
  static void dump_to_s(VALUE obj, int depth, Out out, bool as_ok) {
356
- volatile VALUE rstr = rb_funcall(obj, oj_to_s_id, 0);
331
+ volatile VALUE rstr = oj_safe_string_convert(obj);
357
332
 
358
333
  oj_dump_cstr(RSTRING_PTR(rstr), (int)RSTRING_LEN(rstr), 0, 0, out);
359
334
  }
@@ -363,7 +338,7 @@ static ID parameters_id = 0;
363
338
  typedef struct _strLen {
364
339
  const char *str;
365
340
  int len;
366
- } * StrLen;
341
+ } *StrLen;
367
342
 
368
343
  static void dump_actioncontroller_parameters(VALUE obj, int depth, Out out, bool as_ok) {
369
344
  if (0 == parameters_id) {
@@ -381,11 +356,11 @@ static StrLen columns_array(VALUE rcols, int *ccnt) {
381
356
  int cnt = (int)RARRAY_LEN(rcols);
382
357
 
383
358
  *ccnt = cnt;
384
- cols = ALLOC_N(struct _strLen, cnt);
359
+ cols = OJ_R_ALLOC_N(struct _strLen, cnt);
385
360
  for (i = 0, cp = cols; i < cnt; i++, cp++) {
386
- v = rb_ary_entry(rcols, i);
361
+ v = RARRAY_AREF(rcols, i);
387
362
  if (T_STRING != rb_type(v)) {
388
- v = rb_funcall(v, oj_to_s_id, 0);
363
+ v = oj_safe_string_convert(v);
389
364
  }
390
365
  cp->str = StringValuePtr(v);
391
366
  cp->len = (int)RSTRING_LEN(v);
@@ -405,14 +380,12 @@ static void dump_row(VALUE row, StrLen cols, int ccnt, int depth, Out out) {
405
380
  assure_size(out, size);
406
381
  if (out->opts->dump_opts.use) {
407
382
  if (0 < out->opts->dump_opts.array_size) {
408
- strcpy(out->cur, out->opts->dump_opts.array_nl);
409
- out->cur += out->opts->dump_opts.array_size;
383
+ APPEND_CHARS(out->cur, out->opts->dump_opts.array_nl, out->opts->dump_opts.array_size);
410
384
  }
411
385
  if (0 < out->opts->dump_opts.indent_size) {
412
386
  int i;
413
387
  for (i = d2; 0 < i; i--) {
414
- strcpy(out->cur, out->opts->dump_opts.indent_str);
415
- out->cur += out->opts->dump_opts.indent_size;
388
+ APPEND_CHARS(out->cur, out->opts->dump_opts.indent_str, out->opts->dump_opts.indent_size);
416
389
  }
417
390
  }
418
391
  } else {
@@ -420,7 +393,7 @@ static void dump_row(VALUE row, StrLen cols, int ccnt, int depth, Out out) {
420
393
  }
421
394
  oj_dump_cstr(cols->str, cols->len, 0, 0, out);
422
395
  *out->cur++ = ':';
423
- dump_rails_val(rb_ary_entry(row, i), depth, out, true);
396
+ dump_rails_val(RARRAY_AREF(row, i), depth, out, true);
424
397
  if (i < ccnt - 1) {
425
398
  *out->cur++ = ',';
426
399
  }
@@ -429,15 +402,13 @@ static void dump_row(VALUE row, StrLen cols, int ccnt, int depth, Out out) {
429
402
  assure_size(out, size);
430
403
  if (out->opts->dump_opts.use) {
431
404
  if (0 < out->opts->dump_opts.array_size) {
432
- strcpy(out->cur, out->opts->dump_opts.array_nl);
433
- out->cur += out->opts->dump_opts.array_size;
405
+ APPEND_CHARS(out->cur, out->opts->dump_opts.array_nl, out->opts->dump_opts.array_size);
434
406
  }
435
407
  if (0 < out->opts->dump_opts.indent_size) {
436
408
  int i;
437
409
 
438
410
  for (i = depth; 0 < i; i--) {
439
- strcpy(out->cur, out->opts->dump_opts.indent_str);
440
- out->cur += out->opts->dump_opts.indent_size;
411
+ APPEND_CHARS(out->cur, out->opts->dump_opts.indent_str, out->opts->dump_opts.indent_size);
441
412
  }
442
413
  }
443
414
  } else {
@@ -477,38 +448,34 @@ static void dump_activerecord_result(VALUE obj, int depth, Out out, bool as_ok)
477
448
  assure_size(out, size);
478
449
  if (out->opts->dump_opts.use) {
479
450
  if (0 < out->opts->dump_opts.array_size) {
480
- strcpy(out->cur, out->opts->dump_opts.array_nl);
481
- out->cur += out->opts->dump_opts.array_size;
451
+ APPEND_CHARS(out->cur, out->opts->dump_opts.array_nl, out->opts->dump_opts.array_size);
482
452
  }
483
453
  if (0 < out->opts->dump_opts.indent_size) {
484
454
  int i;
485
455
  for (i = d2; 0 < i; i--) {
486
- strcpy(out->cur, out->opts->dump_opts.indent_str);
487
- out->cur += out->opts->dump_opts.indent_size;
456
+ APPEND_CHARS(out->cur, out->opts->dump_opts.indent_str, out->opts->dump_opts.indent_size);
488
457
  }
489
458
  }
490
459
  } else {
491
460
  fill_indent(out, d2);
492
461
  }
493
- dump_row(rb_ary_entry(rows, i), cols, ccnt, d2, out);
462
+ dump_row(RARRAY_AREF(rows, i), cols, ccnt, d2, out);
494
463
  if (i < rcnt - 1) {
495
464
  *out->cur++ = ',';
496
465
  }
497
466
  }
498
- xfree(cols);
467
+ OJ_R_FREE(cols);
499
468
  size = depth * out->indent + 1;
500
469
  assure_size(out, size);
501
470
  if (out->opts->dump_opts.use) {
502
471
  if (0 < out->opts->dump_opts.array_size) {
503
- strcpy(out->cur, out->opts->dump_opts.array_nl);
504
- out->cur += out->opts->dump_opts.array_size;
472
+ APPEND_CHARS(out->cur, out->opts->dump_opts.array_nl, out->opts->dump_opts.array_size);
505
473
  }
506
474
  if (0 < out->opts->dump_opts.indent_size) {
507
475
  int i;
508
476
 
509
477
  for (i = depth; 0 < i; i--) {
510
- strcpy(out->cur, out->opts->dump_opts.indent_str);
511
- out->cur += out->opts->dump_opts.indent_size;
478
+ APPEND_CHARS(out->cur, out->opts->dump_opts.indent_str, out->opts->dump_opts.indent_size);
512
479
  }
513
480
  }
514
481
  } else {
@@ -520,7 +487,7 @@ static void dump_activerecord_result(VALUE obj, int depth, Out out, bool as_ok)
520
487
  typedef struct _namedFunc {
521
488
  const char *name;
522
489
  DumpFunc func;
523
- } * NamedFunc;
490
+ } *NamedFunc;
524
491
 
525
492
  static void dump_as_string(VALUE obj, int depth, Out out, bool as_ok) {
526
493
  if (oj_code_dump(oj_compat_codes, obj, depth, out)) {
@@ -533,9 +500,7 @@ static void dump_as_string(VALUE obj, int depth, Out out, bool as_ok) {
533
500
  static void dump_as_json(VALUE obj, int depth, Out out, bool as_ok) {
534
501
  volatile VALUE ja;
535
502
 
536
- if (Yes == out->opts->trace) {
537
- oj_trace("as_json", obj, __FILE__, __LINE__, depth + 1, TraceRubyIn);
538
- }
503
+ TRACE(out->opts->trace, "as_json", obj, depth + 1, TraceRubyIn);
539
504
  // Some classes elect to not take an options argument so check the arity
540
505
  // of as_json.
541
506
  if (0 == rb_obj_method_arity(obj, oj_as_json_id)) {
@@ -543,9 +508,7 @@ static void dump_as_json(VALUE obj, int depth, Out out, bool as_ok) {
543
508
  } else {
544
509
  ja = rb_funcall2(obj, oj_as_json_id, out->argc, out->argv);
545
510
  }
546
- if (Yes == out->opts->trace) {
547
- oj_trace("as_json", obj, __FILE__, __LINE__, depth + 1, TraceRubyOut);
548
- }
511
+ TRACE(out->opts->trace, "as_json", obj, depth + 1, TraceRubyOut);
549
512
 
550
513
  out->argc = 0;
551
514
  if (ja == obj || !as_ok) {
@@ -603,11 +566,11 @@ static ROpt create_opt(ROptTable rot, VALUE clas) {
603
566
  rot->len++;
604
567
  if (NULL == rot->table) {
605
568
  rot->alen = 256;
606
- rot->table = ALLOC_N(struct _rOpt, rot->alen);
569
+ rot->table = OJ_R_ALLOC_N(struct _rOpt, rot->alen);
607
570
  memset(rot->table, 0, sizeof(struct _rOpt) * rot->alen);
608
571
  } else if (rot->alen <= rot->len) {
609
572
  rot->alen *= 2;
610
- REALLOC_N(rot->table, struct _rOpt, rot->alen);
573
+ OJ_R_REALLOC_N(rot->table, struct _rOpt, rot->alen);
611
574
  memset(rot->table + olen, 0, sizeof(struct _rOpt) * olen);
612
575
  }
613
576
  if (0 == olen) {
@@ -660,9 +623,9 @@ static void encoder_free(void *ptr) {
660
623
  Encoder e = (Encoder)ptr;
661
624
 
662
625
  if (NULL != e->ropts.table) {
663
- xfree(e->ropts.table);
626
+ OJ_R_FREE(e->ropts.table);
664
627
  }
665
- xfree(ptr);
628
+ OJ_R_FREE(ptr);
666
629
  }
667
630
  }
668
631
 
@@ -683,7 +646,7 @@ static void encoder_mark(void *ptr) {
683
646
  * - *options* [_Hash_] formatting options
684
647
  */
685
648
  static VALUE encoder_new(int argc, VALUE *argv, VALUE self) {
686
- Encoder e = ALLOC(struct _encoder);
649
+ Encoder e = OJ_R_ALLOC(struct _encoder);
687
650
 
688
651
  e->opts = oj_default_options;
689
652
  e->arg = Qnil;
@@ -699,8 +662,8 @@ static VALUE encoder_new(int argc, VALUE *argv, VALUE self) {
699
662
  static VALUE resolve_classpath(const char *name) {
700
663
  char class_name[1024];
701
664
  VALUE clas;
702
- char * end = class_name + sizeof(class_name) - 1;
703
- char * s;
665
+ char *end = class_name + sizeof(class_name) - 1;
666
+ char *s;
704
667
  const char *n = name;
705
668
  ID cid;
706
669
 
@@ -766,8 +729,7 @@ static void optimize(int argc, VALUE *argv, ROptTable rot, bool on) {
766
729
  oj_rails_float_opt = on;
767
730
  } else if (oj_string_writer_class == *argv) {
768
731
  string_writer_optimized = on;
769
- } else if (NULL != (ro = oj_rails_get_opt(rot, *argv)) ||
770
- NULL != (ro = create_opt(rot, *argv))) {
732
+ } else if (NULL != (ro = oj_rails_get_opt(rot, *argv)) || NULL != (ro = create_opt(rot, *argv))) {
771
733
  ro->on = on;
772
734
  }
773
735
  }
@@ -829,7 +791,7 @@ rails_mimic_json(VALUE self) {
829
791
  }
830
792
  oj_mimic_json_methods(json);
831
793
  // Setting the default mode breaks the prmoise in the docs not to.
832
- //oj_default_options.mode = RailsMode;
794
+ // oj_default_options.mode = RailsMode;
833
795
 
834
796
  return Qnil;
835
797
  }
@@ -897,7 +859,7 @@ static VALUE rails_optimized(VALUE self, VALUE clas) {
897
859
  typedef struct _oo {
898
860
  Out out;
899
861
  VALUE obj;
900
- } * OO;
862
+ } *OO;
901
863
 
902
864
  static VALUE protect_dump(VALUE ov) {
903
865
  OO oo = (OO)ov;
@@ -908,7 +870,6 @@ static VALUE protect_dump(VALUE ov) {
908
870
  }
909
871
 
910
872
  static VALUE encode(VALUE obj, ROptTable ropts, Options opts, int argc, VALUE *argv) {
911
- char buf[4096];
912
873
  struct _out out;
913
874
  struct _options copts = *opts;
914
875
  volatile VALUE rstr = Qnil;
@@ -925,19 +886,18 @@ static VALUE encode(VALUE obj, ROptTable ropts, Options opts, int argc, VALUE *a
925
886
  } else {
926
887
  copts.escape_mode = RailsEsc;
927
888
  }
928
- out.buf = buf;
929
- out.end = buf + sizeof(buf) - 10;
930
- out.allocated = false;
931
- out.omit_nil = copts.dump_opts.omit_nil;
932
- out.caller = 0;
933
- out.cur = out.buf;
934
- out.circ_cnt = 0;
935
- out.opts = &copts;
936
- out.hash_cnt = 0;
937
- out.indent = copts.indent;
938
- out.argc = argc;
939
- out.argv = argv;
940
- out.ropts = ropts;
889
+
890
+ oj_out_init(&out);
891
+
892
+ out.omit_nil = copts.dump_opts.omit_nil;
893
+ out.cur = out.buf;
894
+ out.circ_cnt = 0;
895
+ out.opts = &copts;
896
+ out.hash_cnt = 0;
897
+ out.indent = copts.indent;
898
+ out.argc = argc;
899
+ out.argv = argv;
900
+ out.ropts = ropts;
941
901
  if (Yes == copts.circular) {
942
902
  oj_cache8_new(&out.circ_cache);
943
903
  }
@@ -963,9 +923,9 @@ static VALUE encode(VALUE obj, ROptTable ropts, Options opts, int argc, VALUE *a
963
923
  if (Yes == copts.circular) {
964
924
  oj_cache8_delete(out.circ_cache);
965
925
  }
966
- if (out.allocated) {
967
- xfree(out.buf);
968
- }
926
+
927
+ oj_out_free(&out);
928
+
969
929
  if (0 != line) {
970
930
  rb_jump_tag(line);
971
931
  }
@@ -1082,28 +1042,16 @@ static VALUE rails_set_encoder(VALUE self) {
1082
1042
  verbose = rb_gv_get("$VERBOSE");
1083
1043
  rb_gv_set("$VERBOSE", Qfalse);
1084
1044
  rb_undef_method(encoding, "use_standard_json_time_format=");
1085
- rb_define_module_function(encoding,
1086
- "use_standard_json_time_format=",
1087
- rails_use_standard_json_time_format,
1088
- 1);
1045
+ rb_define_module_function(encoding, "use_standard_json_time_format=", rails_use_standard_json_time_format, 1);
1089
1046
  rb_undef_method(encoding, "use_standard_json_time_format");
1090
- rb_define_module_function(encoding,
1091
- "use_standard_json_time_format",
1092
- rails_use_standard_json_time_format_get,
1093
- 0);
1047
+ rb_define_module_function(encoding, "use_standard_json_time_format", rails_use_standard_json_time_format_get, 0);
1094
1048
 
1095
1049
  pv = rb_iv_get(encoding, "@escape_html_entities_in_json");
1096
1050
  escape_html = Qtrue == pv;
1097
1051
  rb_undef_method(encoding, "escape_html_entities_in_json=");
1098
- rb_define_module_function(encoding,
1099
- "escape_html_entities_in_json=",
1100
- rails_escape_html_entities_in_json,
1101
- 1);
1052
+ rb_define_module_function(encoding, "escape_html_entities_in_json=", rails_escape_html_entities_in_json, 1);
1102
1053
  rb_undef_method(encoding, "escape_html_entities_in_json");
1103
- rb_define_module_function(encoding,
1104
- "escape_html_entities_in_json",
1105
- rails_escape_html_entities_in_json_get,
1106
- 0);
1054
+ rb_define_module_function(encoding, "escape_html_entities_in_json", rails_escape_html_entities_in_json_get, 0);
1107
1055
 
1108
1056
  pv = rb_iv_get(encoding, "@time_precision");
1109
1057
  oj_default_options.sec_prec = NUM2INT(pv);
@@ -1175,12 +1123,15 @@ oj_optimize_rails(VALUE self) {
1175
1123
  *
1176
1124
  * The Oj ActiveSupport compliant encoder.
1177
1125
  */
1178
- void oj_mimic_rails_init() {
1126
+ void oj_mimic_rails_init(void) {
1179
1127
  VALUE rails = rb_define_module_under(Oj, "Rails");
1180
1128
 
1181
1129
  rb_define_module_function(rails, "encode", rails_encode, -1);
1182
1130
 
1183
1131
  encoder_class = rb_define_class_under(rails, "Encoder", rb_cObject);
1132
+ rb_gc_register_address(&encoder_class);
1133
+ rb_undef_alloc_func(encoder_class);
1134
+
1184
1135
  rb_define_module_function(encoder_class, "new", encoder_new, -1);
1185
1136
  rb_define_module_function(rails, "optimize", rails_optimize, -1);
1186
1137
  rb_define_module_function(rails, "deoptimize", rails_deoptimize, -1);
@@ -1202,7 +1153,7 @@ static void dump_to_hash(VALUE obj, int depth, Out out) {
1202
1153
 
1203
1154
  static void dump_float(VALUE obj, int depth, Out out, bool as_ok) {
1204
1155
  char buf[64];
1205
- char * b;
1156
+ char *b;
1206
1157
  double d = rb_num2dbl(obj);
1207
1158
  int cnt = 0;
1208
1159
 
@@ -1222,7 +1173,7 @@ static void dump_float(VALUE obj, int depth, Out out, bool as_ok) {
1222
1173
  } else if (oj_rails_float_opt) {
1223
1174
  cnt = oj_dump_float_printf(buf, sizeof(buf), obj, d, "%0.16g");
1224
1175
  } else {
1225
- volatile VALUE rstr = rb_funcall(obj, oj_to_s_id, 0);
1176
+ volatile VALUE rstr = oj_safe_string_convert(obj);
1226
1177
 
1227
1178
  strcpy(buf, RSTRING_PTR(rstr));
1228
1179
  cnt = (int)RSTRING_LEN(rstr);
@@ -1263,25 +1214,23 @@ static void dump_array(VALUE a, int depth, Out out, bool as_ok) {
1263
1214
  } else {
1264
1215
  size = d2 * out->indent + 2;
1265
1216
  }
1217
+ assure_size(out, size * cnt);
1266
1218
  cnt--;
1267
1219
  for (i = 0; i <= cnt; i++) {
1268
- assure_size(out, size);
1269
1220
  if (out->opts->dump_opts.use) {
1270
1221
  if (0 < out->opts->dump_opts.array_size) {
1271
- strcpy(out->cur, out->opts->dump_opts.array_nl);
1272
- out->cur += out->opts->dump_opts.array_size;
1222
+ APPEND_CHARS(out->cur, out->opts->dump_opts.array_nl, out->opts->dump_opts.array_size);
1273
1223
  }
1274
1224
  if (0 < out->opts->dump_opts.indent_size) {
1275
1225
  int i;
1276
1226
  for (i = d2; 0 < i; i--) {
1277
- strcpy(out->cur, out->opts->dump_opts.indent_str);
1278
- out->cur += out->opts->dump_opts.indent_size;
1227
+ APPEND_CHARS(out->cur, out->opts->dump_opts.indent_str, out->opts->dump_opts.indent_size);
1279
1228
  }
1280
1229
  }
1281
1230
  } else {
1282
1231
  fill_indent(out, d2);
1283
1232
  }
1284
- dump_rails_val(rb_ary_entry(a, i), d2, out, true);
1233
+ dump_rails_val(RARRAY_AREF(a, i), d2, out, true);
1285
1234
  if (i < cnt) {
1286
1235
  *out->cur++ = ',';
1287
1236
  }
@@ -1290,15 +1239,13 @@ static void dump_array(VALUE a, int depth, Out out, bool as_ok) {
1290
1239
  assure_size(out, size);
1291
1240
  if (out->opts->dump_opts.use) {
1292
1241
  if (0 < out->opts->dump_opts.array_size) {
1293
- strcpy(out->cur, out->opts->dump_opts.array_nl);
1294
- out->cur += out->opts->dump_opts.array_size;
1242
+ APPEND_CHARS(out->cur, out->opts->dump_opts.array_nl, out->opts->dump_opts.array_size);
1295
1243
  }
1296
1244
  if (0 < out->opts->dump_opts.indent_size) {
1297
1245
  int i;
1298
1246
 
1299
1247
  for (i = depth; 0 < i; i--) {
1300
- strcpy(out->cur, out->opts->dump_opts.indent_str);
1301
- out->cur += out->opts->dump_opts.indent_size;
1248
+ APPEND_CHARS(out->cur, out->opts->dump_opts.indent_str, out->opts->dump_opts.indent_size);
1302
1249
  }
1303
1250
  }
1304
1251
  } else {
@@ -1319,7 +1266,7 @@ static int hash_cb(VALUE key, VALUE value, VALUE ov) {
1319
1266
  return ST_CONTINUE;
1320
1267
  }
1321
1268
  if (rtype != T_STRING && rtype != T_SYMBOL) {
1322
- key = rb_funcall(key, oj_to_s_id, 0);
1269
+ key = oj_safe_string_convert(key);
1323
1270
  rtype = rb_type(key);
1324
1271
  }
1325
1272
  if (!out->opts->dump_opts.use) {
@@ -1336,14 +1283,12 @@ static int hash_cb(VALUE key, VALUE value, VALUE ov) {
1336
1283
  size = depth * out->opts->dump_opts.indent_size + out->opts->dump_opts.hash_size + 1;
1337
1284
  assure_size(out, size);
1338
1285
  if (0 < out->opts->dump_opts.hash_size) {
1339
- strcpy(out->cur, out->opts->dump_opts.hash_nl);
1340
- out->cur += out->opts->dump_opts.hash_size;
1286
+ APPEND_CHARS(out->cur, out->opts->dump_opts.hash_nl, out->opts->dump_opts.hash_size);
1341
1287
  }
1342
1288
  if (0 < out->opts->dump_opts.indent_size) {
1343
1289
  int i;
1344
1290
  for (i = depth; 0 < i; i--) {
1345
- strcpy(out->cur, out->opts->dump_opts.indent_str);
1346
- out->cur += out->opts->dump_opts.indent_size;
1291
+ APPEND_CHARS(out->cur, out->opts->dump_opts.indent_str, out->opts->dump_opts.indent_size);
1347
1292
  }
1348
1293
  }
1349
1294
  if (rtype == T_STRING) {
@@ -1354,13 +1299,11 @@ static int hash_cb(VALUE key, VALUE value, VALUE ov) {
1354
1299
  size = out->opts->dump_opts.before_size + out->opts->dump_opts.after_size + 2;
1355
1300
  assure_size(out, size);
1356
1301
  if (0 < out->opts->dump_opts.before_size) {
1357
- strcpy(out->cur, out->opts->dump_opts.before_sep);
1358
- out->cur += out->opts->dump_opts.before_size;
1302
+ APPEND_CHARS(out->cur, out->opts->dump_opts.before_sep, out->opts->dump_opts.before_size);
1359
1303
  }
1360
1304
  *out->cur++ = ':';
1361
1305
  if (0 < out->opts->dump_opts.after_size) {
1362
- strcpy(out->cur, out->opts->dump_opts.after_sep);
1363
- out->cur += out->opts->dump_opts.after_size;
1306
+ APPEND_CHARS(out->cur, out->opts->dump_opts.after_sep, out->opts->dump_opts.after_size);
1364
1307
  }
1365
1308
  }
1366
1309
  dump_rails_val(value, depth, out, true);
@@ -1403,15 +1346,13 @@ static void dump_hash(VALUE obj, int depth, Out out, bool as_ok) {
1403
1346
  size = depth * out->opts->dump_opts.indent_size + out->opts->dump_opts.hash_size + 1;
1404
1347
  assure_size(out, size);
1405
1348
  if (0 < out->opts->dump_opts.hash_size) {
1406
- strcpy(out->cur, out->opts->dump_opts.hash_nl);
1407
- out->cur += out->opts->dump_opts.hash_size;
1349
+ APPEND_CHARS(out->cur, out->opts->dump_opts.hash_nl, out->opts->dump_opts.hash_size);
1408
1350
  }
1409
1351
  if (0 < out->opts->dump_opts.indent_size) {
1410
1352
  int i;
1411
1353
 
1412
1354
  for (i = depth; 0 < i; i--) {
1413
- strcpy(out->cur, out->opts->dump_opts.indent_str);
1414
- out->cur += out->opts->dump_opts.indent_size;
1355
+ APPEND_CHARS(out->cur, out->opts->dump_opts.indent_str, out->opts->dump_opts.indent_size);
1415
1356
  }
1416
1357
  }
1417
1358
  }
@@ -1488,9 +1429,7 @@ static DumpFunc rails_funcs[] = {
1488
1429
  static void dump_rails_val(VALUE obj, int depth, Out out, bool as_ok) {
1489
1430
  int type = rb_type(obj);
1490
1431
 
1491
- if (Yes == out->opts->trace) {
1492
- oj_trace("dump", obj, __FILE__, __LINE__, depth, TraceIn);
1493
- }
1432
+ TRACE(out->opts->trace, "dump", obj, depth, TraceIn);
1494
1433
  if (MAX_DEPTH < depth) {
1495
1434
  rb_raise(rb_eNoMemError, "Too deeply nested.\n");
1496
1435
  }
@@ -1499,16 +1438,12 @@ static void dump_rails_val(VALUE obj, int depth, Out out, bool as_ok) {
1499
1438
 
1500
1439
  if (NULL != f) {
1501
1440
  f(obj, depth, out, as_ok);
1502
- if (Yes == out->opts->trace) {
1503
- oj_trace("dump", obj, __FILE__, __LINE__, depth, TraceOut);
1504
- }
1441
+ TRACE(out->opts->trace, "dump", obj, depth, TraceOut);
1505
1442
  return;
1506
1443
  }
1507
1444
  }
1508
1445
  oj_dump_nil(Qnil, depth, out, false);
1509
- if (Yes == out->opts->trace) {
1510
- oj_trace("dump", Qnil, __FILE__, __LINE__, depth, TraceOut);
1511
- }
1446
+ TRACE(out->opts->trace, "dump", Qnil, depth, TraceOut);
1512
1447
  }
1513
1448
 
1514
1449
  void oj_dump_rails_val(VALUE obj, int depth, Out out) {
data/ext/oj/rails.h CHANGED
@@ -6,7 +6,7 @@
6
6
 
7
7
  #include "dump.h"
8
8
 
9
- extern void oj_mimic_rails_init();
9
+ extern void oj_mimic_rails_init(void);
10
10
  extern ROpt oj_rails_get_opt(ROptTable rot, VALUE clas);
11
11
 
12
12
  extern bool oj_rails_hash_opt;