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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +75 -0
- data/README.md +11 -0
- data/ext/oj/buf.h +4 -0
- data/ext/oj/circarray.c +1 -1
- data/ext/oj/code.c +15 -22
- data/ext/oj/compat.c +10 -10
- data/ext/oj/custom.c +66 -112
- data/ext/oj/dump.c +147 -184
- data/ext/oj/dump.h +25 -8
- data/ext/oj/dump_compat.c +47 -89
- data/ext/oj/dump_leaf.c +14 -58
- data/ext/oj/dump_object.c +72 -188
- data/ext/oj/dump_strict.c +19 -31
- data/ext/oj/encoder.c +43 -0
- data/ext/oj/extconf.rb +5 -4
- data/ext/oj/fast.c +36 -24
- data/ext/oj/intern.c +22 -12
- data/ext/oj/intern.h +1 -1
- data/ext/oj/mimic_json.c +74 -73
- data/ext/oj/object.c +54 -72
- data/ext/oj/odd.c +83 -63
- data/ext/oj/odd.h +13 -13
- data/ext/oj/oj.c +166 -175
- data/ext/oj/oj.h +25 -3
- data/ext/oj/parse.c +123 -79
- data/ext/oj/parse.h +2 -0
- data/ext/oj/parser.c +77 -21
- data/ext/oj/parser.h +12 -0
- data/ext/oj/rails.c +46 -70
- data/ext/oj/rails.h +1 -1
- data/ext/oj/reader.c +2 -0
- data/ext/oj/saj.c +11 -23
- data/ext/oj/saj2.c +333 -85
- data/ext/oj/saj2.h +23 -0
- data/ext/oj/sparse.c +4 -0
- data/ext/oj/stream_writer.c +3 -1
- data/ext/oj/strict.c +13 -13
- data/ext/oj/string_writer.c +12 -5
- data/ext/oj/usual.c +86 -131
- data/ext/oj/usual.h +68 -0
- data/ext/oj/val_stack.c +1 -1
- data/ext/oj/validate.c +21 -26
- data/ext/oj/wab.c +22 -27
- data/lib/oj/saj.rb +20 -6
- data/lib/oj/state.rb +1 -1
- data/lib/oj/version.rb +1 -1
- data/pages/Compatibility.md +1 -1
- data/pages/JsonGem.md +15 -0
- data/pages/Modes.md +6 -3
- data/pages/Options.md +6 -0
- data/pages/Rails.md +12 -0
- data/test/activesupport7/abstract_unit.rb +49 -0
- data/test/activesupport7/decoding_test.rb +125 -0
- data/test/activesupport7/encoding_test.rb +486 -0
- data/test/activesupport7/encoding_test_cases.rb +104 -0
- data/test/activesupport7/time_zone_test_helpers.rb +47 -0
- data/test/bar.rb +3 -8
- data/test/bug.rb +16 -0
- data/test/foo.rb +71 -7
- data/test/helper.rb +8 -2
- data/test/json_gem/json_generator_test.rb +5 -4
- data/test/json_gem/json_parser_test.rb +8 -1
- data/test/json_gem/test_helper.rb +7 -3
- data/test/perf_dump.rb +50 -0
- data/test/test_compat.rb +25 -0
- data/test/test_custom.rb +13 -2
- data/test/test_fast.rb +37 -7
- data/test/test_file.rb +23 -7
- data/test/test_gc.rb +11 -0
- data/test/test_object.rb +8 -10
- data/test/test_parser.rb +3 -19
- data/test/test_parser_debug.rb +27 -0
- data/test/test_parser_saj.rb +92 -2
- data/test/test_saj.rb +1 -1
- data/test/test_scp.rb +2 -4
- data/test/test_strict.rb +2 -0
- data/test/test_various.rb +32 -2
- data/test/test_wab.rb +2 -0
- data/test/tests.rb +9 -1
- data/test/tests_mimic.rb +9 -0
- data/test/tests_mimic_addition.rb +9 -0
- metadata +15 -115
data/ext/oj/parser.c
CHANGED
@@ -11,8 +11,8 @@
|
|
11
11
|
#define USE_THREAD_LIMIT 0
|
12
12
|
// #define USE_THREAD_LIMIT 100000
|
13
13
|
#define MAX_EXP 4932
|
14
|
-
// max in the pow_map
|
15
|
-
#define MAX_POW
|
14
|
+
// max in the pow_map which is the limit for double
|
15
|
+
#define MAX_POW 308
|
16
16
|
|
17
17
|
#define MIN_SLEEP (1000000000LL / (double)CLOCKS_PER_SEC)
|
18
18
|
// 9,223,372,036,854,775,807
|
@@ -385,7 +385,7 @@ static const byte hex_map[256] = "\
|
|
385
385
|
................................\
|
386
386
|
................................";
|
387
387
|
|
388
|
-
static long double pow_map[
|
388
|
+
static long double pow_map[309] = {
|
389
389
|
1.0L, 1.0e1L, 1.0e2L, 1.0e3L, 1.0e4L, 1.0e5L, 1.0e6L, 1.0e7L, 1.0e8L, 1.0e9L, 1.0e10L,
|
390
390
|
1.0e11L, 1.0e12L, 1.0e13L, 1.0e14L, 1.0e15L, 1.0e16L, 1.0e17L, 1.0e18L, 1.0e19L, 1.0e20L, 1.0e21L,
|
391
391
|
1.0e22L, 1.0e23L, 1.0e24L, 1.0e25L, 1.0e26L, 1.0e27L, 1.0e28L, 1.0e29L, 1.0e30L, 1.0e31L, 1.0e32L,
|
@@ -414,15 +414,7 @@ static long double pow_map[401] = {
|
|
414
414
|
1.0e275L, 1.0e276L, 1.0e277L, 1.0e278L, 1.0e279L, 1.0e280L, 1.0e281L, 1.0e282L, 1.0e283L, 1.0e284L, 1.0e285L,
|
415
415
|
1.0e286L, 1.0e287L, 1.0e288L, 1.0e289L, 1.0e290L, 1.0e291L, 1.0e292L, 1.0e293L, 1.0e294L, 1.0e295L, 1.0e296L,
|
416
416
|
1.0e297L, 1.0e298L, 1.0e299L, 1.0e300L, 1.0e301L, 1.0e302L, 1.0e303L, 1.0e304L, 1.0e305L, 1.0e306L, 1.0e307L,
|
417
|
-
1.0e308L
|
418
|
-
1.0e319L, 1.0e320L, 1.0e321L, 1.0e322L, 1.0e323L, 1.0e324L, 1.0e325L, 1.0e326L, 1.0e327L, 1.0e328L, 1.0e329L,
|
419
|
-
1.0e330L, 1.0e331L, 1.0e332L, 1.0e333L, 1.0e334L, 1.0e335L, 1.0e336L, 1.0e337L, 1.0e338L, 1.0e339L, 1.0e340L,
|
420
|
-
1.0e341L, 1.0e342L, 1.0e343L, 1.0e344L, 1.0e345L, 1.0e346L, 1.0e347L, 1.0e348L, 1.0e349L, 1.0e350L, 1.0e351L,
|
421
|
-
1.0e352L, 1.0e353L, 1.0e354L, 1.0e355L, 1.0e356L, 1.0e357L, 1.0e358L, 1.0e359L, 1.0e360L, 1.0e361L, 1.0e362L,
|
422
|
-
1.0e363L, 1.0e364L, 1.0e365L, 1.0e366L, 1.0e367L, 1.0e368L, 1.0e369L, 1.0e370L, 1.0e371L, 1.0e372L, 1.0e373L,
|
423
|
-
1.0e374L, 1.0e375L, 1.0e376L, 1.0e377L, 1.0e378L, 1.0e379L, 1.0e380L, 1.0e381L, 1.0e382L, 1.0e383L, 1.0e384L,
|
424
|
-
1.0e385L, 1.0e386L, 1.0e387L, 1.0e388L, 1.0e389L, 1.0e390L, 1.0e391L, 1.0e392L, 1.0e393L, 1.0e394L, 1.0e395L,
|
425
|
-
1.0e396L, 1.0e397L, 1.0e398L, 1.0e399L, 1.0e400L};
|
417
|
+
1.0e308L};
|
426
418
|
|
427
419
|
static VALUE parser_class;
|
428
420
|
|
@@ -541,6 +533,7 @@ static void calc_num(ojParser p) {
|
|
541
533
|
// nothing to do
|
542
534
|
break;
|
543
535
|
}
|
536
|
+
p->type = OJ_NONE;
|
544
537
|
}
|
545
538
|
|
546
539
|
static void big_change(ojParser p) {
|
@@ -606,6 +599,8 @@ static void parse(ojParser p, const byte *json) {
|
|
606
599
|
const byte *b = json;
|
607
600
|
int i;
|
608
601
|
|
602
|
+
p->line = 1;
|
603
|
+
p->col = -1;
|
609
604
|
#if DEBUG
|
610
605
|
printf("*** parse - mode: %c %s\n", p->map[256], (const char *)json);
|
611
606
|
#endif
|
@@ -660,6 +655,7 @@ static void parse(ojParser p, const byte *json) {
|
|
660
655
|
}
|
661
656
|
buf_append_string(&p->buf, (const char *)start, b - start);
|
662
657
|
if ('"' == *b) {
|
658
|
+
p->cur = b - json;
|
663
659
|
p->funcs[p->stack[p->depth]].add_str(p);
|
664
660
|
p->map = (0 == p->depth) ? value_map : after_map;
|
665
661
|
break;
|
@@ -669,12 +665,14 @@ static void parse(ojParser p, const byte *json) {
|
|
669
665
|
p->next_map = (0 == p->depth) ? value_map : after_map;
|
670
666
|
break;
|
671
667
|
case OPEN_OBJECT:
|
668
|
+
p->cur = b - json;
|
672
669
|
p->funcs[p->stack[p->depth]].open_object(p);
|
673
670
|
p->depth++;
|
674
671
|
p->stack[p->depth] = OBJECT_FUN;
|
675
672
|
p->map = key1_map;
|
676
673
|
break;
|
677
674
|
case NUM_CLOSE_OBJECT:
|
675
|
+
p->cur = b - json;
|
678
676
|
calc_num(p);
|
679
677
|
// flow through
|
680
678
|
case CLOSE_OBJECT:
|
@@ -685,15 +683,18 @@ static void parse(ojParser p, const byte *json) {
|
|
685
683
|
return;
|
686
684
|
}
|
687
685
|
p->depth--;
|
686
|
+
p->cur = b - json;
|
688
687
|
p->funcs[p->stack[p->depth]].close_object(p);
|
689
688
|
break;
|
690
689
|
case OPEN_ARRAY:
|
690
|
+
p->cur = b - json;
|
691
691
|
p->funcs[p->stack[p->depth]].open_array(p);
|
692
692
|
p->depth++;
|
693
693
|
p->stack[p->depth] = ARRAY_FUN;
|
694
694
|
p->map = value_map;
|
695
695
|
break;
|
696
696
|
case NUM_CLOSE_ARRAY:
|
697
|
+
p->cur = b - json;
|
697
698
|
calc_num(p);
|
698
699
|
// flow through
|
699
700
|
case CLOSE_ARRAY:
|
@@ -704,9 +705,11 @@ static void parse(ojParser p, const byte *json) {
|
|
704
705
|
return;
|
705
706
|
}
|
706
707
|
p->depth--;
|
708
|
+
p->cur = b - json;
|
707
709
|
p->funcs[p->stack[p->depth]].close_array(p);
|
708
710
|
break;
|
709
711
|
case NUM_COMMA:
|
712
|
+
p->cur = b - json;
|
710
713
|
calc_num(p);
|
711
714
|
if (0 < p->depth && OBJECT_FUN == p->stack[p->depth]) {
|
712
715
|
p->map = key_map;
|
@@ -868,8 +871,14 @@ static void parse(ojParser p, const byte *json) {
|
|
868
871
|
b--;
|
869
872
|
p->map = big_exp_map;
|
870
873
|
break;
|
871
|
-
case NUM_SPC:
|
872
|
-
|
874
|
+
case NUM_SPC:
|
875
|
+
p->cur = b - json;
|
876
|
+
calc_num(p);
|
877
|
+
break;
|
878
|
+
case NUM_NEWLINE:
|
879
|
+
p->cur = b - json;
|
880
|
+
calc_num(p);
|
881
|
+
b++;
|
873
882
|
#ifdef SPACE_JUMP
|
874
883
|
// for (uint32_t *sj = (uint32_t*)b; 0x20202020 == *sj; sj++) { b += 4; }
|
875
884
|
for (uint16_t *sj = (uint16_t *)b; 0x2020 == *sj; sj++) {
|
@@ -890,6 +899,7 @@ static void parse(ojParser p, const byte *json) {
|
|
890
899
|
buf_append_string(&p->buf, (const char *)start, b - start);
|
891
900
|
}
|
892
901
|
if ('"' == *b) {
|
902
|
+
p->cur = b - json;
|
893
903
|
p->funcs[p->stack[p->depth]].add_str(p);
|
894
904
|
p->map = p->next_map;
|
895
905
|
break;
|
@@ -898,6 +908,7 @@ static void parse(ojParser p, const byte *json) {
|
|
898
908
|
break;
|
899
909
|
case STR_SLASH: p->map = esc_map; break;
|
900
910
|
case STR_QUOTE:
|
911
|
+
p->cur = b - json;
|
901
912
|
p->funcs[p->stack[p->depth]].add_str(p);
|
902
913
|
p->map = p->next_map;
|
903
914
|
break;
|
@@ -975,6 +986,7 @@ static void parse(ojParser p, const byte *json) {
|
|
975
986
|
case VAL_NULL:
|
976
987
|
if ('u' == b[1] && 'l' == b[2] && 'l' == b[3]) {
|
977
988
|
b += 3;
|
989
|
+
p->cur = b - json;
|
978
990
|
p->funcs[p->stack[p->depth]].add_null(p);
|
979
991
|
p->map = (0 == p->depth) ? value_map : after_map;
|
980
992
|
break;
|
@@ -1000,6 +1012,7 @@ static void parse(ojParser p, const byte *json) {
|
|
1000
1012
|
case VAL_TRUE:
|
1001
1013
|
if ('r' == b[1] && 'u' == b[2] && 'e' == b[3]) {
|
1002
1014
|
b += 3;
|
1015
|
+
p->cur = b - json;
|
1003
1016
|
p->funcs[p->stack[p->depth]].add_true(p);
|
1004
1017
|
p->map = (0 == p->depth) ? value_map : after_map;
|
1005
1018
|
break;
|
@@ -1025,6 +1038,7 @@ static void parse(ojParser p, const byte *json) {
|
|
1025
1038
|
case VAL_FALSE:
|
1026
1039
|
if ('a' == b[1] && 'l' == b[2] && 's' == b[3] && 'e' == b[4]) {
|
1027
1040
|
b += 4;
|
1041
|
+
p->cur = b - json;
|
1028
1042
|
p->funcs[p->stack[p->depth]].add_false(p);
|
1029
1043
|
p->map = (0 == p->depth) ? value_map : after_map;
|
1030
1044
|
break;
|
@@ -1058,6 +1072,7 @@ static void parse(ojParser p, const byte *json) {
|
|
1058
1072
|
parse_error(p, "expected null");
|
1059
1073
|
return;
|
1060
1074
|
}
|
1075
|
+
p->cur = b - json;
|
1061
1076
|
p->funcs[p->stack[p->depth]].add_null(p);
|
1062
1077
|
p->map = (0 == p->depth) ? value_map : after_map;
|
1063
1078
|
}
|
@@ -1069,6 +1084,7 @@ static void parse(ojParser p, const byte *json) {
|
|
1069
1084
|
parse_error(p, "expected false");
|
1070
1085
|
return;
|
1071
1086
|
}
|
1087
|
+
p->cur = b - json;
|
1072
1088
|
p->funcs[p->stack[p->depth]].add_false(p);
|
1073
1089
|
p->map = (0 == p->depth) ? value_map : after_map;
|
1074
1090
|
}
|
@@ -1080,6 +1096,7 @@ static void parse(ojParser p, const byte *json) {
|
|
1080
1096
|
parse_error(p, "expected true");
|
1081
1097
|
return;
|
1082
1098
|
}
|
1099
|
+
p->cur = b - json;
|
1083
1100
|
p->funcs[p->stack[p->depth]].add_true(p);
|
1084
1101
|
p->map = (0 == p->depth) ? value_map : after_map;
|
1085
1102
|
}
|
@@ -1097,6 +1114,9 @@ static void parse(ojParser p, const byte *json) {
|
|
1097
1114
|
p->map = trail_map;
|
1098
1115
|
}
|
1099
1116
|
}
|
1117
|
+
if (0 < p->depth) {
|
1118
|
+
parse_error(p, "parse error, not closed");
|
1119
|
+
}
|
1100
1120
|
if (0 == p->depth) {
|
1101
1121
|
switch (p->map[256]) {
|
1102
1122
|
case '0':
|
@@ -1107,7 +1127,10 @@ static void parse(ojParser p, const byte *json) {
|
|
1107
1127
|
case 'D':
|
1108
1128
|
case 'g':
|
1109
1129
|
case 'B':
|
1110
|
-
case 'Y':
|
1130
|
+
case 'Y':
|
1131
|
+
p->cur = b - json;
|
1132
|
+
calc_num(p);
|
1133
|
+
break;
|
1111
1134
|
}
|
1112
1135
|
}
|
1113
1136
|
return;
|
@@ -1122,7 +1145,9 @@ static void parser_free(void *ptr) {
|
|
1122
1145
|
p = (ojParser)ptr;
|
1123
1146
|
buf_cleanup(&p->key);
|
1124
1147
|
buf_cleanup(&p->buf);
|
1125
|
-
p->free
|
1148
|
+
if (NULL != p->free) {
|
1149
|
+
p->free(p);
|
1150
|
+
}
|
1126
1151
|
xfree(ptr);
|
1127
1152
|
}
|
1128
1153
|
|
@@ -1133,7 +1158,9 @@ static void parser_mark(void *ptr) {
|
|
1133
1158
|
if (0 != p->reader) {
|
1134
1159
|
rb_gc_mark(p->reader);
|
1135
1160
|
}
|
1136
|
-
p->mark
|
1161
|
+
if (NULL != p->mark) {
|
1162
|
+
p->mark(p);
|
1163
|
+
}
|
1137
1164
|
}
|
1138
1165
|
}
|
1139
1166
|
|
@@ -1190,7 +1217,7 @@ static VALUE parser_new(int argc, VALUE *argv, VALUE self) {
|
|
1190
1217
|
p->map = value_map;
|
1191
1218
|
|
1192
1219
|
if (argc < 1) {
|
1193
|
-
|
1220
|
+
oj_set_parser_validator(p);
|
1194
1221
|
} else {
|
1195
1222
|
VALUE mode = argv[0];
|
1196
1223
|
|
@@ -1231,6 +1258,32 @@ static VALUE parser_new(int argc, VALUE *argv, VALUE self) {
|
|
1231
1258
|
return Data_Wrap_Struct(parser_class, parser_mark, parser_free, p);
|
1232
1259
|
}
|
1233
1260
|
|
1261
|
+
// Create a new parser without setting the delegate. The parser is
|
1262
|
+
// wrapped. The parser is (ojParser)DATA_PTR(value) where value is the return
|
1263
|
+
// from this function. A delegate must be added before the parser can be
|
1264
|
+
// used. Optionally oj_parser_set_options can be called if the options are not
|
1265
|
+
// set directly.
|
1266
|
+
VALUE oj_parser_new() {
|
1267
|
+
ojParser p = ALLOC(struct _ojParser);
|
1268
|
+
|
1269
|
+
#if HAVE_RB_EXT_RACTOR_SAFE
|
1270
|
+
// This doesn't seem to do anything.
|
1271
|
+
rb_ext_ractor_safe(true);
|
1272
|
+
#endif
|
1273
|
+
memset(p, 0, sizeof(struct _ojParser));
|
1274
|
+
buf_init(&p->key);
|
1275
|
+
buf_init(&p->buf);
|
1276
|
+
p->map = value_map;
|
1277
|
+
|
1278
|
+
return Data_Wrap_Struct(parser_class, parser_mark, parser_free, p);
|
1279
|
+
}
|
1280
|
+
|
1281
|
+
// Set set the options from a hash (ropts).
|
1282
|
+
void oj_parser_set_option(ojParser p, VALUE ropts) {
|
1283
|
+
Check_Type(ropts, T_HASH);
|
1284
|
+
rb_hash_foreach(ropts, opt_cb, (VALUE)p);
|
1285
|
+
}
|
1286
|
+
|
1234
1287
|
/* Document-method: method_missing(value)
|
1235
1288
|
* call-seq: method_missing(value)
|
1236
1289
|
*
|
@@ -1284,7 +1337,7 @@ static VALUE parser_new(int argc, VALUE *argv, VALUE self) {
|
|
1284
1337
|
*/
|
1285
1338
|
static VALUE parser_missing(int argc, VALUE *argv, VALUE self) {
|
1286
1339
|
ojParser p = (ojParser)DATA_PTR(self);
|
1287
|
-
const char
|
1340
|
+
const char *key = NULL;
|
1288
1341
|
volatile VALUE rkey = *argv;
|
1289
1342
|
volatile VALUE rv = Qnil;
|
1290
1343
|
|
@@ -1464,7 +1517,7 @@ static VALUE saj_parser = Qundef;
|
|
1464
1517
|
/* Document-method: saj
|
1465
1518
|
* call-seq: saj
|
1466
1519
|
*
|
1467
|
-
* Returns the default
|
1520
|
+
* Returns the default SAJ parser. Note the default SAJ parser can not be used
|
1468
1521
|
* concurrently in more than one thread.
|
1469
1522
|
*/
|
1470
1523
|
static VALUE parser_saj(VALUE self) {
|
@@ -1515,8 +1568,11 @@ static VALUE parser_validate(VALUE self) {
|
|
1515
1568
|
* isolates options to just the parser so that other parts of the code are not
|
1516
1569
|
* forced to use the same options.
|
1517
1570
|
*/
|
1518
|
-
void oj_parser_init() {
|
1571
|
+
void oj_parser_init(void) {
|
1519
1572
|
parser_class = rb_define_class_under(Oj, "Parser", rb_cObject);
|
1573
|
+
rb_gc_register_address(&parser_class);
|
1574
|
+
rb_undef_alloc_func(parser_class);
|
1575
|
+
|
1520
1576
|
rb_define_module_function(parser_class, "new", parser_new, -1);
|
1521
1577
|
rb_define_method(parser_class, "parse", parser_parse, 1);
|
1522
1578
|
rb_define_method(parser_class, "load", parser_load, 1);
|
data/ext/oj/parser.h
CHANGED
@@ -80,6 +80,7 @@ typedef struct _ojParser {
|
|
80
80
|
|
81
81
|
char token[8];
|
82
82
|
long line;
|
83
|
+
long cur; // only set before call to a function
|
83
84
|
long col;
|
84
85
|
int ri;
|
85
86
|
uint32_t ucode;
|
@@ -87,4 +88,15 @@ typedef struct _ojParser {
|
|
87
88
|
bool just_one;
|
88
89
|
} * ojParser;
|
89
90
|
|
91
|
+
// Create a new parser without setting the delegate. The parser is
|
92
|
+
// wrapped. The parser is (ojParser)DATA_PTR(value) where value is the return
|
93
|
+
// from this function. A delegate must be added before the parser can be
|
94
|
+
// used. Optionally oj_parser_set_options can be called if the options are not
|
95
|
+
// set directly.
|
96
|
+
extern VALUE oj_parser_new();
|
97
|
+
|
98
|
+
// Set set the options from a hash (ropts).
|
99
|
+
extern void oj_parser_set_option(ojParser p, VALUE ropts);
|
100
|
+
|
101
|
+
|
90
102
|
#endif /* OJ_PARSER_H */
|
data/ext/oj/rails.c
CHANGED
@@ -157,7 +157,7 @@ static void dump_struct(VALUE obj, int depth, Out out, bool as_ok) {
|
|
157
157
|
assure_size(out, 2);
|
158
158
|
*out->cur++ = '{';
|
159
159
|
for (i = 0; i < cnt; i++) {
|
160
|
-
volatile VALUE s = rb_sym2str(
|
160
|
+
volatile VALUE s = rb_sym2str(RARRAY_AREF(ma, i));
|
161
161
|
|
162
162
|
name = RSTRING_PTR(s);
|
163
163
|
len = (int)RSTRING_LEN(s);
|
@@ -167,17 +167,14 @@ static void dump_struct(VALUE obj, int depth, Out out, bool as_ok) {
|
|
167
167
|
}
|
168
168
|
fill_indent(out, d3);
|
169
169
|
*out->cur++ = '"';
|
170
|
-
|
171
|
-
out->cur += len;
|
170
|
+
APPEND_CHARS(out->cur, name, len);
|
172
171
|
*out->cur++ = '"';
|
173
172
|
if (0 < out->opts->dump_opts.before_size) {
|
174
|
-
|
175
|
-
out->cur += out->opts->dump_opts.before_size;
|
173
|
+
APPEND_CHARS(out->cur, out->opts->dump_opts.before_sep, out->opts->dump_opts.before_size);
|
176
174
|
}
|
177
175
|
*out->cur++ = ':';
|
178
176
|
if (0 < out->opts->dump_opts.after_size) {
|
179
|
-
|
180
|
-
out->cur += out->opts->dump_opts.after_size;
|
177
|
+
APPEND_CHARS(out->cur, out->opts->dump_opts.after_sep, out->opts->dump_opts.after_size);
|
181
178
|
}
|
182
179
|
#ifdef RSTRUCT_LEN
|
183
180
|
v = RSTRUCT_GET(obj, i);
|
@@ -323,20 +320,15 @@ static void dump_time(VALUE obj, int depth, Out out, bool as_ok) {
|
|
323
320
|
long long sec;
|
324
321
|
long long nsec;
|
325
322
|
|
326
|
-
#ifdef HAVE_RB_TIME_TIMESPEC
|
327
323
|
if (16 <= sizeof(struct timespec)) {
|
328
324
|
struct timespec ts = rb_time_timespec(obj);
|
329
325
|
|
330
326
|
sec = (long long)ts.tv_sec;
|
331
327
|
nsec = ts.tv_nsec;
|
332
328
|
} else {
|
333
|
-
sec =
|
334
|
-
nsec =
|
329
|
+
sec = NUM2LL(rb_funcall2(obj, oj_tv_sec_id, 0, 0));
|
330
|
+
nsec = NUM2LL(rb_funcall2(obj, oj_tv_nsec_id, 0, 0));
|
335
331
|
}
|
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
332
|
dump_sec_nano(obj, sec, nsec, out);
|
341
333
|
}
|
342
334
|
|
@@ -345,9 +337,9 @@ static void dump_timewithzone(VALUE obj, int depth, Out out, bool as_ok) {
|
|
345
337
|
long long nsec = 0;
|
346
338
|
|
347
339
|
if (rb_respond_to(obj, oj_tv_nsec_id)) {
|
348
|
-
nsec =
|
340
|
+
nsec = NUM2LL(rb_funcall2(obj, oj_tv_nsec_id, 0, 0));
|
349
341
|
} else if (rb_respond_to(obj, oj_tv_usec_id)) {
|
350
|
-
nsec =
|
342
|
+
nsec = NUM2LL(rb_funcall2(obj, oj_tv_usec_id, 0, 0)) * 1000;
|
351
343
|
}
|
352
344
|
dump_sec_nano(obj, sec, nsec, out);
|
353
345
|
}
|
@@ -383,7 +375,7 @@ static StrLen columns_array(VALUE rcols, int *ccnt) {
|
|
383
375
|
*ccnt = cnt;
|
384
376
|
cols = ALLOC_N(struct _strLen, cnt);
|
385
377
|
for (i = 0, cp = cols; i < cnt; i++, cp++) {
|
386
|
-
v =
|
378
|
+
v = RARRAY_AREF(rcols, i);
|
387
379
|
if (T_STRING != rb_type(v)) {
|
388
380
|
v = rb_funcall(v, oj_to_s_id, 0);
|
389
381
|
}
|
@@ -405,14 +397,12 @@ static void dump_row(VALUE row, StrLen cols, int ccnt, int depth, Out out) {
|
|
405
397
|
assure_size(out, size);
|
406
398
|
if (out->opts->dump_opts.use) {
|
407
399
|
if (0 < out->opts->dump_opts.array_size) {
|
408
|
-
|
409
|
-
out->cur += out->opts->dump_opts.array_size;
|
400
|
+
APPEND_CHARS(out->cur, out->opts->dump_opts.array_nl, out->opts->dump_opts.array_size);
|
410
401
|
}
|
411
402
|
if (0 < out->opts->dump_opts.indent_size) {
|
412
403
|
int i;
|
413
404
|
for (i = d2; 0 < i; i--) {
|
414
|
-
|
415
|
-
out->cur += out->opts->dump_opts.indent_size;
|
405
|
+
APPEND_CHARS(out->cur, out->opts->dump_opts.indent_str, out->opts->dump_opts.indent_size);
|
416
406
|
}
|
417
407
|
}
|
418
408
|
} else {
|
@@ -420,7 +410,7 @@ static void dump_row(VALUE row, StrLen cols, int ccnt, int depth, Out out) {
|
|
420
410
|
}
|
421
411
|
oj_dump_cstr(cols->str, cols->len, 0, 0, out);
|
422
412
|
*out->cur++ = ':';
|
423
|
-
dump_rails_val(
|
413
|
+
dump_rails_val(RARRAY_AREF(row, i), depth, out, true);
|
424
414
|
if (i < ccnt - 1) {
|
425
415
|
*out->cur++ = ',';
|
426
416
|
}
|
@@ -429,15 +419,13 @@ static void dump_row(VALUE row, StrLen cols, int ccnt, int depth, Out out) {
|
|
429
419
|
assure_size(out, size);
|
430
420
|
if (out->opts->dump_opts.use) {
|
431
421
|
if (0 < out->opts->dump_opts.array_size) {
|
432
|
-
|
433
|
-
out->cur += out->opts->dump_opts.array_size;
|
422
|
+
APPEND_CHARS(out->cur, out->opts->dump_opts.array_nl, out->opts->dump_opts.array_size);
|
434
423
|
}
|
435
424
|
if (0 < out->opts->dump_opts.indent_size) {
|
436
425
|
int i;
|
437
426
|
|
438
427
|
for (i = depth; 0 < i; i--) {
|
439
|
-
|
440
|
-
out->cur += out->opts->dump_opts.indent_size;
|
428
|
+
APPEND_CHARS(out->cur, out->opts->dump_opts.indent_str, out->opts->dump_opts.indent_size);
|
441
429
|
}
|
442
430
|
}
|
443
431
|
} else {
|
@@ -477,20 +465,18 @@ static void dump_activerecord_result(VALUE obj, int depth, Out out, bool as_ok)
|
|
477
465
|
assure_size(out, size);
|
478
466
|
if (out->opts->dump_opts.use) {
|
479
467
|
if (0 < out->opts->dump_opts.array_size) {
|
480
|
-
|
481
|
-
out->cur += out->opts->dump_opts.array_size;
|
468
|
+
APPEND_CHARS(out->cur, out->opts->dump_opts.array_nl, out->opts->dump_opts.array_size);
|
482
469
|
}
|
483
470
|
if (0 < out->opts->dump_opts.indent_size) {
|
484
471
|
int i;
|
485
472
|
for (i = d2; 0 < i; i--) {
|
486
|
-
|
487
|
-
out->cur += out->opts->dump_opts.indent_size;
|
473
|
+
APPEND_CHARS(out->cur, out->opts->dump_opts.indent_str, out->opts->dump_opts.indent_size);
|
488
474
|
}
|
489
475
|
}
|
490
476
|
} else {
|
491
477
|
fill_indent(out, d2);
|
492
478
|
}
|
493
|
-
dump_row(
|
479
|
+
dump_row(RARRAY_AREF(rows, i), cols, ccnt, d2, out);
|
494
480
|
if (i < rcnt - 1) {
|
495
481
|
*out->cur++ = ',';
|
496
482
|
}
|
@@ -500,15 +486,13 @@ static void dump_activerecord_result(VALUE obj, int depth, Out out, bool as_ok)
|
|
500
486
|
assure_size(out, size);
|
501
487
|
if (out->opts->dump_opts.use) {
|
502
488
|
if (0 < out->opts->dump_opts.array_size) {
|
503
|
-
|
504
|
-
out->cur += out->opts->dump_opts.array_size;
|
489
|
+
APPEND_CHARS(out->cur, out->opts->dump_opts.array_nl, out->opts->dump_opts.array_size);
|
505
490
|
}
|
506
491
|
if (0 < out->opts->dump_opts.indent_size) {
|
507
492
|
int i;
|
508
493
|
|
509
494
|
for (i = depth; 0 < i; i--) {
|
510
|
-
|
511
|
-
out->cur += out->opts->dump_opts.indent_size;
|
495
|
+
APPEND_CHARS(out->cur, out->opts->dump_opts.indent_str, out->opts->dump_opts.indent_size);
|
512
496
|
}
|
513
497
|
}
|
514
498
|
} else {
|
@@ -533,7 +517,7 @@ static void dump_as_string(VALUE obj, int depth, Out out, bool as_ok) {
|
|
533
517
|
static void dump_as_json(VALUE obj, int depth, Out out, bool as_ok) {
|
534
518
|
volatile VALUE ja;
|
535
519
|
|
536
|
-
if (Yes == out->opts->trace) {
|
520
|
+
if (RB_UNLIKELY(Yes == out->opts->trace)) {
|
537
521
|
oj_trace("as_json", obj, __FILE__, __LINE__, depth + 1, TraceRubyIn);
|
538
522
|
}
|
539
523
|
// Some classes elect to not take an options argument so check the arity
|
@@ -543,7 +527,7 @@ static void dump_as_json(VALUE obj, int depth, Out out, bool as_ok) {
|
|
543
527
|
} else {
|
544
528
|
ja = rb_funcall2(obj, oj_as_json_id, out->argc, out->argv);
|
545
529
|
}
|
546
|
-
if (Yes == out->opts->trace) {
|
530
|
+
if (RB_UNLIKELY(Yes == out->opts->trace)) {
|
547
531
|
oj_trace("as_json", obj, __FILE__, __LINE__, depth + 1, TraceRubyOut);
|
548
532
|
}
|
549
533
|
|
@@ -908,7 +892,6 @@ static VALUE protect_dump(VALUE ov) {
|
|
908
892
|
}
|
909
893
|
|
910
894
|
static VALUE encode(VALUE obj, ROptTable ropts, Options opts, int argc, VALUE *argv) {
|
911
|
-
char buf[4096];
|
912
895
|
struct _out out;
|
913
896
|
struct _options copts = *opts;
|
914
897
|
volatile VALUE rstr = Qnil;
|
@@ -925,9 +908,9 @@ static VALUE encode(VALUE obj, ROptTable ropts, Options opts, int argc, VALUE *a
|
|
925
908
|
} else {
|
926
909
|
copts.escape_mode = RailsEsc;
|
927
910
|
}
|
928
|
-
|
929
|
-
out
|
930
|
-
|
911
|
+
|
912
|
+
oj_out_init(&out);
|
913
|
+
|
931
914
|
out.omit_nil = copts.dump_opts.omit_nil;
|
932
915
|
out.caller = 0;
|
933
916
|
out.cur = out.buf;
|
@@ -963,9 +946,9 @@ static VALUE encode(VALUE obj, ROptTable ropts, Options opts, int argc, VALUE *a
|
|
963
946
|
if (Yes == copts.circular) {
|
964
947
|
oj_cache8_delete(out.circ_cache);
|
965
948
|
}
|
966
|
-
|
967
|
-
|
968
|
-
|
949
|
+
|
950
|
+
oj_out_free(&out);
|
951
|
+
|
969
952
|
if (0 != line) {
|
970
953
|
rb_jump_tag(line);
|
971
954
|
}
|
@@ -1175,12 +1158,15 @@ oj_optimize_rails(VALUE self) {
|
|
1175
1158
|
*
|
1176
1159
|
* The Oj ActiveSupport compliant encoder.
|
1177
1160
|
*/
|
1178
|
-
void oj_mimic_rails_init() {
|
1161
|
+
void oj_mimic_rails_init(void) {
|
1179
1162
|
VALUE rails = rb_define_module_under(Oj, "Rails");
|
1180
1163
|
|
1181
1164
|
rb_define_module_function(rails, "encode", rails_encode, -1);
|
1182
1165
|
|
1183
1166
|
encoder_class = rb_define_class_under(rails, "Encoder", rb_cObject);
|
1167
|
+
rb_gc_register_address(&encoder_class);
|
1168
|
+
rb_undef_alloc_func(encoder_class);
|
1169
|
+
|
1184
1170
|
rb_define_module_function(encoder_class, "new", encoder_new, -1);
|
1185
1171
|
rb_define_module_function(rails, "optimize", rails_optimize, -1);
|
1186
1172
|
rb_define_module_function(rails, "deoptimize", rails_deoptimize, -1);
|
@@ -1263,25 +1249,23 @@ static void dump_array(VALUE a, int depth, Out out, bool as_ok) {
|
|
1263
1249
|
} else {
|
1264
1250
|
size = d2 * out->indent + 2;
|
1265
1251
|
}
|
1252
|
+
assure_size(out, size * cnt);
|
1266
1253
|
cnt--;
|
1267
1254
|
for (i = 0; i <= cnt; i++) {
|
1268
|
-
assure_size(out, size);
|
1269
1255
|
if (out->opts->dump_opts.use) {
|
1270
1256
|
if (0 < out->opts->dump_opts.array_size) {
|
1271
|
-
|
1272
|
-
out->cur += out->opts->dump_opts.array_size;
|
1257
|
+
APPEND_CHARS(out->cur, out->opts->dump_opts.array_nl, out->opts->dump_opts.array_size);
|
1273
1258
|
}
|
1274
1259
|
if (0 < out->opts->dump_opts.indent_size) {
|
1275
1260
|
int i;
|
1276
1261
|
for (i = d2; 0 < i; i--) {
|
1277
|
-
|
1278
|
-
out->cur += out->opts->dump_opts.indent_size;
|
1262
|
+
APPEND_CHARS(out->cur, out->opts->dump_opts.indent_str, out->opts->dump_opts.indent_size);
|
1279
1263
|
}
|
1280
1264
|
}
|
1281
1265
|
} else {
|
1282
1266
|
fill_indent(out, d2);
|
1283
1267
|
}
|
1284
|
-
dump_rails_val(
|
1268
|
+
dump_rails_val(RARRAY_AREF(a, i), d2, out, true);
|
1285
1269
|
if (i < cnt) {
|
1286
1270
|
*out->cur++ = ',';
|
1287
1271
|
}
|
@@ -1290,15 +1274,13 @@ static void dump_array(VALUE a, int depth, Out out, bool as_ok) {
|
|
1290
1274
|
assure_size(out, size);
|
1291
1275
|
if (out->opts->dump_opts.use) {
|
1292
1276
|
if (0 < out->opts->dump_opts.array_size) {
|
1293
|
-
|
1294
|
-
out->cur += out->opts->dump_opts.array_size;
|
1277
|
+
APPEND_CHARS(out->cur, out->opts->dump_opts.array_nl, out->opts->dump_opts.array_size);
|
1295
1278
|
}
|
1296
1279
|
if (0 < out->opts->dump_opts.indent_size) {
|
1297
1280
|
int i;
|
1298
1281
|
|
1299
1282
|
for (i = depth; 0 < i; i--) {
|
1300
|
-
|
1301
|
-
out->cur += out->opts->dump_opts.indent_size;
|
1283
|
+
APPEND_CHARS(out->cur, out->opts->dump_opts.indent_str, out->opts->dump_opts.indent_size);
|
1302
1284
|
}
|
1303
1285
|
}
|
1304
1286
|
} else {
|
@@ -1336,14 +1318,12 @@ static int hash_cb(VALUE key, VALUE value, VALUE ov) {
|
|
1336
1318
|
size = depth * out->opts->dump_opts.indent_size + out->opts->dump_opts.hash_size + 1;
|
1337
1319
|
assure_size(out, size);
|
1338
1320
|
if (0 < out->opts->dump_opts.hash_size) {
|
1339
|
-
|
1340
|
-
out->cur += out->opts->dump_opts.hash_size;
|
1321
|
+
APPEND_CHARS(out->cur, out->opts->dump_opts.hash_nl, out->opts->dump_opts.hash_size);
|
1341
1322
|
}
|
1342
1323
|
if (0 < out->opts->dump_opts.indent_size) {
|
1343
1324
|
int i;
|
1344
1325
|
for (i = depth; 0 < i; i--) {
|
1345
|
-
|
1346
|
-
out->cur += out->opts->dump_opts.indent_size;
|
1326
|
+
APPEND_CHARS(out->cur, out->opts->dump_opts.indent_str, out->opts->dump_opts.indent_size);
|
1347
1327
|
}
|
1348
1328
|
}
|
1349
1329
|
if (rtype == T_STRING) {
|
@@ -1354,13 +1334,11 @@ static int hash_cb(VALUE key, VALUE value, VALUE ov) {
|
|
1354
1334
|
size = out->opts->dump_opts.before_size + out->opts->dump_opts.after_size + 2;
|
1355
1335
|
assure_size(out, size);
|
1356
1336
|
if (0 < out->opts->dump_opts.before_size) {
|
1357
|
-
|
1358
|
-
out->cur += out->opts->dump_opts.before_size;
|
1337
|
+
APPEND_CHARS(out->cur, out->opts->dump_opts.before_sep, out->opts->dump_opts.before_size);
|
1359
1338
|
}
|
1360
1339
|
*out->cur++ = ':';
|
1361
1340
|
if (0 < out->opts->dump_opts.after_size) {
|
1362
|
-
|
1363
|
-
out->cur += out->opts->dump_opts.after_size;
|
1341
|
+
APPEND_CHARS(out->cur, out->opts->dump_opts.after_sep, out->opts->dump_opts.after_size);
|
1364
1342
|
}
|
1365
1343
|
}
|
1366
1344
|
dump_rails_val(value, depth, out, true);
|
@@ -1403,15 +1381,13 @@ static void dump_hash(VALUE obj, int depth, Out out, bool as_ok) {
|
|
1403
1381
|
size = depth * out->opts->dump_opts.indent_size + out->opts->dump_opts.hash_size + 1;
|
1404
1382
|
assure_size(out, size);
|
1405
1383
|
if (0 < out->opts->dump_opts.hash_size) {
|
1406
|
-
|
1407
|
-
out->cur += out->opts->dump_opts.hash_size;
|
1384
|
+
APPEND_CHARS(out->cur, out->opts->dump_opts.hash_nl, out->opts->dump_opts.hash_size);
|
1408
1385
|
}
|
1409
1386
|
if (0 < out->opts->dump_opts.indent_size) {
|
1410
1387
|
int i;
|
1411
1388
|
|
1412
1389
|
for (i = depth; 0 < i; i--) {
|
1413
|
-
|
1414
|
-
out->cur += out->opts->dump_opts.indent_size;
|
1390
|
+
APPEND_CHARS(out->cur, out->opts->dump_opts.indent_str, out->opts->dump_opts.indent_size);
|
1415
1391
|
}
|
1416
1392
|
}
|
1417
1393
|
}
|
@@ -1488,7 +1464,7 @@ static DumpFunc rails_funcs[] = {
|
|
1488
1464
|
static void dump_rails_val(VALUE obj, int depth, Out out, bool as_ok) {
|
1489
1465
|
int type = rb_type(obj);
|
1490
1466
|
|
1491
|
-
if (Yes == out->opts->trace) {
|
1467
|
+
if (RB_UNLIKELY(Yes == out->opts->trace)) {
|
1492
1468
|
oj_trace("dump", obj, __FILE__, __LINE__, depth, TraceIn);
|
1493
1469
|
}
|
1494
1470
|
if (MAX_DEPTH < depth) {
|
@@ -1499,14 +1475,14 @@ static void dump_rails_val(VALUE obj, int depth, Out out, bool as_ok) {
|
|
1499
1475
|
|
1500
1476
|
if (NULL != f) {
|
1501
1477
|
f(obj, depth, out, as_ok);
|
1502
|
-
if (Yes == out->opts->trace) {
|
1478
|
+
if (RB_UNLIKELY(Yes == out->opts->trace)) {
|
1503
1479
|
oj_trace("dump", obj, __FILE__, __LINE__, depth, TraceOut);
|
1504
1480
|
}
|
1505
1481
|
return;
|
1506
1482
|
}
|
1507
1483
|
}
|
1508
1484
|
oj_dump_nil(Qnil, depth, out, false);
|
1509
|
-
if (Yes == out->opts->trace) {
|
1485
|
+
if (RB_UNLIKELY(Yes == out->opts->trace)) {
|
1510
1486
|
oj_trace("dump", Qnil, __FILE__, __LINE__, depth, TraceOut);
|
1511
1487
|
}
|
1512
1488
|
}
|