oj 3.13.7 → 3.13.23

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 (83) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +75 -0
  3. data/README.md +11 -0
  4. data/ext/oj/buf.h +4 -0
  5. data/ext/oj/circarray.c +1 -1
  6. data/ext/oj/code.c +15 -22
  7. data/ext/oj/compat.c +10 -10
  8. data/ext/oj/custom.c +66 -112
  9. data/ext/oj/dump.c +147 -184
  10. data/ext/oj/dump.h +25 -8
  11. data/ext/oj/dump_compat.c +47 -89
  12. data/ext/oj/dump_leaf.c +14 -58
  13. data/ext/oj/dump_object.c +72 -188
  14. data/ext/oj/dump_strict.c +19 -31
  15. data/ext/oj/encoder.c +43 -0
  16. data/ext/oj/extconf.rb +5 -4
  17. data/ext/oj/fast.c +36 -24
  18. data/ext/oj/intern.c +22 -12
  19. data/ext/oj/intern.h +1 -1
  20. data/ext/oj/mimic_json.c +74 -73
  21. data/ext/oj/object.c +54 -72
  22. data/ext/oj/odd.c +83 -63
  23. data/ext/oj/odd.h +13 -13
  24. data/ext/oj/oj.c +166 -175
  25. data/ext/oj/oj.h +25 -3
  26. data/ext/oj/parse.c +123 -79
  27. data/ext/oj/parse.h +2 -0
  28. data/ext/oj/parser.c +77 -21
  29. data/ext/oj/parser.h +12 -0
  30. data/ext/oj/rails.c +46 -70
  31. data/ext/oj/rails.h +1 -1
  32. data/ext/oj/reader.c +2 -0
  33. data/ext/oj/saj.c +11 -23
  34. data/ext/oj/saj2.c +333 -85
  35. data/ext/oj/saj2.h +23 -0
  36. data/ext/oj/sparse.c +4 -0
  37. data/ext/oj/stream_writer.c +3 -1
  38. data/ext/oj/strict.c +13 -13
  39. data/ext/oj/string_writer.c +12 -5
  40. data/ext/oj/usual.c +86 -131
  41. data/ext/oj/usual.h +68 -0
  42. data/ext/oj/val_stack.c +1 -1
  43. data/ext/oj/validate.c +21 -26
  44. data/ext/oj/wab.c +22 -27
  45. data/lib/oj/saj.rb +20 -6
  46. data/lib/oj/state.rb +1 -1
  47. data/lib/oj/version.rb +1 -1
  48. data/pages/Compatibility.md +1 -1
  49. data/pages/JsonGem.md +15 -0
  50. data/pages/Modes.md +6 -3
  51. data/pages/Options.md +6 -0
  52. data/pages/Rails.md +12 -0
  53. data/test/activesupport7/abstract_unit.rb +49 -0
  54. data/test/activesupport7/decoding_test.rb +125 -0
  55. data/test/activesupport7/encoding_test.rb +486 -0
  56. data/test/activesupport7/encoding_test_cases.rb +104 -0
  57. data/test/activesupport7/time_zone_test_helpers.rb +47 -0
  58. data/test/bar.rb +3 -8
  59. data/test/bug.rb +16 -0
  60. data/test/foo.rb +71 -7
  61. data/test/helper.rb +8 -2
  62. data/test/json_gem/json_generator_test.rb +5 -4
  63. data/test/json_gem/json_parser_test.rb +8 -1
  64. data/test/json_gem/test_helper.rb +7 -3
  65. data/test/perf_dump.rb +50 -0
  66. data/test/test_compat.rb +25 -0
  67. data/test/test_custom.rb +13 -2
  68. data/test/test_fast.rb +37 -7
  69. data/test/test_file.rb +23 -7
  70. data/test/test_gc.rb +11 -0
  71. data/test/test_object.rb +8 -10
  72. data/test/test_parser.rb +3 -19
  73. data/test/test_parser_debug.rb +27 -0
  74. data/test/test_parser_saj.rb +92 -2
  75. data/test/test_saj.rb +1 -1
  76. data/test/test_scp.rb +2 -4
  77. data/test/test_strict.rb +2 -0
  78. data/test/test_various.rb +32 -2
  79. data/test/test_wab.rb +2 -0
  80. data/test/tests.rb +9 -1
  81. data/test/tests_mimic.rb +9 -0
  82. data/test/tests_mimic_addition.rb +9 -0
  83. metadata +15 -115
data/ext/oj/usual.c CHANGED
@@ -3,6 +3,7 @@
3
3
  #include "cache.h"
