oj 3.13.9 → 3.13.12

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.
data/ext/oj/dump_object.c CHANGED
@@ -24,12 +24,7 @@ static void dump_data(VALUE obj, int depth, Out out, bool as_ok) {
24
24
 
25
25
  if (rb_cTime == clas) {
26
26
  assure_size(out, 6);
27
- *out->cur++ = '{';
28
- *out->cur++ = '"';
29
- *out->cur++ = '^';
30
- *out->cur++ = 't';
31
- *out->cur++ = '"';
32
- *out->cur++ = ':';
27
+ APPEND_CHARS(out->cur, "{\"^t\":", 6);
33
28
  dump_time(obj, out);
34
29
  *out->cur++ = '}';
35
30
  *out->cur = '\0';
@@ -91,12 +86,7 @@ static void dump_class(VALUE obj, int depth, Out out, bool as_ok) {
91
86
  size_t len = strlen(s);
92
87
 
93
88
  assure_size(out, 6);
94
- *out->cur++ = '{';
95
- *out->cur++ = '"';
96
- *out->cur++ = '^';
97
- *out->cur++ = 'c';
98
- *out->cur++ = '"';
99
- *out->cur++ = ':';
89
+ APPEND_CHARS(out->cur, "{\"^c\":", 6);
100
90
  oj_dump_cstr(s, len, 0, 0, out);
101
91
  *out->cur++ = '}';
102
92
  *out->cur = '\0';
@@ -120,9 +110,7 @@ static void dump_array_class(VALUE a, VALUE clas, int depth, Out out) {
120
110
  if (0 < id) {
121
111
  assure_size(out, d2 * out->indent + 16);
122
112
  fill_indent(out, d2);
123
- *out->cur++ = '"';
124
- *out->cur++ = '^';
125
- *out->cur++ = 'i';
113
+ APPEND_CHARS(out->cur, "\"^i", 3);
126
114
  dump_ulong(id, out);
127
115
  *out->cur++ = '"';
128
116
  }
@@ -139,25 +127,23 @@ static void dump_array_class(VALUE a, VALUE clas, int depth, Out out) {
139
127
  } else {
140
128
  size = d2 * out->indent + 2;
141
129
  }
130
+ assure_size(out, size * cnt);
142
131
  cnt--;
143
132
  for (i = 0; i <= cnt; i++) {
144
- assure_size(out, size);
145
133
  if (out->opts->dump_opts.use) {
146
134
  if (0 < out->opts->dump_opts.array_size) {
147
- strcpy(out->cur, out->opts->dump_opts.array_nl);
148
- out->cur += out->opts->dump_opts.array_size;
135
+ APPEND_CHARS(out->cur, out->opts->dump_opts.array_nl, out->opts->dump_opts.array_size);
149
136
  }
150
137
  if (0 < out->opts->dump_opts.indent_size) {
151
138
  int i;
152
139
  for (i = d2; 0 < i; i--) {
153
- strcpy(out->cur, out->opts->dump_opts.indent_str);
154
- out->cur += out->opts->dump_opts.indent_size;
140
+ APPEND_CHARS(out->cur, out->opts->dump_opts.indent_str, out->opts->dump_opts.indent_size);
155
141
  }
156
142
  }
157
143
  } else {
158
144
  fill_indent(out, d2);
159
145
  }
160
- oj_dump_obj_val(rb_ary_entry(a, i), d2, out);
146
+ oj_dump_obj_val(RARRAY_AREF(a, i), d2, out);
161
147
  if (i < cnt) {
162
148
  *out->cur++ = ',';
163
149
  }
@@ -168,15 +154,13 @@ static void dump_array_class(VALUE a, VALUE clas, int depth, Out out) {
168
154
  // printf("*** d2: %u indent: %u '%s'\n", d2, out->opts->dump_opts->indent_size,
169
155
  // out->opts->dump_opts->indent);
170
156
  if (0 < out->opts->dump_opts.array_size) {
171
- strcpy(out->cur, out->opts->dump_opts.array_nl);
172
- out->cur += out->opts->dump_opts.array_size;
157
+ APPEND_CHARS(out->cur, out->opts->dump_opts.array_nl, out->opts->dump_opts.array_size);
173
158
  }
174
159
  if (0 < out->opts->dump_opts.indent_size) {
175
160
  int i;
176
161
 
177
162
  for (i = depth; 0 < i; i--) {
178
- strcpy(out->cur, out->opts->dump_opts.indent_str);
179
- out->cur += out->opts->dump_opts.indent_size;
163
+ APPEND_CHARS(out->cur, out->opts->dump_opts.indent_str, out->opts->dump_opts.indent_size);
180
164
  }
181
165
  }
182
166
  } else {
@@ -218,7 +202,7 @@ static int hash_cb(VALUE key, VALUE value, VALUE ov) {
218
202
  int depth = out->depth;
219
203
  long size = depth * out->indent + 1;
220
204
 
221
- if (oj_dump_ignore(out->opts, value)) {
205
+ if (dump_ignore(out->opts, value)) {
222
206
  return ST_CONTINUE;
223
207
  }
224
208
  if (out->omit_nil && Qnil == value) {
@@ -226,47 +210,50 @@ static int hash_cb(VALUE key, VALUE value, VALUE ov) {
226
210
  }
227
211
  assure_size(out, size);
228
212
  fill_indent(out, depth);
229
- if (rb_type(key) == T_STRING) {
213
+ switch (rb_type(key)) {
214
+ case T_STRING:
230
215
  dump_str_class(key, Qundef, depth, out);
231
216
  *out->cur++ = ':';
232
217
  oj_dump_obj_val(value, depth, out);
233
- } else if (rb_type(key) == T_SYMBOL) {
218
+ break;
219
+
220
+ case T_SYMBOL:
234
221
  dump_sym(key, 0, out, false);
235
222
  *out->cur++ = ':';
236
223
  oj_dump_obj_val(value, depth, out);
237
- } else {
238
- int d2 = depth + 1;
239
- long s2 = size + out->indent + 1;
240
- int i;
241
- int started = 0;
242
- uint8_t b;
224
+ break;
243
225
 
244
- assure_size(out, s2 + 15);
245
- *out->cur++ = '"';
246
- *out->cur++ = '^';
247
- *out->cur++ = '#';
248
- out->hash_cnt++;
249
- for (i = 28; 0 <= i; i -= 4) {
250
- b = (uint8_t)((out->hash_cnt >> i) & 0x0000000F);
251
- if ('\0' != b) {
252
- started = 1;
253
- }
254
- if (started) {
255
- *out->cur++ = hex_chars[b];
226
+ default:
227
+ {
228
+ int d2 = depth + 1;
229
+ long s2 = size + out->indent + 1;
230
+ int i;
231
+ int started = 0;
232
+ uint8_t b;
233
+
234
+ assure_size(out, s2 + 15);
235
+ APPEND_CHARS(out->cur, "\"^#", 3);
236
+ out->hash_cnt++;
237
+ for (i = 28; 0 <= i; i -= 4) {
238
+ b = (uint8_t)((out->hash_cnt >> i) & 0x0000000F);
239
+ if ('\0' != b) {
240
+ started = 1;
241
+ }
242
+ if (started) {
243
+ *out->cur++ = hex_chars[b];
244
+ }
256
245
  }
246
+ APPEND_CHARS(out->cur, "\":[", 3);
247
+ fill_indent(out, d2);
248
+ oj_dump_obj_val(key, d2, out);
249
+ assure_size(out, s2);
250
+ *out->cur++ = ',';
251
+ fill_indent(out, d2);
252
+ oj_dump_obj_val(value, d2, out);
253
+ assure_size(out, size);
254
+ fill_indent(out, depth);
255
+ *out->cur++ = ']';
257
256
  }
258
- *out->cur++ = '"';
259
- *out->cur++ = ':';
260
- *out->cur++ = '[';
261
- fill_indent(out, d2);
262
- oj_dump_obj_val(key, d2, out);
263
- assure_size(out, s2);
264
- *out->cur++ = ',';
265
- fill_indent(out, d2);
266
- oj_dump_obj_val(value, d2, out);
267
- assure_size(out, size);
268
- fill_indent(out, depth);
269
- *out->cur++ = ']';
270
257
  }
271
258
  out->depth = depth;
272
259
  *out->cur++ = ',';
@@ -286,8 +273,7 @@ static void dump_hash_class(VALUE obj, VALUE clas, int depth, Out out) {
286
273
  size = depth * out->indent + 2;
287
274
  assure_size(out, 2);
288
275
  if (0 == cnt) {
289
- *out->cur++ = '{';
290
- *out->cur++ = '}';
276
+ APPEND_CHARS(out->cur, "{}", 2);
291
277
  } else {
292
278
  long id = oj_check_circular(obj, out);
293
279
 
@@ -298,11 +284,7 @@ static void dump_hash_class(VALUE obj, VALUE clas, int depth, Out out) {
298
284
  if (0 < id) {
299
285
  assure_size(out, size + 16);
300
286
  fill_indent(out, depth + 1);
301
- *out->cur++ = '"';
302
- *out->cur++ = '^';
303
- *out->cur++ = 'i';
304
- *out->cur++ = '"';
305
- *out->cur++ = ':';
287
+ APPEND_CHARS(out->cur, "\"^i\":", 5);
306
288
  dump_ulong(id, out);
307
289
  *out->cur++ = ',';
308
290
  }
@@ -318,15 +300,13 @@ static void dump_hash_class(VALUE obj, VALUE clas, int depth, Out out) {
318
300
  size = depth * out->opts->dump_opts.indent_size + out->opts->dump_opts.hash_size + 1;
319
301
  assure_size(out, size);
320
302
  if (0 < out->opts->dump_opts.hash_size) {
321
- strcpy(out->cur, out->opts->dump_opts.hash_nl);
322
- out->cur += out->opts->dump_opts.hash_size;
303
+ APPEND_CHARS(out->cur, out->opts->dump_opts.hash_nl, out->opts->dump_opts.hash_size);
323
304
  }
324
305
  if (0 < out->opts->dump_opts.indent_size) {
325
306
  int i;
326
307
 
327
308
  for (i = depth; 0 < i; i--) {
328
- strcpy(out->cur, out->opts->dump_opts.indent_str);
329
- out->cur += out->opts->dump_opts.indent_size;
309
+ APPEND_CHARS(out->cur, out->opts->dump_opts.indent_str, out->opts->dump_opts.indent_size);
330
310
  }
331
311
  }
332
312
  }
@@ -342,7 +322,7 @@ static int dump_attr_cb(ID key, VALUE value, VALUE ov) {
342
322
  size_t size = depth * out->indent + 1;
343
323
  const char *attr = rb_id2name(key);
344
324
 
345
- if (oj_dump_ignore(out->opts, value)) {
325
+ if (dump_ignore(out->opts, value)) {
346
326
  return ST_CONTINUE;
347
327
  }
348
328
  if (out->omit_nil && Qnil == value) {
@@ -401,11 +381,7 @@ static void dump_odd(VALUE obj, Odd odd, VALUE clas, int depth, Out out) {
401
381
  size = d2 * out->indent + clen + 10;
402
382
  assure_size(out, size);
403
383
  fill_indent(out, d2);
404
- *out->cur++ = '"';
405
- *out->cur++ = '^';
406
- *out->cur++ = 'O';
407
- *out->cur++ = '"';
408
- *out->cur++ = ':';
384
+ APPEND_CHARS(out->cur, "\"^O\":", 5);
409
385
  oj_dump_cstr(class_name, clen, 0, 0, out);
410
386
  *out->cur++ = ',';
411
387
  }
@@ -423,12 +399,9 @@ static void dump_odd(VALUE obj, Odd odd, VALUE clas, int depth, Out out) {
423
399
  assure_size(out, size);
424
400
  fill_indent(out, d2);
425
401
  *out->cur++ = '"';
426
- memcpy(out->cur, name, nlen);
427
- out->cur += nlen;
428
- *out->cur++ = '"';
429
- *out->cur++ = ':';
430
- memcpy(out->cur, s, len);
431
- out->cur += len;
402
+ APPEND_CHARS(out->cur, name, nlen);
403
+ APPEND_CHARS(out->cur, "\":", 2);
404
+ APPEND_CHARS(out->cur, s, len);
432
405
  *out->cur = '\0';
433
406
  }
434
407
  } else {
@@ -439,7 +412,7 @@ static void dump_odd(VALUE obj, Odd odd, VALUE clas, int depth, Out out) {
439
412
  assure_size(out, size);
440
413
  name = rb_id2name(*idp);
441
414
  nlen = strlen(name);
442
- if (0 != *fp) {
415
+ if (NULL != *fp) {
443
416
  v = (*fp)(obj);
444
417
  } else if (0 == strchr(name, '.')) {
445
418
  v = rb_funcall(obj, *idp, 0);
@@ -502,22 +475,14 @@ static void dump_obj_attrs(VALUE obj, VALUE clas, slot_t id, int depth, Out out)
502
475
 
503
476
  assure_size(out, d2 * out->indent + clen + 10);
504
477
  fill_indent(out, d2);
505
- *out->cur++ = '"';
506
- *out->cur++ = '^';
507
- *out->cur++ = 'o';
508
- *out->cur++ = '"';
509
- *out->cur++ = ':';
478
+ APPEND_CHARS(out->cur, "\"^o\":", 5);
510
479
  oj_dump_cstr(class_name, clen, 0, 0, out);
511
480
  }
512
481
  if (0 < id) {
513
482
  assure_size(out, d2 * out->indent + 16);
514
483
  *out->cur++ = ',';
515
484
  fill_indent(out, d2);
516
- *out->cur++ = '"';
517
- *out->cur++ = '^';
518
- *out->cur++ = 'i';
519
- *out->cur++ = '"';
520
- *out->cur++ = ':';
485
+ APPEND_CHARS(out->cur, "\"^i\":", 5);
521
486
  dump_ulong(id, out);
522
487
  }
523
488
  switch (type) {
@@ -525,39 +490,21 @@ static void dump_obj_attrs(VALUE obj, VALUE clas, slot_t id, int depth, Out out)
525
490
  assure_size(out, d2 * out->indent + 14);
526
491
  *out->cur++ = ',';
527
492
  fill_indent(out, d2);
528
- *out->cur++ = '"';
529
- *out->cur++ = 's';
530
- *out->cur++ = 'e';
531
- *out->cur++ = 'l';
532
- *out->cur++ = 'f';
533
- *out->cur++ = '"';
534
- *out->cur++ = ':';
493
+ APPEND_CHARS(out->cur, "\"self\":", 7);
535
494
  oj_dump_cstr(RSTRING_PTR(obj), (int)RSTRING_LEN(obj), 0, 0, out);
536
495
  break;
537
496
  case T_ARRAY:
538
497
  assure_size(out, d2 * out->indent + 14);
539
498
  *out->cur++ = ',';
540
499
  fill_indent(out, d2);
541
- *out->cur++ = '"';
542
- *out->cur++ = 's';
543
- *out->cur++ = 'e';
544
- *out->cur++ = 'l';
545
- *out->cur++ = 'f';
546
- *out->cur++ = '"';
547
- *out->cur++ = ':';
500
+ APPEND_CHARS(out->cur, "\"self\":", 7);
548
501
  dump_array_class(obj, Qundef, depth + 1, out);
549
502
  break;
550
503
  case T_HASH:
551
504
  assure_size(out, d2 * out->indent + 14);
552
505
  *out->cur++ = ',';
553
506
  fill_indent(out, d2);
554
- *out->cur++ = '"';
555
- *out->cur++ = 's';
556
- *out->cur++ = 'e';
557
- *out->cur++ = 'l';
558
- *out->cur++ = 'f';
559
- *out->cur++ = '"';
560
- *out->cur++ = ':';
507
+ APPEND_CHARS(out->cur, "\"self\":", 7);
561
508
  dump_hash_class(obj, Qundef, depth + 1, out);
562
509
  break;
563
510
  default: break;
@@ -605,7 +552,7 @@ static void dump_obj_attrs(VALUE obj, VALUE clas, slot_t id, int depth, Out out)
605
552
  }
606
553
  value = rb_ivar_get(obj, vid);
607
554
 
608
- if (oj_dump_ignore(out->opts, value)) {
555
+ if (dump_ignore(out->opts, value)) {
609
556
  continue;
610
557
  }
611
558
  if (out->omit_nil && Qnil == value) {
@@ -681,12 +628,7 @@ static void dump_struct(VALUE obj, int depth, Out out, bool as_ok) {
681
628
  assure_size(out, size);
682
629
  *out->cur++ = '{';
683
630
  fill_indent(out, d2);
684
- *out->cur++ = '"';
685
- *out->cur++ = '^';
686
- *out->cur++ = 'u';
687
- *out->cur++ = '"';
688
- *out->cur++ = ':';
689
- *out->cur++ = '[';
631
+ APPEND_CHARS(out->cur, "\"^u\":[", 6);
690
632
  if ('#' == *class_name) {
691
633
  VALUE ma = rb_struct_s_members(clas);
692
634
  const char *name;
@@ -694,7 +636,7 @@ static void dump_struct(VALUE obj, int depth, Out out, bool as_ok) {
694
636
 
695
637
  *out->cur++ = '[';
696
638
  for (i = 0; i < cnt; i++) {
697
- volatile VALUE s = rb_sym2str(rb_ary_entry(ma, i));
639
+ volatile VALUE s = rb_sym2str(RARRAY_AREF(ma, i));
698
640
 
699
641
  name = RSTRING_PTR(s);
700
642
  len = (int)RSTRING_LEN(s);
@@ -704,16 +646,14 @@ static void dump_struct(VALUE obj, int depth, Out out, bool as_ok) {
704
646
  *out->cur++ = ',';
705
647
  }
706
648
  *out->cur++ = '"';
707
- memcpy(out->cur, name, len);
708
- out->cur += len;
649
+ APPEND_CHARS(out->cur, name, len);
709
650
  *out->cur++ = '"';
710
651
  }
711
652
  *out->cur++ = ']';
712
653
  } else {
713
654
  fill_indent(out, d3);
714
655
  *out->cur++ = '"';
715
- memcpy(out->cur, class_name, len);
716
- out->cur += len;
656
+ APPEND_CHARS(out->cur, class_name, len);
717
657
  *out->cur++ = '"';
718
658
  }
719
659
  *out->cur++ = ',';
@@ -730,7 +670,7 @@ static void dump_struct(VALUE obj, int depth, Out out, bool as_ok) {
730
670
 
731
671
  for (i = 0; i < cnt; i++) {
732
672
  v = RSTRUCT_GET(obj, i);
733
- if (oj_dump_ignore(out->opts, v)) {
673
+ if (dump_ignore(out->opts, v)) {
734
674
  v = Qnil;
735
675
  }
736
676
  assure_size(out, size);
@@ -748,7 +688,7 @@ static void dump_struct(VALUE obj, int depth, Out out, bool as_ok) {
748
688
  for (i = 0; i < slen; i++) {
749
689
  assure_size(out, size);
750
690
  fill_indent(out, d3);
751
- if (oj_dump_ignore(out->opts, v)) {
691
+ if (dump_ignore(out->opts, v)) {
752
692
  v = Qnil;
753
693
  }
754
694
  oj_dump_obj_val(rb_struct_aref(obj, INT2FIX(i)), d3, out, 0, 0, true);
@@ -757,8 +697,7 @@ static void dump_struct(VALUE obj, int depth, Out out, bool as_ok) {
757
697
  }
758
698
  #endif
759
699
  out->cur--;
760
- *out->cur++ = ']';
761
- *out->cur++ = '}';
700
+ APPEND_CHARS(out->cur, "]}", 2);
762
701
  *out->cur = '\0';
763
702
  }
764
703
 
data/ext/oj/dump_strict.c CHANGED
@@ -105,9 +105,7 @@ static void dump_float(VALUE obj, int depth, Out out, bool as_ok) {
105
105
  }
106
106
  }
107
107
  assure_size(out, cnt);
108
- for (b = buf; '\0' != *b; b++) {
109
- *out->cur++ = *b;
110
- }
108
+ APPEND_CHARS(out->cur, buf, cnt);
111
109
  *out->cur = '\0';
112
110
  }
113
111
 
@@ -134,28 +132,26 @@ static void dump_array(VALUE a, int depth, Out out, bool as_ok) {
134
132
  } else {
135
133
  size = d2 * out->indent + 2;
136
134
  }
135
+ assure_size(out, size * cnt);
137
136
  cnt--;
138
137
  for (i = 0; i <= cnt; i++) {
139
- assure_size(out, size);
140
138
  if (out->opts->dump_opts.use) {
141
139
  if (0 < out->opts->dump_opts.array_size) {
142
- strcpy(out->cur, out->opts->dump_opts.array_nl);
143
- out->cur += out->opts->dump_opts.array_size;
140
+ APPEND_CHARS(out->cur, out->opts->dump_opts.array_nl, out->opts->dump_opts.array_size);
144
141
  }
145
142
  if (0 < out->opts->dump_opts.indent_size) {
146
143
  int i;
147
144
  for (i = d2; 0 < i; i--) {
148
- strcpy(out->cur, out->opts->dump_opts.indent_str);
149
- out->cur += out->opts->dump_opts.indent_size;
145
+ APPEND_CHARS(out->cur, out->opts->dump_opts.indent_str, out->opts->dump_opts.indent_size);
150
146
  }
151
147
  }
152
148
  } else {
153
149
  fill_indent(out, d2);
154
150
  }
155
151
  if (NullMode == out->opts->mode) {
156
- oj_dump_null_val(rb_ary_entry(a, i), d2, out);
152
+ oj_dump_null_val(RARRAY_AREF(a, i), d2, out);
157
153
  } else {
158
- oj_dump_strict_val(rb_ary_entry(a, i), d2, out);
154
+ oj_dump_strict_val(RARRAY_AREF(a, i), d2, out);
159
155
  }
160
156
  if (i < cnt) {
161
157
  *out->cur++ = ',';
@@ -167,15 +163,13 @@ static void dump_array(VALUE a, int depth, Out out, bool as_ok) {
167
163
  // printf("*** d2: %u indent: %u '%s'\n", d2, out->opts->dump_opts->indent_size,
168
164
  // out->opts->dump_opts->indent);
169
165
  if (0 < out->opts->dump_opts.array_size) {
170
- strcpy(out->cur, out->opts->dump_opts.array_nl);
171
- out->cur += out->opts->dump_opts.array_size;
166
+ APPEND_CHARS(out->cur, out->opts->dump_opts.array_nl, out->opts->dump_opts.array_size);
172
167
  }
173
168
  if (0 < out->opts->dump_opts.indent_size) {
174
169
  int i;
175
170
 
176
171
  for (i = depth; 0 < i; i--) {
177
- strcpy(out->cur, out->opts->dump_opts.indent_str);
178
- out->cur += out->opts->dump_opts.indent_size;
172
+ APPEND_CHARS(out->cur, out->opts->dump_opts.indent_str, out->opts->dump_opts.indent_size);
179
173
  }
180
174
  }
181
175
  } else {
@@ -214,14 +208,12 @@ static int hash_cb(VALUE key, VALUE value, VALUE ov) {
214
208
  size = depth * out->opts->dump_opts.indent_size + out->opts->dump_opts.hash_size + 1;
215
209
  assure_size(out, size);
216
210
  if (0 < out->opts->dump_opts.hash_size) {
217
- strcpy(out->cur, out->opts->dump_opts.hash_nl);
218
- out->cur += out->opts->dump_opts.hash_size;
211
+ APPEND_CHARS(out->cur, out->opts->dump_opts.hash_nl, out->opts->dump_opts.hash_size);
219
212
  }
220
213
  if (0 < out->opts->dump_opts.indent_size) {
221
214
  int i;
222
215
  for (i = depth; 0 < i; i--) {
223
- strcpy(out->cur, out->opts->dump_opts.indent_str);
224
- out->cur += out->opts->dump_opts.indent_size;
216
+ APPEND_CHARS(out->cur, out->opts->dump_opts.indent_str, out->opts->dump_opts.indent_size);
225
217
  }
226
218
  }
227
219
  if (rtype == T_STRING) {
@@ -232,13 +224,11 @@ static int hash_cb(VALUE key, VALUE value, VALUE ov) {
232
224
  size = out->opts->dump_opts.before_size + out->opts->dump_opts.after_size + 2;
233
225
  assure_size(out, size);
234
226
  if (0 < out->opts->dump_opts.before_size) {
235
- strcpy(out->cur, out->opts->dump_opts.before_sep);
236
- out->cur += out->opts->dump_opts.before_size;
227
+ APPEND_CHARS(out->cur, out->opts->dump_opts.before_sep, out->opts->dump_opts.before_size);
237
228
  }
238
229
  *out->cur++ = ':';
239
230
  if (0 < out->opts->dump_opts.after_size) {
240
- strcpy(out->cur, out->opts->dump_opts.after_sep);
241
- out->cur += out->opts->dump_opts.after_size;
231
+ APPEND_CHARS(out->cur, out->opts->dump_opts.after_sep, out->opts->dump_opts.after_size);
242
232
  }
243
233
  }
244
234
  if (NullMode == out->opts->mode) {
@@ -281,15 +271,13 @@ static void dump_hash(VALUE obj, int depth, Out out, bool as_ok) {
281
271
  size = depth * out->opts->dump_opts.indent_size + out->opts->dump_opts.hash_size + 1;
282
272
  assure_size(out, size);
283
273
  if (0 < out->opts->dump_opts.hash_size) {
284
- strcpy(out->cur, out->opts->dump_opts.hash_nl);
285
- out->cur += out->opts->dump_opts.hash_size;
274
+ APPEND_CHARS(out->cur, out->opts->dump_opts.hash_nl, out->opts->dump_opts.hash_size);
286
275
  }
287
276
  if (0 < out->opts->dump_opts.indent_size) {
288
277
  int i;
289
278
 
290
279
  for (i = depth; 0 < i; i--) {
291
- strcpy(out->cur, out->opts->dump_opts.indent_str);
292
- out->cur += out->opts->dump_opts.indent_size;
280
+ APPEND_CHARS(out->cur, out->opts->dump_opts.indent_str, out->opts->dump_opts.indent_size);
293
281
  }
294
282
  }
295
283
  }
data/ext/oj/encoder.c ADDED
@@ -0,0 +1,43 @@
1
+ // Copyright (c) 2011, 2022 Peter Ohler. All rights reserved.
2
+ // Licensed under the MIT License. See LICENSE file in the project root for license details.
3
+
4
+ #include "oj.h"
5
+
6
+ typedef struct _encoder {
7
+ int indent; // indention for dump, default 2
8
+ char circular; // YesNo
9
+ char escape_mode; // Escape_Mode
10
+ char mode; // Mode
11
+ char time_format; // TimeFormat
12
+ char bigdec_as_num; // YesNo
13
+ char to_hash; // YesNo
14
+ char to_json; // YesNo
15
+ char as_json; // YesNo
16
+ char raw_json; // YesNo
17
+ char trace; // YesNo
18
+ char sec_prec_set; // boolean (0 or 1)
19
+ char ignore_under; // YesNo - ignore attrs starting with _ if true in object and custom modes
20
+ int64_t int_range_min; // dump numbers below as string
21
+ int64_t int_range_max; // dump numbers above as string
22
+ const char* create_id; // 0 or string
23
+ size_t create_id_len; // length of create_id
24
+ int sec_prec; // second precision when dumping time
25
+ char float_prec; // float precision, linked to float_fmt
26
+ char float_fmt[7]; // float format for dumping, if empty use Ruby
27
+ struct _dumpOpts dump_opts;
28
+ struct _rxClass str_rx;
29
+ VALUE* ignore; // Qnil terminated array of classes or NULL
30
+ } * Encoder;
31
+
32
+ /*
33
+ rb_define_module_function(Oj, "encode", encode, -1);
34
+ rb_define_module_function(Oj, "to_file", to_file, -1); // or maybe just write
35
+ rb_define_module_function(Oj, "to_stream", to_stream, -1);
36
+ */
37
+
38
+ // write(to, obj)
39
+ // if to is a string then open file
40
+ // else if stream then write to stream
41
+ // handle non-blocking
42
+
43
+ // should each mode have a different encoder or use delegates like the parser?
data/ext/oj/fast.c CHANGED
@@ -13,6 +13,7 @@
13
13
 
14
14
  #include "encode.h"
15
15
  #include "oj.h"
16
+ #include "dump.h"
16
17
 
17
18
  // maximum to allocate on the stack, arbitrary limit
18
19
  #define SMALL_JSON 65536
@@ -771,7 +772,7 @@ static VALUE parse_json(VALUE clas, char *json, bool given, bool allocated) {
771
772
  pi.doc = doc;
772
773
  #if IS_WINDOWS
773
774
  // assume a 1M stack and give half to ruby
774
- pi.stack_min = (void*)((char*)&pi - (512 * 1024));
775
+ pi.stack_min = (void *)((char *)&pi - (512L * 1024L));
775
776
  #else
776
777
  {
777
778
  struct rlimit lim;
@@ -1492,6 +1493,7 @@ static VALUE doc_each_child(int argc, VALUE *argv, VALUE self) {
1492
1493
  Doc doc = self_doc(self);
1493
1494
  const char *path = 0;
1494
1495
  size_t wlen;
1496
+ Leaf * where_orig = doc->where;
1495
1497
 
1496
1498
  wlen = doc->where - doc->where_path;
1497
1499
  if (0 < wlen) {
@@ -1508,9 +1510,13 @@ static VALUE doc_each_child(int argc, VALUE *argv, VALUE self) {
1508
1510
  if (0 < wlen) {
1509
1511
  memcpy(doc->where_path, save_path, sizeof(Leaf) * (wlen + 1));
1510
1512
  }
1513
+ doc->where = where_orig;
1511
1514
  return Qnil;
1512
1515
  }
1513
1516
  }
1517
+ if (NULL == doc->where || NULL == *doc->where) {
1518
+ return Qnil;
1519
+ }
1514
1520
  if (COL_VAL == (*doc->where)->value_type && 0 != (*doc->where)->elements) {
1515
1521
  Leaf first = (*doc->where)->elements->next;
1516
1522
  Leaf e = first;
@@ -1525,6 +1531,7 @@ static VALUE doc_each_child(int argc, VALUE *argv, VALUE self) {
1525
1531
  if (0 < wlen) {
1526
1532
  memcpy(doc->where_path, save_path, sizeof(Leaf) * (wlen + 1));
1527
1533
  }
1534
+ doc->where = where_orig;
1528
1535
  }
1529
1536
  return Qnil;
1530
1537
  }
@@ -1604,18 +1611,15 @@ static VALUE doc_dump(int argc, VALUE *argv, VALUE self) {
1604
1611
  volatile VALUE rjson;
1605
1612
 
1606
1613
  if (0 == filename) {
1607
- char buf[4096];
1608
1614
  struct _out out;
1609
1615
 
1610
- out.buf = buf;
1611
- out.end = buf + sizeof(buf) - 10;
1612
- out.allocated = false;
1616
+ oj_out_init(&out);
1617
+
1613
1618
  out.omit_nil = oj_default_options.dump_opts.omit_nil;
1614
1619
  oj_dump_leaf_to_json(leaf, &oj_default_options, &out);
1615
1620
  rjson = rb_str_new2(out.buf);
1616
- if (out.allocated) {
1617
- xfree(out.buf);
1618
- }
1621
+
1622
+ oj_out_free(&out);
1619
1623
  } else {
1620
1624
  oj_write_leaf_to_file(leaf, filename, &oj_default_options);
1621
1625
  rjson = Qnil;
@@ -1711,8 +1715,10 @@ static VALUE doc_not_implemented(VALUE self) {
1711
1715
  * # Now try again using a path to Oj::Doc.fetch() directly and not using a
1712
1716
  * block. doc = Oj::Doc.open(json) doc.fetch('/2/three') #=> 3 doc.close()
1713
1717
  */
1714
- void oj_init_doc() {
1718
+ void oj_init_doc(void) {
1715
1719
  oj_doc_class = rb_define_class_under(Oj, "Doc", rb_cObject);
1720
+ rb_gc_register_address(&oj_doc_class);
1721
+ rb_undef_alloc_func(oj_doc_class);
1716
1722
  rb_define_singleton_method(oj_doc_class, "open", doc_open, 1);
1717
1723
  rb_define_singleton_method(oj_doc_class, "open_file", doc_open_file, 1);
1718
1724
  rb_define_singleton_method(oj_doc_class, "parse", doc_open, 1);
data/ext/oj/intern.c CHANGED
@@ -86,8 +86,12 @@ static VALUE form_attr(const char *str, size_t len) {
86
86
  return (VALUE)rb_intern3(buf, len + 1, oj_utf8_encoding);
87
87
  }
88
88
 
89
- void oj_hash_init() {
89
+ void oj_hash_init(void) {
90
90
  VALUE cache_class = rb_define_class_under(Oj, "Cache", rb_cObject);
91
+ rb_undef_alloc_func(cache_class);
92
+
93
+ rb_gc_register_address(&cache_class);
94
+ rb_undef_alloc_func(cache_class);
91
95
 
92
96
  str_cache = cache_create(0, form_str, true, true);
93
97
  str_cache_obj = Data_Wrap_Struct(cache_class, cache_mark, cache_free, str_cache);
@@ -275,6 +279,7 @@ VALUE oj_class_intern(const char *key, size_t len, bool safe, ParseInfo pi, int
275
279
  bucket->len = len;
276
280
  bucket->val = resolve_classpath(pi, key, len, auto_define, error_class);
277
281
  }
282
+ rb_gc_register_mark_object(bucket->val);
278
283
  return bucket->val;
279
284
  }
280
285
 
@@ -287,8 +292,10 @@ char *oj_strndup(const char *s, size_t len) {
287
292
  return d;
288
293
  }
289
294
 
290
- void intern_cleanup() {
295
+ /*
296
+ void intern_cleanup(void) {
291
297
  cache_free(str_cache);
292
298
  cache_free(sym_cache);
293
299
  cache_free(attr_cache);
294
300
  }
301
+ */