oj 3.13.23 → 3.16.9
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 +81 -0
- data/README.md +2 -2
- data/ext/oj/buf.h +7 -6
- data/ext/oj/cache.c +29 -26
- data/ext/oj/cache.h +3 -2
- data/ext/oj/cache8.c +10 -9
- data/ext/oj/circarray.c +7 -5
- data/ext/oj/circarray.h +2 -2
- data/ext/oj/code.c +5 -12
- data/ext/oj/code.h +2 -2
- data/ext/oj/compat.c +20 -60
- data/ext/oj/custom.c +26 -59
- data/ext/oj/debug.c +3 -9
- data/ext/oj/dump.c +103 -53
- data/ext/oj/dump.h +1 -4
- data/ext/oj/dump_compat.c +557 -592
- data/ext/oj/dump_leaf.c +3 -5
- data/ext/oj/dump_object.c +42 -48
- data/ext/oj/dump_strict.c +10 -22
- data/ext/oj/encoder.c +1 -1
- data/ext/oj/err.c +2 -13
- data/ext/oj/err.h +9 -12
- data/ext/oj/extconf.rb +16 -7
- data/ext/oj/fast.c +60 -92
- data/ext/oj/intern.c +62 -47
- data/ext/oj/intern.h +3 -7
- data/ext/oj/mem.c +318 -0
- data/ext/oj/mem.h +53 -0
- data/ext/oj/mimic_json.c +51 -32
- data/ext/oj/object.c +33 -43
- data/ext/oj/odd.c +8 -6
- data/ext/oj/odd.h +4 -4
- data/ext/oj/oj.c +243 -212
- data/ext/oj/oj.h +83 -81
- data/ext/oj/parse.c +94 -148
- data/ext/oj/parse.h +21 -24
- data/ext/oj/parser.c +80 -67
- data/ext/oj/parser.h +7 -8
- data/ext/oj/rails.c +70 -92
- data/ext/oj/reader.c +9 -14
- data/ext/oj/reader.h +4 -2
- data/ext/oj/resolve.c +3 -4
- data/ext/oj/rxclass.c +6 -5
- data/ext/oj/rxclass.h +1 -1
- data/ext/oj/saj.c +10 -9
- data/ext/oj/saj2.c +37 -49
- data/ext/oj/saj2.h +1 -1
- data/ext/oj/scp.c +3 -14
- data/ext/oj/sparse.c +22 -70
- data/ext/oj/stream_writer.c +45 -41
- data/ext/oj/strict.c +20 -52
- data/ext/oj/string_writer.c +64 -38
- data/ext/oj/trace.h +31 -4
- data/ext/oj/usual.c +125 -114
- data/ext/oj/usual.h +7 -6
- data/ext/oj/util.h +1 -1
- data/ext/oj/val_stack.c +13 -2
- data/ext/oj/val_stack.h +8 -7
- data/ext/oj/wab.c +25 -57
- data/lib/oj/active_support_helper.rb +1 -3
- data/lib/oj/bag.rb +7 -1
- data/lib/oj/easy_hash.rb +4 -5
- data/lib/oj/error.rb +0 -1
- data/lib/oj/json.rb +162 -150
- data/lib/oj/mimic.rb +7 -7
- data/lib/oj/schandler.rb +5 -4
- data/lib/oj/state.rb +8 -5
- data/lib/oj/version.rb +1 -2
- data/lib/oj.rb +2 -0
- data/pages/InstallOptions.md +20 -0
- data/pages/Options.md +4 -0
- data/test/_test_active.rb +8 -9
- data/test/_test_active_mimic.rb +7 -8
- data/test/_test_mimic_rails.rb +17 -20
- data/test/activerecord/result_test.rb +5 -6
- data/test/activesupport6/encoding_test.rb +63 -28
- data/test/activesupport7/abstract_unit.rb +4 -1
- data/test/activesupport7/encoding_test.rb +72 -22
- data/test/files.rb +15 -15
- data/test/foo.rb +18 -69
- data/test/helper.rb +5 -8
- data/test/isolated/shared.rb +3 -2
- data/test/json_gem/json_addition_test.rb +2 -2
- data/test/json_gem/json_common_interface_test.rb +8 -6
- data/test/json_gem/json_encoding_test.rb +0 -0
- data/test/json_gem/json_ext_parser_test.rb +1 -0
- data/test/json_gem/json_fixtures_test.rb +3 -2
- data/test/json_gem/json_generator_test.rb +50 -33
- data/test/json_gem/json_generic_object_test.rb +11 -11
- data/test/json_gem/json_parser_test.rb +46 -46
- data/test/json_gem/json_string_matching_test.rb +9 -9
- data/test/mem.rb +13 -12
- data/test/perf.rb +21 -26
- data/test/perf_compat.rb +31 -33
- data/test/perf_dump.rb +28 -28
- data/test/perf_fast.rb +80 -82
- data/test/perf_file.rb +27 -29
- data/test/perf_object.rb +65 -69
- data/test/perf_once.rb +12 -11
- data/test/perf_parser.rb +42 -48
- data/test/perf_saj.rb +46 -54
- data/test/perf_scp.rb +57 -69
- data/test/perf_simple.rb +41 -39
- data/test/perf_strict.rb +68 -70
- data/test/perf_wab.rb +67 -69
- data/test/prec.rb +5 -5
- data/test/sample/change.rb +0 -1
- data/test/sample/dir.rb +0 -1
- data/test/sample/doc.rb +0 -1
- data/test/sample/file.rb +0 -1
- data/test/sample/group.rb +0 -1
- data/test/sample/hasprops.rb +0 -1
- data/test/sample/layer.rb +0 -1
- data/test/sample/rect.rb +0 -1
- data/test/sample/shape.rb +0 -1
- data/test/sample/text.rb +0 -1
- data/test/sample.rb +16 -16
- data/test/sample_json.rb +8 -8
- data/test/test_compat.rb +81 -54
- data/test/test_custom.rb +63 -52
- data/test/test_debian.rb +7 -10
- data/test/test_fast.rb +86 -90
- data/test/test_file.rb +24 -29
- data/test/test_gc.rb +5 -5
- data/test/test_generate.rb +5 -5
- data/test/test_hash.rb +4 -4
- data/test/test_integer_range.rb +9 -9
- data/test/test_null.rb +20 -20
- data/test/test_object.rb +92 -87
- data/test/test_parser.rb +4 -4
- data/test/test_parser_debug.rb +5 -5
- data/test/test_parser_saj.rb +27 -25
- data/test/test_parser_usual.rb +44 -6
- data/test/test_rails.rb +2 -2
- data/test/test_saj.rb +10 -8
- data/test/test_scp.rb +35 -35
- data/test/test_strict.rb +38 -32
- data/test/test_various.rb +146 -97
- data/test/test_wab.rb +46 -44
- data/test/test_writer.rb +63 -47
- data/test/tests.rb +7 -7
- data/test/tests_mimic.rb +6 -6
- data/test/tests_mimic_addition.rb +6 -6
- metadata +46 -26
- data/test/activesupport4/decoding_test.rb +0 -108
- data/test/activesupport4/encoding_test.rb +0 -531
- data/test/activesupport4/test_helper.rb +0 -41
- data/test/activesupport5/abstract_unit.rb +0 -45
- data/test/activesupport5/decoding_test.rb +0 -133
- data/test/activesupport5/encoding_test.rb +0 -500
- data/test/activesupport5/encoding_test_cases.rb +0 -98
- data/test/activesupport5/test_helper.rb +0 -72
- data/test/activesupport5/time_zone_test_helpers.rb +0 -39
- data/test/bar.rb +0 -11
- data/test/baz.rb +0 -16
- data/test/bug.rb +0 -16
- data/test/zoo.rb +0 -13
data/ext/oj/rails.c
CHANGED
@@ -5,6 +5,7 @@
|
|
5
5
|
|
6
6
|
#include "code.h"
|
7
7
|
#include "encode.h"
|
8
|
+
#include "mem.h"
|
8
9
|
#include "trace.h"
|
9
10
|
#include "util.h"
|
10
11
|
|
@@ -15,7 +16,7 @@ typedef struct _encoder {
|
|
15
16
|
struct _rOptTable ropts;
|
16
17
|
struct _options opts;
|
17
18
|
VALUE arg;
|
18
|
-
} *
|
19
|
+
} *Encoder;
|
19
20
|
|
20
21
|
bool oj_rails_hash_opt = false;
|
21
22
|
bool oj_rails_array_opt = false;
|
@@ -76,7 +77,7 @@ static ROptTable copy_opts(ROptTable src, ROptTable dest) {
|
|
76
77
|
if (NULL == src->table) {
|
77
78
|
dest->table = NULL;
|
78
79
|
} else {
|
79
|
-
dest->table =
|
80
|
+
dest->table = OJ_R_ALLOC_N(struct _rOpt, dest->alen);
|
80
81
|
memcpy(dest->table, src->table, sizeof(struct _rOpt) * dest->alen);
|
81
82
|
}
|
82
83
|
return NULL;
|
@@ -140,7 +141,7 @@ static void dump_struct(VALUE obj, int depth, Out out, bool as_ok) {
|
|
140
141
|
int cnt;
|
141
142
|
int i;
|
142
143
|
int len;
|
143
|
-
const char
|
144
|
+
const char *name;
|
144
145
|
|
145
146
|
#ifdef RSTRUCT_LEN
|
146
147
|
#if RSTRUCT_LEN_RETURNS_INTEGER_OBJECT
|
@@ -198,8 +199,8 @@ static void dump_enumerable(VALUE obj, int depth, Out out, bool as_ok) {
|
|
198
199
|
}
|
199
200
|
|
200
201
|
static void dump_bigdecimal(VALUE obj, int depth, Out out, bool as_ok) {
|
201
|
-
volatile VALUE rstr =
|
202
|
-
const char
|
202
|
+
volatile VALUE rstr = oj_safe_string_convert(obj);
|
203
|
+
const char *str = RSTRING_PTR(rstr);
|
203
204
|
|
204
205
|
if ('I' == *str || 'N' == *str || ('-' == *str && 'I' == str[1])) {
|
205
206
|
oj_dump_nil(Qnil, depth, out, false);
|
@@ -262,14 +263,7 @@ static void dump_sec_nano(VALUE obj, int64_t sec, long nsec, Out out) {
|
|
262
263
|
tzmin);
|
263
264
|
} else if (0 == out->opts->sec_prec) {
|
264
265
|
if (0 == tzsecs && rb_funcall2(obj, oj_utcq_id, 0, 0)) {
|
265
|
-
len = sprintf(buf,
|
266
|
-
"%04d-%02d-%02dT%02d:%02d:%02dZ",
|
267
|
-
ti.year,
|
268
|
-
ti.mon,
|
269
|
-
ti.day,
|
270
|
-
ti.hour,
|
271
|
-
ti.min,
|
272
|
-
ti.sec);
|
266
|
+
len = sprintf(buf, "%04d-%02d-%02dT%02d:%02d:%02dZ", ti.year, ti.mon, ti.day, ti.hour, ti.min, ti.sec);
|
273
267
|
} else {
|
274
268
|
len = sprintf(buf,
|
275
269
|
"%04d-%02d-%02dT%02d:%02d:%02d%c%02d:%02d",
|
@@ -300,18 +294,7 @@ static void dump_sec_nano(VALUE obj, int64_t sec, long nsec, Out out) {
|
|
300
294
|
format[32] = '0' + out->opts->sec_prec;
|
301
295
|
len -= 9 - out->opts->sec_prec;
|
302
296
|
}
|
303
|
-
len = sprintf(buf,
|
304
|
-
format,
|
305
|
-
ti.year,
|
306
|
-
ti.mon,
|
307
|
-
ti.day,
|
308
|
-
ti.hour,
|
309
|
-
ti.min,
|
310
|
-
ti.sec,
|
311
|
-
nsec,
|
312
|
-
tzsign,
|
313
|
-
tzhour,
|
314
|
-
tzmin);
|
297
|
+
len = sprintf(buf, format, ti.year, ti.mon, ti.day, ti.hour, ti.min, ti.sec, nsec, tzsign, tzhour, tzmin);
|
315
298
|
}
|
316
299
|
oj_dump_cstr(buf, len, 0, 0, out);
|
317
300
|
}
|
@@ -345,7 +328,7 @@ static void dump_timewithzone(VALUE obj, int depth, Out out, bool as_ok) {
|
|
345
328
|
}
|
346
329
|
|
347
330
|
static void dump_to_s(VALUE obj, int depth, Out out, bool as_ok) {
|
348
|
-
volatile VALUE rstr =
|
331
|
+
volatile VALUE rstr = oj_safe_string_convert(obj);
|
349
332
|
|
350
333
|
oj_dump_cstr(RSTRING_PTR(rstr), (int)RSTRING_LEN(rstr), 0, 0, out);
|
351
334
|
}
|
@@ -355,7 +338,7 @@ static ID parameters_id = 0;
|
|
355
338
|
typedef struct _strLen {
|
356
339
|
const char *str;
|
357
340
|
int len;
|
358
|
-
} *
|
341
|
+
} *StrLen;
|
359
342
|
|
360
343
|
static void dump_actioncontroller_parameters(VALUE obj, int depth, Out out, bool as_ok) {
|
361
344
|
if (0 == parameters_id) {
|
@@ -373,11 +356,11 @@ static StrLen columns_array(VALUE rcols, int *ccnt) {
|
|
373
356
|
int cnt = (int)RARRAY_LEN(rcols);
|
374
357
|
|
375
358
|
*ccnt = cnt;
|
376
|
-
cols =
|
359
|
+
cols = OJ_R_ALLOC_N(struct _strLen, cnt);
|
377
360
|
for (i = 0, cp = cols; i < cnt; i++, cp++) {
|
378
361
|
v = RARRAY_AREF(rcols, i);
|
379
362
|
if (T_STRING != rb_type(v)) {
|
380
|
-
v =
|
363
|
+
v = oj_safe_string_convert(v);
|
381
364
|
}
|
382
365
|
cp->str = StringValuePtr(v);
|
383
366
|
cp->len = (int)RSTRING_LEN(v);
|
@@ -481,7 +464,7 @@ static void dump_activerecord_result(VALUE obj, int depth, Out out, bool as_ok)
|
|
481
464
|
*out->cur++ = ',';
|
482
465
|
}
|
483
466
|
}
|
484
|
-
|
467
|
+
OJ_R_FREE(cols);
|
485
468
|
size = depth * out->indent + 1;
|
486
469
|
assure_size(out, size);
|
487
470
|
if (out->opts->dump_opts.use) {
|
@@ -504,7 +487,7 @@ static void dump_activerecord_result(VALUE obj, int depth, Out out, bool as_ok)
|
|
504
487
|
typedef struct _namedFunc {
|
505
488
|
const char *name;
|
506
489
|
DumpFunc func;
|
507
|
-
} *
|
490
|
+
} *NamedFunc;
|
508
491
|
|
509
492
|
static void dump_as_string(VALUE obj, int depth, Out out, bool as_ok) {
|
510
493
|
if (oj_code_dump(oj_compat_codes, obj, depth, out)) {
|
@@ -517,9 +500,7 @@ static void dump_as_string(VALUE obj, int depth, Out out, bool as_ok) {
|
|
517
500
|
static void dump_as_json(VALUE obj, int depth, Out out, bool as_ok) {
|
518
501
|
volatile VALUE ja;
|
519
502
|
|
520
|
-
|
521
|
-
oj_trace("as_json", obj, __FILE__, __LINE__, depth + 1, TraceRubyIn);
|
522
|
-
}
|
503
|
+
TRACE(out->opts->trace, "as_json", obj, depth + 1, TraceRubyIn);
|
523
504
|
// Some classes elect to not take an options argument so check the arity
|
524
505
|
// of as_json.
|
525
506
|
if (0 == rb_obj_method_arity(obj, oj_as_json_id)) {
|
@@ -527,9 +508,7 @@ static void dump_as_json(VALUE obj, int depth, Out out, bool as_ok) {
|
|
527
508
|
} else {
|
528
509
|
ja = rb_funcall2(obj, oj_as_json_id, out->argc, out->argv);
|
529
510
|
}
|
530
|
-
|
531
|
-
oj_trace("as_json", obj, __FILE__, __LINE__, depth + 1, TraceRubyOut);
|
532
|
-
}
|
511
|
+
TRACE(out->opts->trace, "as_json", obj, depth + 1, TraceRubyOut);
|
533
512
|
|
534
513
|
out->argc = 0;
|
535
514
|
if (ja == obj || !as_ok) {
|
@@ -587,11 +566,11 @@ static ROpt create_opt(ROptTable rot, VALUE clas) {
|
|
587
566
|
rot->len++;
|
588
567
|
if (NULL == rot->table) {
|
589
568
|
rot->alen = 256;
|
590
|
-
rot->table =
|
569
|
+
rot->table = OJ_R_ALLOC_N(struct _rOpt, rot->alen);
|
591
570
|
memset(rot->table, 0, sizeof(struct _rOpt) * rot->alen);
|
592
571
|
} else if (rot->alen <= rot->len) {
|
593
572
|
rot->alen *= 2;
|
594
|
-
|
573
|
+
OJ_R_REALLOC_N(rot->table, struct _rOpt, rot->alen);
|
595
574
|
memset(rot->table + olen, 0, sizeof(struct _rOpt) * olen);
|
596
575
|
}
|
597
576
|
if (0 == olen) {
|
@@ -644,9 +623,9 @@ static void encoder_free(void *ptr) {
|
|
644
623
|
Encoder e = (Encoder)ptr;
|
645
624
|
|
646
625
|
if (NULL != e->ropts.table) {
|
647
|
-
|
626
|
+
OJ_R_FREE(e->ropts.table);
|
648
627
|
}
|
649
|
-
|
628
|
+
OJ_R_FREE(ptr);
|
650
629
|
}
|
651
630
|
}
|
652
631
|
|
@@ -660,6 +639,17 @@ static void encoder_mark(void *ptr) {
|
|
660
639
|
}
|
661
640
|
}
|
662
641
|
|
642
|
+
static const rb_data_type_t oj_encoder_type = {
|
643
|
+
"Oj/encoder",
|
644
|
+
{
|
645
|
+
encoder_mark,
|
646
|
+
encoder_free,
|
647
|
+
NULL,
|
648
|
+
},
|
649
|
+
0,
|
650
|
+
0,
|
651
|
+
};
|
652
|
+
|
663
653
|
/* Document-method: new
|
664
654
|
* call-seq: new(options=nil)
|
665
655
|
*
|
@@ -667,7 +657,7 @@ static void encoder_mark(void *ptr) {
|
|
667
657
|
* - *options* [_Hash_] formatting options
|
668
658
|
*/
|
669
659
|
static VALUE encoder_new(int argc, VALUE *argv, VALUE self) {
|
670
|
-
Encoder e =
|
660
|
+
Encoder e = OJ_R_ALLOC(struct _encoder);
|
671
661
|
|
672
662
|
e->opts = oj_default_options;
|
673
663
|
e->arg = Qnil;
|
@@ -677,14 +667,14 @@ static VALUE encoder_new(int argc, VALUE *argv, VALUE self) {
|
|
677
667
|
oj_parse_options(*argv, &e->opts);
|
678
668
|
e->arg = *argv;
|
679
669
|
}
|
680
|
-
return
|
670
|
+
return TypedData_Wrap_Struct(encoder_class, &oj_encoder_type, e);
|
681
671
|
}
|
682
672
|
|
683
673
|
static VALUE resolve_classpath(const char *name) {
|
684
674
|
char class_name[1024];
|
685
675
|
VALUE clas;
|
686
|
-
char
|
687
|
-
char
|
676
|
+
char *end = class_name + sizeof(class_name) - 1;
|
677
|
+
char *s;
|
688
678
|
const char *n = name;
|
689
679
|
ID cid;
|
690
680
|
|
@@ -750,8 +740,7 @@ static void optimize(int argc, VALUE *argv, ROptTable rot, bool on) {
|
|
750
740
|
oj_rails_float_opt = on;
|
751
741
|
} else if (oj_string_writer_class == *argv) {
|
752
742
|
string_writer_optimized = on;
|
753
|
-
} else if (NULL != (ro = oj_rails_get_opt(rot, *argv)) ||
|
754
|
-
NULL != (ro = create_opt(rot, *argv))) {
|
743
|
+
} else if (NULL != (ro = oj_rails_get_opt(rot, *argv)) || NULL != (ro = create_opt(rot, *argv))) {
|
755
744
|
ro->on = on;
|
756
745
|
}
|
757
746
|
}
|
@@ -770,7 +759,8 @@ static void optimize(int argc, VALUE *argv, ROptTable rot, bool on) {
|
|
770
759
|
* - *classes* [_Class_] a list of classes to optimize
|
771
760
|
*/
|
772
761
|
static VALUE encoder_optimize(int argc, VALUE *argv, VALUE self) {
|
773
|
-
Encoder e
|
762
|
+
Encoder e;
|
763
|
+
TypedData_Get_Struct(self, struct _encoder, &oj_encoder_type, e);
|
774
764
|
|
775
765
|
optimize(argc, argv, &e->ropts, true);
|
776
766
|
|
@@ -813,7 +803,7 @@ rails_mimic_json(VALUE self) {
|
|
813
803
|
}
|
814
804
|
oj_mimic_json_methods(json);
|
815
805
|
// Setting the default mode breaks the prmoise in the docs not to.
|
816
|
-
//oj_default_options.mode = RailsMode;
|
806
|
+
// oj_default_options.mode = RailsMode;
|
817
807
|
|
818
808
|
return Qnil;
|
819
809
|
}
|
@@ -826,7 +816,8 @@ rails_mimic_json(VALUE self) {
|
|
826
816
|
* - *classes* [_Class_] a list of classes to deoptimize
|
827
817
|
*/
|
828
818
|
static VALUE encoder_deoptimize(int argc, VALUE *argv, VALUE self) {
|
829
|
-
Encoder e
|
819
|
+
Encoder e;
|
820
|
+
TypedData_Get_Struct(self, struct _encoder, &oj_encoder_type, e);
|
830
821
|
|
831
822
|
optimize(argc, argv, &e->ropts, false);
|
832
823
|
|
@@ -855,8 +846,11 @@ static VALUE rails_deoptimize(int argc, VALUE *argv, VALUE self) {
|
|
855
846
|
* @return true if the class is being optimized for rails and false otherwise
|
856
847
|
*/
|
857
848
|
static VALUE encoder_optimized(VALUE self, VALUE clas) {
|
858
|
-
Encoder e
|
859
|
-
ROpt ro
|
849
|
+
Encoder e;
|
850
|
+
ROpt ro;
|
851
|
+
|
852
|
+
TypedData_Get_Struct(self, struct _encoder, &oj_encoder_type, e);
|
853
|
+
ro = oj_rails_get_opt(&e->ropts, clas);
|
860
854
|
|
861
855
|
if (NULL == ro) {
|
862
856
|
return Qfalse;
|
@@ -881,7 +875,7 @@ static VALUE rails_optimized(VALUE self, VALUE clas) {
|
|
881
875
|
typedef struct _oo {
|
882
876
|
Out out;
|
883
877
|
VALUE obj;
|
884
|
-
} *
|
878
|
+
} *OO;
|
885
879
|
|
886
880
|
static VALUE protect_dump(VALUE ov) {
|
887
881
|
OO oo = (OO)ov;
|
@@ -911,16 +905,15 @@ static VALUE encode(VALUE obj, ROptTable ropts, Options opts, int argc, VALUE *a
|
|
911
905
|
|
912
906
|
oj_out_init(&out);
|
913
907
|
|
914
|
-
out.omit_nil
|
915
|
-
out.
|
916
|
-
out.
|
917
|
-
out.
|
918
|
-
out.
|
919
|
-
out.
|
920
|
-
out.
|
921
|
-
out.
|
922
|
-
out.
|
923
|
-
out.ropts = ropts;
|
908
|
+
out.omit_nil = copts.dump_opts.omit_nil;
|
909
|
+
out.cur = out.buf;
|
910
|
+
out.circ_cnt = 0;
|
911
|
+
out.opts = &copts;
|
912
|
+
out.hash_cnt = 0;
|
913
|
+
out.indent = copts.indent;
|
914
|
+
out.argc = argc;
|
915
|
+
out.argv = argv;
|
916
|
+
out.ropts = ropts;
|
924
917
|
if (Yes == copts.circular) {
|
925
918
|
oj_cache8_new(&out.circ_cache);
|
926
919
|
}
|
@@ -963,7 +956,8 @@ static VALUE encode(VALUE obj, ROptTable ropts, Options opts, int argc, VALUE *a
|
|
963
956
|
* Returns encoded object as a JSON string.
|
964
957
|
*/
|
965
958
|
static VALUE encoder_encode(VALUE self, VALUE obj) {
|
966
|
-
Encoder e
|
959
|
+
Encoder e;
|
960
|
+
TypedData_Get_Struct(self, struct _encoder, &oj_encoder_type, e);
|
967
961
|
|
968
962
|
if (Qnil != e->arg) {
|
969
963
|
VALUE argv[1] = {e->arg};
|
@@ -1065,28 +1059,16 @@ static VALUE rails_set_encoder(VALUE self) {
|
|
1065
1059
|
verbose = rb_gv_get("$VERBOSE");
|
1066
1060
|
rb_gv_set("$VERBOSE", Qfalse);
|
1067
1061
|
rb_undef_method(encoding, "use_standard_json_time_format=");
|
1068
|
-
rb_define_module_function(encoding,
|
1069
|
-
"use_standard_json_time_format=",
|
1070
|
-
rails_use_standard_json_time_format,
|
1071
|
-
1);
|
1062
|
+
rb_define_module_function(encoding, "use_standard_json_time_format=", rails_use_standard_json_time_format, 1);
|
1072
1063
|
rb_undef_method(encoding, "use_standard_json_time_format");
|
1073
|
-
rb_define_module_function(encoding,
|
1074
|
-
"use_standard_json_time_format",
|
1075
|
-
rails_use_standard_json_time_format_get,
|
1076
|
-
0);
|
1064
|
+
rb_define_module_function(encoding, "use_standard_json_time_format", rails_use_standard_json_time_format_get, 0);
|
1077
1065
|
|
1078
1066
|
pv = rb_iv_get(encoding, "@escape_html_entities_in_json");
|
1079
1067
|
escape_html = Qtrue == pv;
|
1080
1068
|
rb_undef_method(encoding, "escape_html_entities_in_json=");
|
1081
|
-
rb_define_module_function(encoding,
|
1082
|
-
"escape_html_entities_in_json=",
|
1083
|
-
rails_escape_html_entities_in_json,
|
1084
|
-
1);
|
1069
|
+
rb_define_module_function(encoding, "escape_html_entities_in_json=", rails_escape_html_entities_in_json, 1);
|
1085
1070
|
rb_undef_method(encoding, "escape_html_entities_in_json");
|
1086
|
-
rb_define_module_function(encoding,
|
1087
|
-
"escape_html_entities_in_json",
|
1088
|
-
rails_escape_html_entities_in_json_get,
|
1089
|
-
0);
|
1071
|
+
rb_define_module_function(encoding, "escape_html_entities_in_json", rails_escape_html_entities_in_json_get, 0);
|
1090
1072
|
|
1091
1073
|
pv = rb_iv_get(encoding, "@time_precision");
|
1092
1074
|
oj_default_options.sec_prec = NUM2INT(pv);
|
@@ -1119,6 +1101,8 @@ static VALUE rails_set_decoder(VALUE self) {
|
|
1119
1101
|
} else {
|
1120
1102
|
json_error = rb_define_class_under(json, "JSONError", rb_eStandardError);
|
1121
1103
|
}
|
1104
|
+
|
1105
|
+
rb_global_variable(&oj_json_parser_error_class);
|
1122
1106
|
if (rb_const_defined_at(json, rb_intern("ParserError"))) {
|
1123
1107
|
oj_json_parser_error_class = rb_const_get(json, rb_intern("ParserError"));
|
1124
1108
|
} else {
|
@@ -1188,7 +1172,7 @@ static void dump_to_hash(VALUE obj, int depth, Out out) {
|
|
1188
1172
|
|
1189
1173
|
static void dump_float(VALUE obj, int depth, Out out, bool as_ok) {
|
1190
1174
|
char buf[64];
|
1191
|
-
char
|
1175
|
+
char *b;
|
1192
1176
|
double d = rb_num2dbl(obj);
|
1193
1177
|
int cnt = 0;
|
1194
1178
|
|
@@ -1208,7 +1192,7 @@ static void dump_float(VALUE obj, int depth, Out out, bool as_ok) {
|
|
1208
1192
|
} else if (oj_rails_float_opt) {
|
1209
1193
|
cnt = oj_dump_float_printf(buf, sizeof(buf), obj, d, "%0.16g");
|
1210
1194
|
} else {
|
1211
|
-
volatile VALUE rstr =
|
1195
|
+
volatile VALUE rstr = oj_safe_string_convert(obj);
|
1212
1196
|
|
1213
1197
|
strcpy(buf, RSTRING_PTR(rstr));
|
1214
1198
|
cnt = (int)RSTRING_LEN(rstr);
|
@@ -1301,7 +1285,7 @@ static int hash_cb(VALUE key, VALUE value, VALUE ov) {
|
|
1301
1285
|
return ST_CONTINUE;
|
1302
1286
|
}
|
1303
1287
|
if (rtype != T_STRING && rtype != T_SYMBOL) {
|
1304
|
-
key =
|
1288
|
+
key = oj_safe_string_convert(key);
|
1305
1289
|
rtype = rb_type(key);
|
1306
1290
|
}
|
1307
1291
|
if (!out->opts->dump_opts.use) {
|
@@ -1464,9 +1448,7 @@ static DumpFunc rails_funcs[] = {
|
|
1464
1448
|
static void dump_rails_val(VALUE obj, int depth, Out out, bool as_ok) {
|
1465
1449
|
int type = rb_type(obj);
|
1466
1450
|
|
1467
|
-
|
1468
|
-
oj_trace("dump", obj, __FILE__, __LINE__, depth, TraceIn);
|
1469
|
-
}
|
1451
|
+
TRACE(out->opts->trace, "dump", obj, depth, TraceIn);
|
1470
1452
|
if (MAX_DEPTH < depth) {
|
1471
1453
|
rb_raise(rb_eNoMemError, "Too deeply nested.\n");
|
1472
1454
|
}
|
@@ -1475,16 +1457,12 @@ static void dump_rails_val(VALUE obj, int depth, Out out, bool as_ok) {
|
|
1475
1457
|
|
1476
1458
|
if (NULL != f) {
|
1477
1459
|
f(obj, depth, out, as_ok);
|
1478
|
-
|
1479
|
-
oj_trace("dump", obj, __FILE__, __LINE__, depth, TraceOut);
|
1480
|
-
}
|
1460
|
+
TRACE(out->opts->trace, "dump", obj, depth, TraceOut);
|
1481
1461
|
return;
|
1482
1462
|
}
|
1483
1463
|
}
|
1484
1464
|
oj_dump_nil(Qnil, depth, out, false);
|
1485
|
-
|
1486
|
-
oj_trace("dump", Qnil, __FILE__, __LINE__, depth, TraceOut);
|
1487
|
-
}
|
1465
|
+
TRACE(out->opts->trace, "dump", Qnil, depth, TraceOut);
|
1488
1466
|
}
|
1489
1467
|
|
1490
1468
|
void oj_dump_rails_val(VALUE obj, int depth, Out out) {
|
data/ext/oj/reader.c
CHANGED
@@ -14,6 +14,7 @@
|
|
14
14
|
#include <time.h>
|
15
15
|
#include <unistd.h>
|
16
16
|
|
17
|
+
#include "mem.h"
|
17
18
|
#include "oj.h"
|
18
19
|
#include "reader.h"
|
19
20
|
#include "ruby.h"
|
@@ -63,8 +64,7 @@ void oj_reader_init(Reader reader, VALUE io, int fd, bool to_s) {
|
|
63
64
|
reader->tail = reader->head;
|
64
65
|
reader->read_end = reader->head + RSTRING_LEN(s);
|
65
66
|
} else if (rb_cFile == io_class && Qnil != (stat = rb_funcall(io, oj_stat_id, 0)) &&
|
66
|
-
Qnil != (ftype = rb_funcall(stat, oj_ftype_id, 0)) &&
|
67
|
-
0 == strcmp("file", StringValuePtr(ftype)) &&
|
67
|
+
Qnil != (ftype = rb_funcall(stat, oj_ftype_id, 0)) && 0 == strcmp("file", StringValuePtr(ftype)) &&
|
68
68
|
0 == FIX2INT(rb_funcall(io, oj_pos_id, 0))) {
|
69
69
|
reader->read_func = read_from_fd;
|
70
70
|
reader->fd = FIX2INT(rb_funcall(io, oj_fileno_id, 0));
|
@@ -75,7 +75,7 @@ void oj_reader_init(Reader reader, VALUE io, int fd, bool to_s) {
|
|
75
75
|
reader->read_func = read_from_io;
|
76
76
|
reader->io = io;
|
77
77
|
} else if (to_s) {
|
78
|
-
volatile VALUE rstr =
|
78
|
+
volatile VALUE rstr = oj_safe_string_convert(io);
|
79
79
|
|
80
80
|
reader->read_func = 0;
|
81
81
|
reader->in_str = StringValuePtr(rstr);
|
@@ -83,8 +83,7 @@ void oj_reader_init(Reader reader, VALUE io, int fd, bool to_s) {
|
|
83
83
|
reader->tail = reader->head;
|
84
84
|
reader->read_end = reader->head + RSTRING_LEN(rstr);
|
85
85
|
} else {
|
86
|
-
rb_raise(rb_eArgError,
|
87
|
-
"parser io argument must be a String or respond to readpartial() or read().\n");
|
86
|
+
rb_raise(rb_eArgError, "parser io argument must be a String or respond to readpartial() or read().\n");
|
88
87
|
}
|
89
88
|
}
|
90
89
|
|
@@ -107,10 +106,10 @@ int oj_reader_read(Reader reader) {
|
|
107
106
|
size_t size = reader->end - reader->head + BUF_PAD;
|
108
107
|
|
109
108
|
if (reader->head == reader->base) {
|
110
|
-
reader->head =
|
109
|
+
reader->head = OJ_R_ALLOC_N(char, size * 2);
|
111
110
|
memcpy((char *)reader->head, old, size);
|
112
111
|
} else {
|
113
|
-
|
112
|
+
OJ_R_REALLOC_N(reader->head, char, size * 2);
|
114
113
|
}
|
115
114
|
reader->free_head = 1;
|
116
115
|
reader->end = reader->head + size * 2 - BUF_PAD;
|
@@ -123,9 +122,7 @@ int oj_reader_read(Reader reader) {
|
|
123
122
|
reader->str = reader->head + (reader->str - old);
|
124
123
|
}
|
125
124
|
} else {
|
126
|
-
memmove((char *)reader->head,
|
127
|
-
reader->head + shift,
|
128
|
-
reader->read_end - (reader->head + shift));
|
125
|
+
memmove((char *)reader->head, reader->head + shift, reader->read_end - (reader->head + shift));
|
129
126
|
reader->tail -= shift;
|
130
127
|
reader->read_end -= shift;
|
131
128
|
if (0 != reader->pro) {
|
@@ -157,7 +154,7 @@ static VALUE partial_io_cb(VALUE rbuf) {
|
|
157
154
|
Reader reader = (Reader)rbuf;
|
158
155
|
VALUE args[1];
|
159
156
|
VALUE rstr;
|
160
|
-
char
|
157
|
+
char *str;
|
161
158
|
size_t cnt;
|
162
159
|
|
163
160
|
args[0] = ULONG2NUM(reader->end - reader->tail);
|
@@ -167,7 +164,6 @@ static VALUE partial_io_cb(VALUE rbuf) {
|
|
167
164
|
}
|
168
165
|
str = StringValuePtr(rstr);
|
169
166
|
cnt = RSTRING_LEN(rstr);
|
170
|
-
// printf("*** partial read %lu bytes, str: '%s'\n", cnt, str);
|
171
167
|
strcpy(reader->tail, str);
|
172
168
|
reader->read_end = reader->tail + cnt;
|
173
169
|
|
@@ -178,7 +174,7 @@ static VALUE io_cb(VALUE rbuf) {
|
|
178
174
|
Reader reader = (Reader)rbuf;
|
179
175
|
VALUE args[1];
|
180
176
|
VALUE rstr;
|
181
|
-
char
|
177
|
+
char *str;
|
182
178
|
size_t cnt;
|
183
179
|
|
184
180
|
args[0] = ULONG2NUM(reader->end - reader->tail);
|
@@ -188,7 +184,6 @@ static VALUE io_cb(VALUE rbuf) {
|
|
188
184
|
}
|
189
185
|
str = StringValuePtr(rstr);
|
190
186
|
cnt = RSTRING_LEN(rstr);
|
191
|
-
// printf("*** read %lu bytes, str: '%s'\n", cnt, str);
|
192
187
|
strcpy(reader->tail, str);
|
193
188
|
reader->read_end = reader->tail + cnt;
|
194
189
|
|
data/ext/oj/reader.h
CHANGED
@@ -4,6 +4,8 @@
|
|
4
4
|
#ifndef OJ_READER_H
|
5
5
|
#define OJ_READER_H
|
6
6
|
|
7
|
+
#include "mem.h"
|
8
|
+
|
7
9
|
typedef struct _reader {
|
8
10
|
char base[0x00001000];
|
9
11
|
char *head;
|
@@ -22,7 +24,7 @@ typedef struct _reader {
|
|
22
24
|
VALUE io;
|
23
25
|
const char *in_str;
|
24
26
|
};
|
25
|
-
} *
|
27
|
+
} *Reader;
|
26
28
|
|
27
29
|
extern void oj_reader_init(Reader reader, VALUE io, int fd, bool to_s);
|
28
30
|
extern int oj_reader_read(Reader reader);
|
@@ -114,7 +116,7 @@ static inline int reader_expect(Reader reader, const char *s) {
|
|
114
116
|
|
115
117
|
static inline void reader_cleanup(Reader reader) {
|
116
118
|
if (reader->free_head && 0 != reader->head) {
|
117
|
-
|
119
|
+
OJ_R_FREE((char *)reader->head);
|
118
120
|
reader->head = 0;
|
119
121
|
reader->free_head = 0;
|
120
122
|
}
|
data/ext/oj/resolve.c
CHANGED
@@ -27,12 +27,11 @@ inline static VALUE resolve_classname(VALUE mod, const char *classname, int auto
|
|
27
27
|
return clas;
|
28
28
|
}
|
29
29
|
|
30
|
-
static VALUE
|
31
|
-
resolve_classpath(ParseInfo pi, const char *name, size_t len, int auto_define, VALUE error_class) {
|
30
|
+
static VALUE resolve_classpath(ParseInfo pi, const char *name, size_t len, int auto_define, VALUE error_class) {
|
32
31
|
char class_name[1024];
|
33
32
|
VALUE clas;
|
34
|
-
char
|
35
|
-
char
|
33
|
+
char *end = class_name + sizeof(class_name) - 1;
|
34
|
+
char *s;
|
36
35
|
const char *n = name;
|
37
36
|
|
38
37
|
clas = rb_cObject;
|
data/ext/oj/rxclass.c
CHANGED
@@ -10,6 +10,7 @@
|
|
10
10
|
#include <regex.h>
|
11
11
|
#endif
|
12
12
|
|
13
|
+
#include "mem.h"
|
13
14
|
#include "rxclass.h"
|
14
15
|
|
15
16
|
typedef struct _rxC {
|
@@ -20,7 +21,7 @@ typedef struct _rxC {
|
|
20
21
|
#endif
|
21
22
|
VALUE clas;
|
22
23
|
char src[256];
|
23
|
-
} *
|
24
|
+
} *RxC;
|
24
25
|
|
25
26
|
void oj_rxclass_init(RxClass rc) {
|
26
27
|
*rc->err = '\0';
|
@@ -37,13 +38,13 @@ void oj_rxclass_cleanup(RxClass rc) {
|
|
37
38
|
if (Qnil == rxc->rrx) {
|
38
39
|
regfree(&rxc->rx);
|
39
40
|
}
|
40
|
-
|
41
|
+
OJ_R_FREE(rxc);
|
41
42
|
#endif
|
42
43
|
}
|
43
44
|
}
|
44
45
|
|
45
46
|
void oj_rxclass_rappend(RxClass rc, VALUE rx, VALUE clas) {
|
46
|
-
RxC rxc =
|
47
|
+
RxC rxc = OJ_R_ALLOC_N(struct _rxC, 1);
|
47
48
|
|
48
49
|
memset(rxc, 0, sizeof(struct _rxC));
|
49
50
|
rxc->rrx = rx;
|
@@ -70,7 +71,7 @@ int oj_rxclass_append(RxClass rc, const char *expr, VALUE clas) {
|
|
70
71
|
(unsigned long)sizeof(rxc->src));
|
71
72
|
return EINVAL;
|
72
73
|
}
|
73
|
-
rxc =
|
74
|
+
rxc = OJ_R_ALLOC_N(struct _rxC, 1);
|
74
75
|
rxc->next = 0;
|
75
76
|
rxc->clas = clas;
|
76
77
|
|
@@ -80,7 +81,7 @@ int oj_rxclass_append(RxClass rc, const char *expr, VALUE clas) {
|
|
80
81
|
rxc->rrx = Qnil;
|
81
82
|
if (0 != (err = regcomp(&rxc->rx, expr, flags))) {
|
82
83
|
regerror(err, &rxc->rx, rc->err, sizeof(rc->err));
|
83
|
-
|
84
|
+
OJ_FREE(rxc);
|
84
85
|
return err;
|
85
86
|
}
|
86
87
|
#endif
|
data/ext/oj/rxclass.h
CHANGED
data/ext/oj/saj.c
CHANGED
@@ -15,6 +15,7 @@
|
|
15
15
|
#define OJ_INFINITY (1.0 / 0.0)
|
16
16
|
|
17
17
|
#include "encode.h"
|
18
|
+
#include "mem.h"
|
18
19
|
#include "oj.h"
|
19
20
|
|
20
21
|
typedef struct _parseInfo {
|
@@ -28,7 +29,7 @@ typedef struct _parseInfo {
|
|
28
29
|
int has_array_end;
|
29
30
|
int has_add_value;
|
30
31
|
int has_error;
|
31
|
-
} *
|
32
|
+
} *ParseInfo;
|
32
33
|
|
33
34
|
static void read_next(ParseInfo pi, const char *key);
|
34
35
|
static void read_hash(ParseInfo pi, const char *key);
|
@@ -577,7 +578,7 @@ static void saj_parse(VALUE handler, char *json) {
|
|
577
578
|
/* initialize parse info */
|
578
579
|
pi.str = json;
|
579
580
|
pi.s = json;
|
580
|
-
#if IS_WINDOWS
|
581
|
+
#if IS_WINDOWS || !defined(HAVE_GETRLIMIT)
|
581
582
|
pi.stack_min = (void *)((char *)&obj - (512L * 1024L)); /* assume a 1M stack and give half to ruby */
|
582
583
|
#else
|
583
584
|
{
|
@@ -631,7 +632,7 @@ oj_saj_parse(int argc, VALUE *argv, VALUE self) {
|
|
631
632
|
if (rb_type(input) == T_STRING) {
|
632
633
|
// the json string gets modified so make a copy of it
|
633
634
|
len = RSTRING_LEN(input) + 1;
|
634
|
-
json =
|
635
|
+
json = OJ_R_ALLOC_N(char, len);
|
635
636
|
strcpy(json, StringValuePtr(input));
|
636
637
|
} else {
|
637
638
|
VALUE clas = rb_obj_class(input);
|
@@ -640,8 +641,8 @@ oj_saj_parse(int argc, VALUE *argv, VALUE self) {
|
|
640
641
|
if (oj_stringio_class == clas) {
|
641
642
|
s = rb_funcall2(input, oj_string_id, 0, 0);
|
642
643
|
len = RSTRING_LEN(s) + 1;
|
643
|
-
json =
|
644
|
-
strcpy(json,
|
644
|
+
json = OJ_R_ALLOC_N(char, len);
|
645
|
+
strcpy(json, StringValueCStr(s));
|
645
646
|
#if !IS_WINDOWS
|
646
647
|
} else if (rb_cFile == clas && 0 == FIX2INT(rb_funcall(input, oj_pos_id, 0))) {
|
647
648
|
int fd = FIX2INT(rb_funcall(input, oj_fileno_id, 0));
|
@@ -649,7 +650,7 @@ oj_saj_parse(int argc, VALUE *argv, VALUE self) {
|
|
649
650
|
|
650
651
|
len = lseek(fd, 0, SEEK_END);
|
651
652
|
lseek(fd, 0, SEEK_SET);
|
652
|
-
json =
|
653
|
+
json = OJ_R_ALLOC_N(char, len + 1);
|
653
654
|
if (0 >= (cnt = read(fd, json, len)) || cnt != (ssize_t)len) {
|
654
655
|
rb_raise(rb_eIOError, "failed to read from IO Object.");
|
655
656
|
}
|
@@ -658,14 +659,14 @@ oj_saj_parse(int argc, VALUE *argv, VALUE self) {
|
|
658
659
|
} else if (rb_respond_to(input, oj_read_id)) {
|
659
660
|
s = rb_funcall2(input, oj_read_id, 0, 0);
|
660
661
|
len = RSTRING_LEN(s) + 1;
|
661
|
-
json =
|
662
|
-
strcpy(json,
|
662
|
+
json = OJ_R_ALLOC_N(char, len);
|
663
|
+
strcpy(json, StringValueCStr(s));
|
663
664
|
} else {
|
664
665
|
rb_raise(rb_eArgError, "saj_parse() expected a String or IO Object.");
|
665
666
|
}
|
666
667
|
}
|
667
668
|
saj_parse(*argv, json);
|
668
|
-
|
669
|
+
OJ_R_FREE(json);
|
669
670
|
|
670
671
|
return Qnil;
|
671
672
|
}
|