4
4
  #include "oj.h"
5
5
  #include "parser.h"
6
+ #include "usual.h"
6
7
 
7
8
  // The Usual delegate builds Ruby objects during parsing. It makes use of
8
9
  // three stacks. The first is the value stack. This is where parsed values are
@@ -28,61 +29,6 @@
28
29
 
29
30
  #define DEBUG 0
30
31
 
31
- // Used to mark the start of each Hash, Array, or Object. The members point at
32
- // positions of the start in the value stack and if not an Array into the key
33
- // stack.
34
- typedef struct _col {
35
- long vi; // value stack index
36
- long ki; // key stack index if an hash else -1 for an array
37
- } * Col;
38
-
39
- typedef union _key {
40
- struct {
41
- int16_t len;
42
- char buf[30];
43
- };
44
- struct {
45
- int16_t xlen; // should be the same as len
46
- char * key;
47
- };
48
- } * Key;
49
-
50
- #define MISS_AUTO 'A'
51
- #define MISS_RAISE 'R'
52
- #define MISS_IGNORE 'I'
53
-
54
- typedef struct _delegate {
55
- VALUE *vhead;
56
- VALUE *vtail;
57
- VALUE *vend;
58
-
59
- Col chead;
60
- Col ctail;
61
- Col cend;
62
-
63
- Key khead;
64
- Key ktail;
65
- Key kend;
66
-
67
- VALUE (*get_key)(ojParser p, Key kp);
68
- struct _cache *key_cache; // same as str_cache or sym_cache
69
- struct _cache *str_cache;
70
- struct _cache *sym_cache;
71
- struct _cache *class_cache;
72
- struct _cache *attr_cache;
73
-
74
- VALUE array_class;
75
- VALUE hash_class;
76
-
77
- char * create_id;
78
- uint8_t create_id_len;
79
- uint8_t cache_str;
80
- uint8_t cache_xrate;
81
- uint8_t miss_class;
82
- bool cache_keys;
83
- bool ignore_json_create;
84
- } * Delegate;
85
-
86
32
  static ID to_f_id = 0;
87
33
  static ID ltlt_id = 0;
88
34
  static ID hset_id = 0;
@@ -178,7 +124,7 @@ static VALUE form_class_auto(const char *str, size_t len) {
178
124
  return resolve_classpath(str, len, true);
179
125
  }
180
126
 
