oj 3.13.9 → 3.13.12

Sign up to get free protection for your applications and to get access to all the features.
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
+ */