181
- static void assure_cstack(Delegate d) {
127
+ static void assure_cstack(Usual d) {
182
128
  if (d->cend <= d->ctail + 1) {
183
129
  size_t cap = d->cend - d->chead;
184
130
  long pos = d->ctail - d->chead;
@@ -191,7 +137,7 @@ static void assure_cstack(Delegate d) {
191
137
  }
192
138
 
193
139
  static void push(ojParser p, VALUE v) {
194
- Delegate d = (Delegate)p->ctx;
140
+ Usual d = (Usual)p->ctx;
195
141
 
196
142
  if (d->vend <= d->vtail) {
197
143
  size_t cap = d->vend - d->vhead;
@@ -207,7 +153,7 @@ static void push(ojParser p, VALUE v) {
207
153
  }
208
154
 
209
155
  static VALUE cache_key(ojParser p, Key kp) {
210
- Delegate d = (Delegate)p->ctx;
156
+ Usual d = (Usual)p->ctx;
211
157
 
212
158
  if ((size_t)kp->len < sizeof(kp->buf)) {
213
159
  return cache_intern(d->key_cache, kp->buf, kp->len);
@@ -230,7 +176,7 @@ static VALUE sym_key(ojParser p, Key kp) {
230
176
  }
231
177
 
232
178
  static ID get_attr_id(ojParser p, Key kp) {
233
- Delegate d = (Delegate)p->ctx;
179
+ Usual d = (Usual)p->ctx;
234
180
 
235
181
  if ((size_t)kp->len < sizeof(kp->buf)) {
236
182
  return (ID)cache_intern(d->attr_cache, kp->buf, kp->len);
@@ -239,7 +185,7 @@ static ID get_attr_id(ojParser p, Key kp) {
239
185
  }
240
186
 
241
187
  static void push_key(ojParser p) {
242
- Delegate d = (Delegate)p->ctx;
188
+ Usual d = (Usual)p->ctx;
243
189
  size_t klen = buf_len(&p->key);
244
190
  const char *key = buf_str(&p->key);
245
191
 
@@ -263,7 +209,7 @@ static void push_key(ojParser p) {
263
209
  }
264
210
 
265
211
  static void push2(ojParser p, VALUE v) {
266
- Delegate d = (Delegate)p->ctx;
212
+ Usual d = (Usual)p->ctx;
267
213
 
268
214
  if (d->vend <= d->vtail + 1) {
269
215
  size_t cap = d->vend - d->vhead;
@@ -281,7 +227,7 @@ static void push2(ojParser p, VALUE v) {
281
227
  }
282
228
 
283
229
  static void open_object(ojParser p) {
284
- Delegate d = (Delegate)p->ctx;
230
+ Usual d = (Usual)p->ctx;
285
231
 
286
232
  assure_cstack(d);
287
233
  d->ctail->vi = d->vtail - d->vhead;
@@ -291,7 +237,7 @@ static void open_object(ojParser p) {
291
237
  }
292
238
 
293
239
  static void open_object_key(ojParser p) {
294
- Delegate d = (Delegate)p->ctx;
240
+ Usual d = (Usual)p->ctx;
295
241
 
296
242
  push_key(p);
297
243
  assure_cstack(d);
@@ -302,7 +248,7 @@ static void open_object_key(ojParser p) {
302
248
  }
303
249
 
304
250
  static void open_array(ojParser p) {
305
- Delegate d = (Delegate)p->ctx;
251
+ Usual d = (Usual)p->ctx;
306
252
 
307
253
  assure_cstack(d);
308
254
  d->ctail->vi = d->vtail - d->vhead;
@@ -312,7 +258,7 @@ static void open_array(ojParser p) {
312
258
  }
313
259
 
314
260
  static void open_array_key(ojParser p) {
315
- Delegate d = (Delegate)p->ctx;
261
+ Usual d = (Usual)p->ctx;
316
262
 
317
263
  push_key(p);
318
264
  assure_cstack(d);
@@ -324,7 +270,7 @@ static void open_array_key(ojParser p) {
324
270
 
325
271
  static void close_object(ojParser p) {
326
272
  VALUE * vp;
327
- Delegate d = (Delegate)p->ctx;
273
+ Usual d = (Usual)p->ctx;
328
274
 
329
275
  d->ctail--;
330
276
 
@@ -357,7 +303,7 @@ static void close_object(ojParser p) {
357
303
 
358
304
  static void close_object_class(ojParser p) {
359
305
  VALUE * vp;
360
- Delegate d = (Delegate)p->ctx;
306
+ Usual d = (Usual)p->ctx;
361
307
 
362
308
  d->ctail--;
363
309
 
@@ -380,7 +326,7 @@ static void close_object_class(ojParser p) {
380
326
 
381
327
  static void close_object_create(ojParser p) {
382
328
  VALUE * vp;
383
- Delegate d = (Delegate)p->ctx;
329
+ Usual d = (Usual)p->ctx;
384
330
 
385
331
  d->ctail--;
386
332
 
@@ -459,7 +405,7 @@ static void close_object_create(ojParser p) {
459
405
  }
460
406
 
461
407
  static void close_array(ojParser p) {
462
- Delegate d = (Delegate)p->ctx;
408
+ Usual d = (Usual)p->ctx;
463
409
 
464
410
  d->ctail--;
465
411
  VALUE * head = d->vhead + d->ctail->vi + 1;
@@ -472,7 +418,7 @@ static void close_array(ojParser p) {
472
418
 
473
419
  static void close_array_class(ojParser p) {
474
420
  VALUE * vp;
475
- Delegate d = (Delegate)p->ctx;
421
+ Usual d = (Usual)p->ctx;
476
422
 
477
423
  d->ctail--;
478
424
  VALUE * head = d->vhead + d->ctail->vi + 1;
@@ -537,7 +483,7 @@ static void add_float_key(ojParser p) {
537
483
  static void add_float_as_big(ojParser p) {
538
484
  char buf[64];
539
485
 
540
- // fails on ubuntu
486
+ // snprintf fails on ubuntu and macOS for long double
541
487
  // snprintf(buf, sizeof(buf), "%Lg", p->num.dub);
542
488
  sprintf(buf, "%Lg", p->num.dub);
543
489
  push(p, rb_funcall(rb_cObject, oj_bigdecimal_id, 1, rb_str_new2(buf)));
@@ -546,7 +492,9 @@ static void add_float_as_big(ojParser p) {
546
492
  static void add_float_as_big_key(ojParser p) {
547
493
  char buf[64];
548
494
 
549
- snprintf(buf, sizeof(buf), "%Lg", p->num.dub);
495
+ // snprintf fails on ubuntu and macOS for long double
496
+ // snprintf(buf, sizeof(buf), "%Lg", p->num.dub);
497
+ sprintf(buf, "%Lg", p->num.dub);
550
498
  push_key(p);
551
499
  push2(p, rb_funcall(rb_cObject, oj_bigdecimal_id, 1, rb_str_new2(buf)));
552
500
  }
@@ -583,7 +531,7 @@ static void add_big_as_ruby_key(ojParser p) {
583
531
  }
584
532
 
585
533
  static void add_str(ojParser p) {
586
- Delegate d = (Delegate)p->ctx;
534
+ Usual d = (Usual)p->ctx;
587
535
  volatile VALUE rstr;
588
536
  const char * str = buf_str(&p->buf);
589
537
  size_t len = buf_len(&p->buf);
@@ -597,7 +545,7 @@ static void add_str(ojParser p) {
597
545
  }
598
546
 
599
547
  static void add_str_key(ojParser p) {
600
- Delegate d = (Delegate)p->ctx;
548
+ Usual d = (Usual)p->ctx;
601
549
  volatile VALUE rstr;
602
550
  const char * str = buf_str(&p->buf);
603
551
  size_t len = buf_len(&p->buf);
@@ -612,7 +560,7 @@ static void add_str_key(ojParser p) {
612
560
  }
613
561
 
614
562
  static void add_str_key_create(ojParser p) {
615
- Delegate d = (Delegate)p->ctx;
563
+ Usual d = (Usual)p->ctx;
616
564
  volatile VALUE rstr;
617
565
  const char * str = buf_str(&p->buf);
618
566
  size_t len = buf_len(&p->buf);
@@ -646,7 +594,7 @@ static void add_str_key_create(ojParser p) {
646
594
  }
647
595
 
648
596
  static VALUE result(ojParser p) {
649
- Delegate d = (Delegate)p->ctx;
597
+ Usual d = (Usual)p->ctx;
650
598
 
651
599
  if (d->vhead < d->vtail) {
652
600
  return *d->vhead;
@@ -655,7 +603,7 @@ static VALUE result(ojParser p) {
655
603
  }
656
604
 
657
605
  static void start(ojParser p) {
658
- Delegate d = (Delegate)p->ctx;
606
+ Usual d = (Usual)p->ctx;
659
607
 
660
608
  d->vtail = d->vhead;
661
609
  d->ctail = d->chead;
@@ -663,7 +611,7 @@ static void start(ojParser p) {
663
611
  }
664
612
 
665
613
  static void dfree(ojParser p) {
666
- Delegate d = (Delegate)p->ctx;
614
+ Usual d = (Usual)p->ctx;
667
615
 
668
616
  cache_free(d->str_cache);
669
617
  cache_free(d->attr_cache);
@@ -682,10 +630,10 @@ static void dfree(ojParser p) {
682
630
  }
683
631
 
684
632
  static void mark(ojParser p) {
685
- if (NULL == p->ctx) {
633
+ if (NULL == p || NULL == p->ctx) {
686
634
  return;
687
635
  }
688
- Delegate d = (Delegate)p->ctx;
636
+ Usual d = (Usual)p->ctx;
689
637
  VALUE * vp;
690
638
 
691
639
  if (NULL == d) {
@@ -718,13 +666,13 @@ struct opt {
718
666
  };
719
667
 
720
668
  static VALUE opt_array_class(ojParser p, VALUE value) {
721
- Delegate d = (Delegate)p->ctx;
669
+ Usual d = (Usual)p->ctx;
722
670
 
723
671
  return d->array_class;
724
672
  }
725
673
 
726
674
  static VALUE opt_array_class_set(ojParser p, VALUE value) {
727
- Delegate d = (Delegate)p->ctx;
675
+ Usual d = (Usual)p->ctx;
728
676
 
729
677
  if (Qnil == value) {
730
678
  p->funcs[TOP_FUN].close_array = close_array;
@@ -745,13 +693,13 @@ static VALUE opt_array_class_set(ojParser p, VALUE value) {
745
693
  }
746
694
 
747
695
  static VALUE opt_cache_keys(ojParser p, VALUE value) {
748
- Delegate d = (Delegate)p->ctx;
696
+ Usual d = (Usual)p->ctx;
749
697
 
750
698
  return d->cache_keys ? Qtrue : Qfalse;
751
699
  }
752
700
 
753
701
  static VALUE opt_cache_keys_set(ojParser p, VALUE value) {
754
- Delegate d = (Delegate)p->ctx;
702
+ Usual d = (Usual)p->ctx;
755
703
 
756
704
  if (Qtrue == value) {
757
705
  d->cache_keys = true;
@@ -773,13 +721,13 @@ static VALUE opt_cache_keys_set(ojParser p, VALUE value) {
773
721
  }
774
722
 
775
723
  static VALUE opt_cache_strings(ojParser p, VALUE value) {
776
- Delegate d = (Delegate)p->ctx;
724
+ Usual d = (Usual)p->ctx;
777
725
 
778
726
  return INT2NUM((int)d->cache_str);
779
727
  }
780
728
 
781
729
  static VALUE opt_cache_strings_set(ojParser p, VALUE value) {
782
- Delegate d = (Delegate)p->ctx;
730
+ Usual d = (Usual)p->ctx;
783
731
  int limit = NUM2INT(value);
784
732
 
785
733
  if (CACHE_MAX_KEY < limit) {
@@ -793,13 +741,13 @@ static VALUE opt_cache_strings_set(ojParser p, VALUE value) {
793
741
  }
794
742
 
795
743
  static VALUE opt_cache_expunge(ojParser p, VALUE value) {
796
- Delegate d = (Delegate)p->ctx;
744
+ Usual d = (Usual)p->ctx;
797
745
 
798
746
  return INT2NUM((int)d->cache_xrate);
799
747
  }
800
748
 
801
749
  static VALUE opt_cache_expunge_set(ojParser p, VALUE value) {
802
- Delegate d = (Delegate)p->ctx;
750
+ Usual d = (Usual)p->ctx;
803
751
  int rate = NUM2INT(value);
804
752
 
805
753
  if (rate < 0) {
@@ -817,13 +765,13 @@ static VALUE opt_cache_expunge_set(ojParser p, VALUE value) {
817
765
  }
818
766
 
819
767
  static VALUE opt_capacity(ojParser p, VALUE value) {
820
- Delegate d = (Delegate)p->ctx;
768
+ Usual d = (Usual)p->ctx;
821
769
 
822
770
  return ULONG2NUM(d->vend - d->vhead);
823
771
  }
824
772
 
825
773
  static VALUE opt_capacity_set(ojParser p, VALUE value) {
826
- Delegate d = (Delegate)p->ctx;
774
+ Usual d = (Usual)p->ctx;
827
775
  long cap = NUM2LONG(value);
828
776
 
829
777
  if (d->vend - d->vhead < cap) {
@@ -844,13 +792,13 @@ static VALUE opt_capacity_set(ojParser p, VALUE value) {
844
792
  }
845
793
 
846
794
  static VALUE opt_class_cache(ojParser p, VALUE value) {
847
- Delegate d = (Delegate)p->ctx;
795
+ Usual d = (Usual)p->ctx;
848
796
 
849
797
  return (NULL != d->class_cache) ? Qtrue : Qfalse;
850
798
  }
851
799
 
852
800
  static VALUE opt_class_cache_set(ojParser p, VALUE value) {
853
- Delegate d = (Delegate)p->ctx;
801
+ Usual d = (Usual)p->ctx;
854
802
 
855
803
  if (Qtrue == value) {
856
804
  if (NULL == d->class_cache) {
@@ -864,7 +812,7 @@ static VALUE opt_class_cache_set(ojParser p, VALUE value) {
864
812
  }
865
813
 
866
814
  static VALUE opt_create_id(ojParser p, VALUE value) {
867
- Delegate d = (Delegate)p->ctx;
815
+ Usual d = (Usual)p->ctx;
868
816
 
869
817
  if (NULL == d->create_id) {
870
818
  return Qnil;
@@ -873,7 +821,7 @@ static VALUE opt_create_id(ojParser p, VALUE value) {
873
821
  }
874
822
 
875
823
  static VALUE opt_create_id_set(ojParser p, VALUE value) {
876
- Delegate d = (Delegate)p->ctx;
824
+ Usual d = (Usual)p->ctx;
877
825
 
878
826
  if (Qnil == value) {
879
827
  d->create_id = NULL;
@@ -983,13 +931,13 @@ static VALUE opt_decimal_set(ojParser p, VALUE value) {
983
931
  }
984
932
 
985
933
  static VALUE opt_hash_class(ojParser p, VALUE value) {
986
- Delegate d = (Delegate)p->ctx;
934
+ Usual d = (Usual)p->ctx;
987
935
 
988
936
  return d->hash_class;
989
937
  }
990
938
 
991
939
  static VALUE opt_hash_class_set(ojParser p, VALUE value) {
992
- Delegate d = (Delegate)p->ctx;
940
+ Usual d = (Usual)p->ctx;
993
941
 
994
942
  if (Qnil != value) {
995
943
  rb_check_type(value, T_CLASS);
@@ -1013,13 +961,13 @@ static VALUE opt_hash_class_set(ojParser p, VALUE value) {
1013
961
  }
1014
962
 
1015
963
  static VALUE opt_ignore_json_create(ojParser p, VALUE value) {
1016
- Delegate d = (Delegate)p->ctx;
964
+ Usual d = (Usual)p->ctx;
1017
965
 
1018
966
  return d->ignore_json_create ? Qtrue : Qfalse;
1019
967
  }
1020
968
 
1021
969
  static VALUE opt_ignore_json_create_set(ojParser p, VALUE value) {
1022
- Delegate d = (Delegate)p->ctx;
970
+ Usual d = (Usual)p->ctx;
1023
971
 
1024
972
  d->ignore_json_create = (Qtrue == value);
1025
973
 
@@ -1027,7 +975,7 @@ static VALUE opt_ignore_json_create_set(ojParser p, VALUE value) {
1027
975
  }
1028
976
 
1029
977
  static VALUE opt_missing_class(ojParser p, VALUE value) {
1030
- Delegate d = (Delegate)p->ctx;
978
+ Usual d = (Usual)p->ctx;
1031
979
 
1032
980
  switch (d->miss_class) {
1033
981
  case MISS_AUTO: return ID2SYM(rb_intern("auto"));
@@ -1038,7 +986,7 @@ static VALUE opt_missing_class(ojParser p, VALUE value) {
1038
986
  }
1039
987
 
1040
988
  static VALUE opt_missing_class_set(ojParser p, VALUE value) {
1041
- Delegate d = (Delegate)p->ctx;
989
+ Usual d = (Usual)p->ctx;
1042
990
  const char * mode;
1043
991
  volatile VALUE s;
1044
992
 
@@ -1089,13 +1037,13 @@ static VALUE opt_omit_null_set(ojParser p, VALUE value) {
1089
1037
  }
1090
1038
 
1091
1039
  static VALUE opt_symbol_keys(ojParser p, VALUE value) {
1092
- Delegate d = (Delegate)p->ctx;
1040
+ Usual d = (Usual)p->ctx;
1093
1041
 
1094
1042
  return (NULL != d->sym_cache) ? Qtrue : Qfalse;
1095
1043
  }
1096
1044
 
1097
1045
  static VALUE opt_symbol_keys_set(ojParser p, VALUE value) {
1098
- Delegate d = (Delegate)p->ctx;
1046
+ Usual d = (Usual)p->ctx;
1099
1047
 
1100
1048
  if (Qtrue == value) {
1101
1049
  d->sym_cache = cache_create(0, form_sym, true, false);
@@ -1119,33 +1067,33 @@ static VALUE opt_symbol_keys_set(ojParser p, VALUE value) {
1119
1067
  static VALUE option(ojParser p, const char *key, VALUE value) {
1120
1068
  struct opt *op;
1121
1069
  struct opt opts[] = {
1122
- {.name = "array_class", .func = opt_array_class},
1123
- {.name = "array_class=", .func = opt_array_class_set},
1124
- {.name = "cache_keys", .func = opt_cache_keys},
1125
- {.name = "cache_keys=", .func = opt_cache_keys_set},
1126
- {.name = "cache_strings", .func = opt_cache_strings},
1127
- {.name = "cache_strings=", .func = opt_cache_strings_set},
1128
- {.name = "cache_expunge", .func = opt_cache_expunge},
1129
- {.name = "cache_expunge=", .func = opt_cache_expunge_set},
1130
- {.name = "capacity", .func = opt_capacity},
1131
- {.name = "capacity=", .func = opt_capacity_set},
1132
- {.name = "class_cache", .func = opt_class_cache},
1133
- {.name = "class_cache=", .func = opt_class_cache_set},
1134
- {.name = "create_id", .func = opt_create_id},
1135
- {.name = "create_id=", .func = opt_create_id_set},
1136
- {.name = "decimal", .func = opt_decimal},
1137
- {.name = "decimal=", .func = opt_decimal_set},
1138
- {.name = "hash_class", .func = opt_hash_class},
1139
- {.name = "hash_class=", .func = opt_hash_class_set},
1140
- {.name = "ignore_json_create", .func = opt_ignore_json_create},
1141
- {.name = "ignore_json_create=", .func = opt_ignore_json_create_set},
1142
- {.name = "missing_class", .func = opt_missing_class},
1143
- {.name = "missing_class=", .func = opt_missing_class_set},
1144
- {.name = "omit_null", .func = opt_omit_null},
1145
- {.name = "omit_null=", .func = opt_omit_null_set},
1146
- {.name = "symbol_keys", .func = opt_symbol_keys},
1147
- {.name = "symbol_keys=", .func = opt_symbol_keys_set},
1148
- {.name = NULL},
1070
+ {.name = "array_class", .func = opt_array_class},
1071
+ {.name = "array_class=", .func = opt_array_class_set},
1072
+ {.name = "cache_keys", .func = opt_cache_keys},
1073
+ {.name = "cache_keys=", .func = opt_cache_keys_set},
1074
+ {.name = "cache_strings", .func = opt_cache_strings},
1075
+ {.name = "cache_strings=", .func = opt_cache_strings_set},
1076
+ {.name = "cache_expunge", .func = opt_cache_expunge},
1077
+ {.name = "cache_expunge=", .func = opt_cache_expunge_set},
1078
+ {.name = "capacity", .func = opt_capacity},
1079
+ {.name = "capacity=", .func = opt_capacity_set},
1080
+ {.name = "class_cache", .func = opt_class_cache},
1081
+ {.name = "class_cache=", .func = opt_class_cache_set},
1082
+ {.name = "create_id", .func = opt_create_id},
1083
+ {.name = "create_id=", .func = opt_create_id_set},
1084
+ {.name = "decimal", .func = opt_decimal},
1085
+ {.name = "decimal=", .func = opt_decimal_set},
1086
+ {.name = "hash_class", .func = opt_hash_class},
1087
+ {.name = "hash_class=", .func = opt_hash_class_set},
1088
+ {.name = "ignore_json_create", .func = opt_ignore_json_create},
1089
+ {.name = "ignore_json_create=", .func = opt_ignore_json_create_set},
1090
+ {.name = "missing_class", .func = opt_missing_class},
1091
+ {.name = "missing_class=", .func = opt_missing_class_set},
1092
+ {.name = "omit_null", .func = opt_omit_null},
1093
+ {.name = "omit_null=", .func = opt_omit_null_set},
1094
+ {.name = "symbol_keys", .func = opt_symbol_keys},
1095
+ {.name = "symbol_keys=", .func = opt_symbol_keys_set},
1096
+ {.name = NULL},
1149
1097
  };
1150
1098
 
1151
1099
  for (op = opts; NULL != op->name; op++) {
@@ -1160,8 +1108,7 @@ static VALUE option(ojParser p, const char *key, VALUE value) {
1160
1108
 
1161
1109
  ///// the set up //////////////////////////////////////////////////////////////
1162
1110
 
1163
- void oj_set_parser_usual(ojParser p) {
1164
- Delegate d = ALLOC(struct _delegate);
1111
+ void oj_init_usual(ojParser p, Usual d) {
1165
1112
  int cap = 4096;
1166
1113
 
1167
1114
  d->vhead = ALLOC_N(VALUE, cap);
@@ -1233,6 +1180,8 @@ void oj_set_parser_usual(ojParser p) {
1233
1180
  d->class_cache = NULL;
1234
1181
  d->key_cache = d->str_cache;
1235
1182
 
1183
+ // The parser fields are set but the functions can be replaced by a
1184
+ // delegate that wraps the usual delegate.
1236
1185
  p->ctx = (void *)d;
1237
1186
  p->option = option;
1238
1187
  p->result = result;
@@ -1250,3 +1199,9 @@ void oj_set_parser_usual(ojParser p) {
1250
1199
  hset_id = rb_intern("[]=");
1251
1200
  }
1252
1201
  }
1202
+
1203
+ void oj_set_parser_usual(ojParser p) {
1204
+ Usual d = ALLOC(struct _usual);
1205
+
1206
+ oj_init_usual(p, d);
1207
+ }
data/ext/oj/usual.h ADDED
@@ -0,0 +1,68 @@
1
+ // Copyright (c) 2022, Peter Ohler, All rights reserved.
2
+
3
+ #include <ruby.h>
4
+ #include <stdbool.h>
5
+ #include <stdint.h>
6
+
7
+ struct _cache;
8
+ struct _ojParser;
9
+
10
+ // Used to mark the start of each Hash, Array, or Object. The members point at
11
+ // positions of the start in the value stack and if not an Array into the key
12
+ // stack.
13
+ typedef struct _col {
14
+ long vi; // value stack index
15
+ long ki; // key stack index if an hash else -1 for an array
16
+ } * Col;
17
+
18
+ typedef union _key {
19
+ struct {
20
+ int16_t len;
21
+ char buf[30];
22
+ };
23
+ struct {
24
+ int16_t xlen; // should be the same as len
25
+ char * key;
26
+ };
27
+ } * Key;
28
+
29
+ #define MISS_AUTO 'A'
30
+ #define MISS_RAISE 'R'
31
+ #define MISS_IGNORE 'I'
32
+
33
+ typedef struct _usual {
34
+ VALUE *vhead;
35
+ VALUE *vtail;
36
+ VALUE *vend;
37
+
38
+ Col chead;
39
+ Col ctail;
40
+ Col cend;
41
+
42
+ Key khead;
43
+ Key ktail;
44
+ Key kend;
45
+
46
+ VALUE (*get_key)(ojParser p, Key kp);
47
+ struct _cache *key_cache; // same as str_cache or sym_cache
48
+ struct _cache *str_cache;
49
+ struct _cache *sym_cache;
50
+ struct _cache *class_cache;
51
+ struct _cache *attr_cache;
52
+
53
+ VALUE array_class;
54
+ VALUE hash_class;
55
+
56
+ char * create_id;
57
+ uint8_t create_id_len;
58
+ uint8_t cache_str;
59
+ uint8_t cache_xrate;
60
+ uint8_t miss_class;
61
+ bool cache_keys;
62
+ bool ignore_json_create;
63
+ } * Usual;
64
+
65
+ // Initialize the parser with the usual delegate. If the usual delegate is
66
+ // wrapped then this function is called first and then the parser functions
67
+ // can be replaced.
68
+ extern void oj_init_usual(struct _ojParser *p, Usual d);
data/ext/oj/val_stack.c CHANGED
@@ -12,7 +12,7 @@ static void mark(void *ptr) {
12
12
  ValStack stack = (ValStack)ptr;
13
13
  Val v;
14
14
 
15
- if (0 == ptr) {
15
+ if (NULL == ptr) {
16
16
  return;
17
17
  }
18
18
  #ifdef HAVE_PTHREAD_MUTEX_INIT
data/ext/oj/validate.c CHANGED
@@ -2,50 +2,45 @@
2
2
 
3
3
  #include "parser.h"
4
4
 
5
- static void
6
- noop(ojParser p) {
5
+ static void noop(ojParser p) {
7
6
  }
8
7
 
9
- static VALUE
10
- option(ojParser p, const char *key, VALUE value) {
8
+ static VALUE option(ojParser p, const char *key, VALUE value) {
11
9
  rb_raise(rb_eArgError, "%s is not an option for the validate delegate", key);
12
10
  return Qnil;
13
11
  }
14
12
 
15
- static VALUE
16
- result(ojParser p) {
13
+ static VALUE result(ojParser p) {
17
14
  return Qnil;
18
15
  }
19
16
 
20
- static void
21
- dfree(ojParser p) {
17
+ static void dfree(ojParser p) {
22
18
  }
23
19
 
24
- static void
25
- mark(ojParser p) {
20
+ static void mark(ojParser p) {
26
21
  }
27
22
 
28
23
  void oj_set_parser_validator(ojParser p) {
29
- p->ctx = NULL;
30
- Funcs end = p->funcs + 3;
24
+ Funcs end = p->funcs + 3;
31
25
  Funcs f;
26
+ p->ctx = NULL;
32
27
 
33
28
  for (f = p->funcs; f < end; f++) {
34
- f->add_null = noop;
35
- f->add_true = noop;
36
- f->add_false = noop;
37
- f->add_int = noop;
38
- f->add_float = noop;
39
- f->add_big = noop;
40
- f->add_str = noop;
41
- f->open_array = noop;
42
- f->close_array = noop;
43
- f->open_object = noop;
44
- f->close_object = noop;
29
+ f->add_null = noop;
30
+ f->add_true = noop;
31
+ f->add_false = noop;
32
+ f->add_int = noop;
33
+ f->add_float = noop;
34
+ f->add_big = noop;
35
+ f->add_str = noop;
36
+ f->open_array = noop;
37
+ f->close_array = noop;
38
+ f->open_object = noop;
39
+ f->close_object = noop;
45
40
  }
46
41
  p->option = option;
47
42
  p->result = result;
48
- p->free = dfree;
49
- p->mark = mark;
50
- p->start = noop;
43
+ p->free = dfree;
44
+ p->mark = mark;
45
+ p->start = noop;
51
46
  }