oj 3.13.9 → 3.13.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +14 -0
- data/README.md +9 -0
- data/ext/oj/circarray.c +1 -1
- data/ext/oj/code.c +15 -22
- data/ext/oj/custom.c +32 -59
- data/ext/oj/dump.c +129 -175
- data/ext/oj/dump.h +25 -8
- data/ext/oj/dump_compat.c +44 -81
- data/ext/oj/dump_leaf.c +14 -58
- data/ext/oj/dump_object.c +68 -129
- data/ext/oj/dump_strict.c +14 -26
- data/ext/oj/encoder.c +43 -0
- data/ext/oj/fast.c +15 -9
- data/ext/oj/intern.c +9 -2
- data/ext/oj/intern.h +1 -1
- data/ext/oj/mimic_json.c +73 -73
- data/ext/oj/object.c +1 -1
- data/ext/oj/odd.c +83 -63
- data/ext/oj/odd.h +13 -13
- data/ext/oj/oj.c +29 -17
- data/ext/oj/oj.h +20 -2
- data/ext/oj/parse.c +3 -2
- data/ext/oj/parser.c +10 -15
- data/ext/oj/rails.c +43 -62
- data/ext/oj/rails.h +1 -1
- data/ext/oj/reader.c +2 -0
- data/ext/oj/saj.c +11 -23
- data/ext/oj/stream_writer.c +3 -1
- data/ext/oj/string_writer.c +12 -5
- data/ext/oj/wab.c +9 -9
- data/lib/oj/version.rb +1 -1
- data/pages/JsonGem.md +15 -0
- data/pages/Modes.md +6 -3
- data/pages/Rails.md +12 -0
- data/test/bar.rb +1 -8
- data/test/foo.rb +70 -13
- data/test/perf_dump.rb +50 -0
- data/test/test_fast.rb +19 -0
- data/test/test_object.rb +12 -7
- data/test/test_saj.rb +1 -1
- data/test/test_various.rb +27 -2
- data/test/tests.rb +0 -1
- metadata +6 -3
data/ext/oj/oj.h
CHANGED
@@ -39,6 +39,16 @@ enum st_retval { ST_CONTINUE = 0, ST_STOP = 1, ST_DELETE = 2, ST_CHECK };
|
|
39
39
|
#define NINF_VAL "-3.0e14159265358979323846"
|
40
40
|
#define NAN_VAL "3.3e14159265358979323846"
|
41
41
|
|
42
|
+
#if __STDC_VERSION__ >= 199901L
|
43
|
+
// To avoid using ruby_snprintf with C99.
|
44
|
+
#undef snprintf
|
45
|
+
#include <stdio.h>
|
46
|
+
#endif
|
47
|
+
|
48
|
+
// To avoid using ruby_nonempty_memcpy().
|
49
|
+
#undef memcpy
|
50
|
+
#include <string.h>
|
51
|
+
|
42
52
|
typedef enum { Yes = 'y', No = 'n', NotSet = 0 } YesNo;
|
43
53
|
|
44
54
|
typedef enum {
|
@@ -176,6 +186,7 @@ typedef struct _rOptTable {
|
|
176
186
|
} * ROptTable;
|
177
187
|
|
178
188
|
typedef struct _out {
|
189
|
+
char stack_buffer[4096];
|
179
190
|
char * buf;
|
180
191
|
char * end;
|
181
192
|
char * cur;
|
@@ -265,8 +276,8 @@ extern void oj_str_writer_pop(StrWriter sw);
|
|
265
276
|
extern void oj_str_writer_pop_all(StrWriter sw);
|
266
277
|
|
267
278
|
extern void oj_init_doc(void);
|
268
|
-
extern void oj_string_writer_init();
|
269
|
-
extern void oj_stream_writer_init();
|
279
|
+
extern void oj_string_writer_init(void);
|
280
|
+
extern void oj_stream_writer_init(void);
|
270
281
|
extern void oj_str_writer_init(StrWriter sw, int buf_size);
|
271
282
|
extern VALUE oj_define_mimic_json(int argc, VALUE *argv, VALUE self);
|
272
283
|
extern VALUE oj_mimic_generate(int argc, VALUE *argv, VALUE self);
|
@@ -282,6 +293,7 @@ extern VALUE oj_rails_encode(int argc, VALUE *argv, VALUE self);
|
|
282
293
|
extern VALUE Oj;
|
283
294
|
extern struct _options oj_default_options;
|
284
295
|
extern rb_encoding * oj_utf8_encoding;
|
296
|
+
extern int oj_utf8_encoding_index;
|
285
297
|
|
286
298
|
extern VALUE oj_bag_class;
|
287
299
|
extern VALUE oj_bigdecimal_class;
|
@@ -364,6 +376,12 @@ extern bool oj_use_hash_alt;
|
|
364
376
|
extern bool oj_use_array_alt;
|
365
377
|
extern bool string_writer_optimized;
|
366
378
|
|
379
|
+
#define APPEND_CHARS(buffer, chars, size) \
|
380
|
+
{ \
|
381
|
+
memcpy(buffer, chars, size); \
|
382
|
+
buffer += size; \
|
383
|
+
}
|
384
|
+
|
367
385
|
#ifdef HAVE_PTHREAD_MUTEX_INIT
|
368
386
|
extern pthread_mutex_t oj_cache_mutex;
|
369
387
|
#else
|
data/ext/oj/parse.c
CHANGED
@@ -972,9 +972,10 @@ static VALUE protect_parse(VALUE pip) {
|
|
972
972
|
extern int oj_utf8_index;
|
973
973
|
|
974
974
|
static void oj_pi_set_input_str(ParseInfo pi, volatile VALUE *inputp) {
|
975
|
-
|
975
|
+
int idx = RB_ENCODING_GET(*inputp);
|
976
976
|
|
977
|
-
if (
|
977
|
+
if (oj_utf8_encoding_index != idx) {
|
978
|
+
rb_encoding *enc = rb_enc_from_index(idx);
|
978
979
|
*inputp = rb_str_conv_enc(*inputp, enc, oj_utf8_encoding);
|
979
980
|
}
|
980
981
|
pi->json = RSTRING_PTR(*inputp);
|
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
|
|
@@ -1190,7 +1182,7 @@ static VALUE parser_new(int argc, VALUE *argv, VALUE self) {
|
|
1190
1182
|
p->map = value_map;
|
1191
1183
|
|
1192
1184
|
if (argc < 1) {
|
1193
|
-
|
1185
|
+
oj_set_parser_validator(p);
|
1194
1186
|
} else {
|
1195
1187
|
VALUE mode = argv[0];
|
1196
1188
|
|
@@ -1284,7 +1276,7 @@ static VALUE parser_new(int argc, VALUE *argv, VALUE self) {
|
|
1284
1276
|
*/
|
1285
1277
|
static VALUE parser_missing(int argc, VALUE *argv, VALUE self) {
|
1286
1278
|
ojParser p = (ojParser)DATA_PTR(self);
|
1287
|
-
const char
|
1279
|
+
const char *key = NULL;
|
1288
1280
|
volatile VALUE rkey = *argv;
|
1289
1281
|
volatile VALUE rv = Qnil;
|
1290
1282
|
|
@@ -1515,8 +1507,11 @@ static VALUE parser_validate(VALUE self) {
|
|
1515
1507
|
* isolates options to just the parser so that other parts of the code are not
|
1516
1508
|
* forced to use the same options.
|
1517
1509
|
*/
|
1518
|
-
void oj_parser_init() {
|
1510
|
+
void oj_parser_init(void) {
|
1519
1511
|
parser_class = rb_define_class_under(Oj, "Parser", rb_cObject);
|
1512
|
+
rb_gc_register_address(&parser_class);
|
1513
|
+
rb_undef_alloc_func(parser_class);
|
1514
|
+
|
1520
1515
|
rb_define_module_function(parser_class, "new", parser_new, -1);
|
1521
1516
|
rb_define_method(parser_class, "parse", parser_parse, 1);
|
1522
1517
|
rb_define_method(parser_class, "load", parser_load, 1);
|
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);
|
@@ -330,12 +327,12 @@ static void dump_time(VALUE obj, int depth, Out out, bool as_ok) {
|
|
330
327
|
sec = (long long)ts.tv_sec;
|
331
328
|
nsec = ts.tv_nsec;
|
332
329
|
} else {
|
333
|
-
sec =
|
334
|
-
nsec =
|
330
|
+
sec = NUM2LL(rb_funcall2(obj, oj_tv_sec_id, 0, 0));
|
331
|
+
nsec = NUM2LL(rb_funcall2(obj, oj_tv_nsec_id, 0, 0));
|
335
332
|
}
|
336
333
|
#else
|
337
|
-
sec =
|
338
|
-
nsec =
|
334
|
+
sec = NUM2LL(rb_funcall2(obj, oj_tv_sec_id, 0, 0));
|
335
|
+
nsec = NUM2LL(rb_funcall2(obj, oj_tv_nsec_id, 0, 0));
|
339
336
|
#endif
|
340
337
|
dump_sec_nano(obj, sec, nsec, out);
|
341
338
|
}
|
@@ -345,9 +342,9 @@ static void dump_timewithzone(VALUE obj, int depth, Out out, bool as_ok) {
|
|
345
342
|
long long nsec = 0;
|
346
343
|
|
347
344
|
if (rb_respond_to(obj, oj_tv_nsec_id)) {
|
348
|
-
nsec =
|
345
|
+
nsec = NUM2LL(rb_funcall2(obj, oj_tv_nsec_id, 0, 0));
|
349
346
|
} else if (rb_respond_to(obj, oj_tv_usec_id)) {
|
350
|
-
nsec =
|
347
|
+
nsec = NUM2LL(rb_funcall2(obj, oj_tv_usec_id, 0, 0)) * 1000;
|
351
348
|
}
|
352
349
|
dump_sec_nano(obj, sec, nsec, out);
|
353
350
|
}
|
@@ -383,7 +380,7 @@ static StrLen columns_array(VALUE rcols, int *ccnt) {
|
|
383
380
|
*ccnt = cnt;
|
384
381
|
cols = ALLOC_N(struct _strLen, cnt);
|
385
382
|
for (i = 0, cp = cols; i < cnt; i++, cp++) {
|
386
|
-
v =
|
383
|
+
v = RARRAY_AREF(rcols, i);
|
387
384
|
if (T_STRING != rb_type(v)) {
|
388
385
|
v = rb_funcall(v, oj_to_s_id, 0);
|
389
386
|
}
|
@@ -405,14 +402,12 @@ static void dump_row(VALUE row, StrLen cols, int ccnt, int depth, Out out) {
|
|
405
402
|
assure_size(out, size);
|
406
403
|
if (out->opts->dump_opts.use) {
|
407
404
|
if (0 < out->opts->dump_opts.array_size) {
|
408
|
-
|
409
|
-
out->cur += out->opts->dump_opts.array_size;
|
405
|
+
APPEND_CHARS(out->cur, out->opts->dump_opts.array_nl, out->opts->dump_opts.array_size);
|
410
406
|
}
|
411
407
|
if (0 < out->opts->dump_opts.indent_size) {
|
412
408
|
int i;
|
413
409
|
for (i = d2; 0 < i; i--) {
|
414
|
-
|
415
|
-
out->cur += out->opts->dump_opts.indent_size;
|
410
|
+
APPEND_CHARS(out->cur, out->opts->dump_opts.indent_str, out->opts->dump_opts.indent_size);
|
416
411
|
}
|
417
412
|
}
|
418
413
|
} else {
|
@@ -420,7 +415,7 @@ static void dump_row(VALUE row, StrLen cols, int ccnt, int depth, Out out) {
|
|
420
415
|
}
|
421
416
|
oj_dump_cstr(cols->str, cols->len, 0, 0, out);
|
422
417
|
*out->cur++ = ':';
|
423
|
-
dump_rails_val(
|
418
|
+
dump_rails_val(RARRAY_AREF(row, i), depth, out, true);
|
424
419
|
if (i < ccnt - 1) {
|
425
420
|
*out->cur++ = ',';
|
426
421
|
}
|
@@ -429,15 +424,13 @@ static void dump_row(VALUE row, StrLen cols, int ccnt, int depth, Out out) {
|
|
429
424
|
assure_size(out, size);
|
430
425
|
if (out->opts->dump_opts.use) {
|
431
426
|
if (0 < out->opts->dump_opts.array_size) {
|
432
|
-
|
433
|
-
out->cur += out->opts->dump_opts.array_size;
|
427
|
+
APPEND_CHARS(out->cur, out->opts->dump_opts.array_nl, out->opts->dump_opts.array_size);
|
434
428
|
}
|
435
429
|
if (0 < out->opts->dump_opts.indent_size) {
|
436
430
|
int i;
|
437
431
|
|
438
432
|
for (i = depth; 0 < i; i--) {
|
439
|
-
|
440
|
-
out->cur += out->opts->dump_opts.indent_size;
|
433
|
+
APPEND_CHARS(out->cur, out->opts->dump_opts.indent_str, out->opts->dump_opts.indent_size);
|
441
434
|
}
|
442
435
|
}
|
443
436
|
} else {
|
@@ -477,20 +470,18 @@ static void dump_activerecord_result(VALUE obj, int depth, Out out, bool as_ok)
|
|
477
470
|
assure_size(out, size);
|
478
471
|
if (out->opts->dump_opts.use) {
|
479
472
|
if (0 < out->opts->dump_opts.array_size) {
|
480
|
-
|
481
|
-
out->cur += out->opts->dump_opts.array_size;
|
473
|
+
APPEND_CHARS(out->cur, out->opts->dump_opts.array_nl, out->opts->dump_opts.array_size);
|
482
474
|
}
|
483
475
|
if (0 < out->opts->dump_opts.indent_size) {
|
484
476
|
int i;
|
485
477
|
for (i = d2; 0 < i; i--) {
|
486
|
-
|
487
|
-
out->cur += out->opts->dump_opts.indent_size;
|
478
|
+
APPEND_CHARS(out->cur, out->opts->dump_opts.indent_str, out->opts->dump_opts.indent_size);
|
488
479
|
}
|
489
480
|
}
|
490
481
|
} else {
|
491
482
|
fill_indent(out, d2);
|
492
483
|
}
|
493
|
-
dump_row(
|
484
|
+
dump_row(RARRAY_AREF(rows, i), cols, ccnt, d2, out);
|
494
485
|
if (i < rcnt - 1) {
|
495
486
|
*out->cur++ = ',';
|
496
487
|
}
|
@@ -500,15 +491,13 @@ static void dump_activerecord_result(VALUE obj, int depth, Out out, bool as_ok)
|
|
500
491
|
assure_size(out, size);
|
501
492
|
if (out->opts->dump_opts.use) {
|
502
493
|
if (0 < out->opts->dump_opts.array_size) {
|
503
|
-
|
504
|
-
out->cur += out->opts->dump_opts.array_size;
|
494
|
+
APPEND_CHARS(out->cur, out->opts->dump_opts.array_nl, out->opts->dump_opts.array_size);
|
505
495
|
}
|
506
496
|
if (0 < out->opts->dump_opts.indent_size) {
|
507
497
|
int i;
|
508
498
|
|
509
499
|
for (i = depth; 0 < i; i--) {
|
510
|
-
|
511
|
-
out->cur += out->opts->dump_opts.indent_size;
|
500
|
+
APPEND_CHARS(out->cur, out->opts->dump_opts.indent_str, out->opts->dump_opts.indent_size);
|
512
501
|
}
|
513
502
|
}
|
514
503
|
} else {
|
@@ -908,7 +897,6 @@ static VALUE protect_dump(VALUE ov) {
|
|
908
897
|
}
|
909
898
|
|
910
899
|
static VALUE encode(VALUE obj, ROptTable ropts, Options opts, int argc, VALUE *argv) {
|
911
|
-
char buf[4096];
|
912
900
|
struct _out out;
|
913
901
|
struct _options copts = *opts;
|
914
902
|
volatile VALUE rstr = Qnil;
|
@@ -925,9 +913,9 @@ static VALUE encode(VALUE obj, ROptTable ropts, Options opts, int argc, VALUE *a
|
|
925
913
|
} else {
|
926
914
|
copts.escape_mode = RailsEsc;
|
927
915
|
}
|
928
|
-
|
929
|
-
out
|
930
|
-
|
916
|
+
|
917
|
+
oj_out_init(&out);
|
918
|
+
|
931
919
|
out.omit_nil = copts.dump_opts.omit_nil;
|
932
920
|
out.caller = 0;
|
933
921
|
out.cur = out.buf;
|
@@ -963,9 +951,9 @@ static VALUE encode(VALUE obj, ROptTable ropts, Options opts, int argc, VALUE *a
|
|
963
951
|
if (Yes == copts.circular) {
|
964
952
|
oj_cache8_delete(out.circ_cache);
|
965
953
|
}
|
966
|
-
|
967
|
-
|
968
|
-
|
954
|
+
|
955
|
+
oj_out_free(&out);
|
956
|
+
|
969
957
|
if (0 != line) {
|
970
958
|
rb_jump_tag(line);
|
971
959
|
}
|
@@ -1175,12 +1163,15 @@ oj_optimize_rails(VALUE self) {
|
|
1175
1163
|
*
|
1176
1164
|
* The Oj ActiveSupport compliant encoder.
|
1177
1165
|
*/
|
1178
|
-
void oj_mimic_rails_init() {
|
1166
|
+
void oj_mimic_rails_init(void) {
|
1179
1167
|
VALUE rails = rb_define_module_under(Oj, "Rails");
|
1180
1168
|
|
1181
1169
|
rb_define_module_function(rails, "encode", rails_encode, -1);
|
1182
1170
|
|
1183
1171
|
encoder_class = rb_define_class_under(rails, "Encoder", rb_cObject);
|
1172
|
+
rb_gc_register_address(&encoder_class);
|
1173
|
+
rb_undef_alloc_func(encoder_class);
|
1174
|
+
|
1184
1175
|
rb_define_module_function(encoder_class, "new", encoder_new, -1);
|
1185
1176
|
rb_define_module_function(rails, "optimize", rails_optimize, -1);
|
1186
1177
|
rb_define_module_function(rails, "deoptimize", rails_deoptimize, -1);
|
@@ -1263,25 +1254,23 @@ static void dump_array(VALUE a, int depth, Out out, bool as_ok) {
|
|
1263
1254
|
} else {
|
1264
1255
|
size = d2 * out->indent + 2;
|
1265
1256
|
}
|
1257
|
+
assure_size(out, size * cnt);
|
1266
1258
|
cnt--;
|
1267
1259
|
for (i = 0; i <= cnt; i++) {
|
1268
|
-
assure_size(out, size);
|
1269
1260
|
if (out->opts->dump_opts.use) {
|
1270
1261
|
if (0 < out->opts->dump_opts.array_size) {
|
1271
|
-
|
1272
|
-
out->cur += out->opts->dump_opts.array_size;
|
1262
|
+
APPEND_CHARS(out->cur, out->opts->dump_opts.array_nl, out->opts->dump_opts.array_size);
|
1273
1263
|
}
|
1274
1264
|
if (0 < out->opts->dump_opts.indent_size) {
|
1275
1265
|
int i;
|
1276
1266
|
for (i = d2; 0 < i; i--) {
|
1277
|
-
|
1278
|
-
out->cur += out->opts->dump_opts.indent_size;
|
1267
|
+
APPEND_CHARS(out->cur, out->opts->dump_opts.indent_str, out->opts->dump_opts.indent_size);
|
1279
1268
|
}
|
1280
1269
|
}
|
1281
1270
|
} else {
|
1282
1271
|
fill_indent(out, d2);
|
1283
1272
|
}
|
1284
|
-
dump_rails_val(
|
1273
|
+
dump_rails_val(RARRAY_AREF(a, i), d2, out, true);
|
1285
1274
|
if (i < cnt) {
|
1286
1275
|
*out->cur++ = ',';
|
1287
1276
|
}
|
@@ -1290,15 +1279,13 @@ static void dump_array(VALUE a, int depth, Out out, bool as_ok) {
|
|
1290
1279
|
assure_size(out, size);
|
1291
1280
|
if (out->opts->dump_opts.use) {
|
1292
1281
|
if (0 < out->opts->dump_opts.array_size) {
|
1293
|
-
|
1294
|
-
out->cur += out->opts->dump_opts.array_size;
|
1282
|
+
APPEND_CHARS(out->cur, out->opts->dump_opts.array_nl, out->opts->dump_opts.array_size);
|
1295
1283
|
}
|
1296
1284
|
if (0 < out->opts->dump_opts.indent_size) {
|
1297
1285
|
int i;
|
1298
1286
|
|
1299
1287
|
for (i = depth; 0 < i; i--) {
|
1300
|
-
|
1301
|
-
out->cur += out->opts->dump_opts.indent_size;
|
1288
|
+
APPEND_CHARS(out->cur, out->opts->dump_opts.indent_str, out->opts->dump_opts.indent_size);
|
1302
1289
|
}
|
1303
1290
|
}
|
1304
1291
|
} else {
|
@@ -1336,14 +1323,12 @@ static int hash_cb(VALUE key, VALUE value, VALUE ov) {
|
|
1336
1323
|
size = depth * out->opts->dump_opts.indent_size + out->opts->dump_opts.hash_size + 1;
|
1337
1324
|
assure_size(out, size);
|
1338
1325
|
if (0 < out->opts->dump_opts.hash_size) {
|
1339
|
-
|
1340
|
-
out->cur += out->opts->dump_opts.hash_size;
|
1326
|
+
APPEND_CHARS(out->cur, out->opts->dump_opts.hash_nl, out->opts->dump_opts.hash_size);
|
1341
1327
|
}
|
1342
1328
|
if (0 < out->opts->dump_opts.indent_size) {
|
1343
1329
|
int i;
|
1344
1330
|
for (i = depth; 0 < i; i--) {
|
1345
|
-
|
1346
|
-
out->cur += out->opts->dump_opts.indent_size;
|
1331
|
+
APPEND_CHARS(out->cur, out->opts->dump_opts.indent_str, out->opts->dump_opts.indent_size);
|
1347
1332
|
}
|
1348
1333
|
}
|
1349
1334
|
if (rtype == T_STRING) {
|
@@ -1354,13 +1339,11 @@ static int hash_cb(VALUE key, VALUE value, VALUE ov) {
|
|
1354
1339
|
size = out->opts->dump_opts.before_size + out->opts->dump_opts.after_size + 2;
|
1355
1340
|
assure_size(out, size);
|
1356
1341
|
if (0 < out->opts->dump_opts.before_size) {
|
1357
|
-
|
1358
|
-
out->cur += out->opts->dump_opts.before_size;
|
1342
|
+
APPEND_CHARS(out->cur, out->opts->dump_opts.before_sep, out->opts->dump_opts.before_size);
|
1359
1343
|
}
|
1360
1344
|
*out->cur++ = ':';
|
1361
1345
|
if (0 < out->opts->dump_opts.after_size) {
|
1362
|
-
|
1363
|
-
out->cur += out->opts->dump_opts.after_size;
|
1346
|
+
APPEND_CHARS(out->cur, out->opts->dump_opts.after_sep, out->opts->dump_opts.after_size);
|
1364
1347
|
}
|
1365
1348
|
}
|
1366
1349
|
dump_rails_val(value, depth, out, true);
|
@@ -1403,15 +1386,13 @@ static void dump_hash(VALUE obj, int depth, Out out, bool as_ok) {
|
|
1403
1386
|
size = depth * out->opts->dump_opts.indent_size + out->opts->dump_opts.hash_size + 1;
|
1404
1387
|
assure_size(out, size);
|
1405
1388
|
if (0 < out->opts->dump_opts.hash_size) {
|
1406
|
-
|
1407
|
-
out->cur += out->opts->dump_opts.hash_size;
|
1389
|
+
APPEND_CHARS(out->cur, out->opts->dump_opts.hash_nl, out->opts->dump_opts.hash_size);
|
1408
1390
|
}
|
1409
1391
|
if (0 < out->opts->dump_opts.indent_size) {
|
1410
1392
|
int i;
|
1411
1393
|
|
1412
1394
|
for (i = depth; 0 < i; i--) {
|
1413
|
-
|
1414
|
-
out->cur += out->opts->dump_opts.indent_size;
|
1395
|
+
APPEND_CHARS(out->cur, out->opts->dump_opts.indent_str, out->opts->dump_opts.indent_size);
|
1415
1396
|
}
|
1416
1397
|
}
|
1417
1398
|
}
|
data/ext/oj/rails.h
CHANGED
data/ext/oj/reader.c
CHANGED
data/ext/oj/saj.c
CHANGED
@@ -210,10 +210,7 @@ static void read_hash(ParseInfo pi, const char *key) {
|
|
210
210
|
pi->s++;
|
211
211
|
} else {
|
212
212
|
if (pi->has_error) {
|
213
|
-
call_error("invalid format, expected , or } while in an object",
|
214
|
-
pi,
|
215
|
-
__FILE__,
|
216
|
-
__LINE__);
|
213
|
+
call_error("invalid format, expected , or } while in an object", pi, __FILE__, __LINE__);
|
217
214
|
}
|
218
215
|
raise_error("invalid format, expected , or } while in an object", pi->str, pi->s);
|
219
216
|
}
|
@@ -243,10 +240,7 @@ static void read_array(ParseInfo pi, const char *key) {
|
|
243
240
|
break;
|
244
241
|
} else {
|
245
242
|
if (pi->has_error) {
|
246
|
-
call_error("invalid format, expected , or ] while in an array",
|
247
|
-
pi,
|
248
|
-
__FILE__,
|
249
|
-
__LINE__);
|
243
|
+
call_error("invalid format, expected , or ] while in an array", pi, __FILE__, __LINE__);
|
250
244
|
}
|
251
245
|
raise_error("invalid format, expected , or ] while in an array", pi->str, pi->s);
|
252
246
|
}
|
@@ -276,7 +270,7 @@ static void read_str(ParseInfo pi, const char *key) {
|
|
276
270
|
#endif
|
277
271
|
|
278
272
|
static void read_num(ParseInfo pi, const char *key) {
|
279
|
-
char
|
273
|
+
char *start = pi->s;
|
280
274
|
int64_t n = 0;
|
281
275
|
long a = 0;
|
282
276
|
long div = 1;
|
@@ -351,9 +345,7 @@ static void read_num(ParseInfo pi, const char *key) {
|
|
351
345
|
|
352
346
|
*pi->s = '\0';
|
353
347
|
if (pi->has_add_value) {
|
354
|
-
call_add_value(pi->handler,
|
355
|
-
rb_funcall(rb_cObject, oj_bigdecimal_id, 1, rb_str_new2(start)),
|
356
|
-
key);
|
348
|
+
call_add_value(pi->handler, rb_funcall(rb_cObject, oj_bigdecimal_id, 1, rb_str_new2(start)), key);
|
357
349
|
}
|
358
350
|
*pi->s = c;
|
359
351
|
} else {
|
@@ -371,9 +363,7 @@ static void read_num(ParseInfo pi, const char *key) {
|
|
371
363
|
|
372
364
|
*pi->s = '\0';
|
373
365
|
if (pi->has_add_value) {
|
374
|
-
call_add_value(pi->handler,
|
375
|
-
rb_funcall(rb_cObject, oj_bigdecimal_id, 1, rb_str_new2(start)),
|
376
|
-
key);
|
366
|
+
call_add_value(pi->handler, rb_funcall(rb_cObject, oj_bigdecimal_id, 1, rb_str_new2(start)), key);
|
377
367
|
}
|
378
368
|
*pi->s = c;
|
379
369
|
} else {
|
@@ -505,9 +495,9 @@ static char *unicode_to_chars(ParseInfo pi, char *t, uint32_t code) {
|
|
505
495
|
* reached again. Do not read the character after the terminating quote.
|
506
496
|
*/
|
507
497
|
static char *read_quoted_value(ParseInfo pi) {
|
508
|
-
char
|
509
|
-
char
|
510
|
-
char
|
498
|
+
char *value = 0;
|
499
|
+
char *h = pi->s; /* head */
|
500
|
+
char *t = h; /* tail */
|
511
501
|
uint32_t code;
|
512
502
|
|
513
503
|
h++; /* skip quote character */
|
@@ -588,15 +578,13 @@ static void saj_parse(VALUE handler, char *json) {
|
|
588
578
|
pi.str = json;
|
589
579
|
pi.s = json;
|
590
580
|
#if IS_WINDOWS
|
591
|
-
pi.stack_min = (void *)((char *)&obj -
|
592
|
-
(512 * 1024)); /* assume a 1M stack and give half to ruby */
|
581
|
+
pi.stack_min = (void *)((char *)&obj - (512L * 1024L)); /* assume a 1M stack and give half to ruby */
|
593
582
|
#else
|
594
583
|
{
|
595
584
|
struct rlimit lim;
|
596
585
|
|
597
586
|
if (0 == getrlimit(RLIMIT_STACK, &lim) && RLIM_INFINITY != lim.rlim_cur) {
|
598
|
-
pi.stack_min = (void *)((char *)&obj - (lim.rlim_cur / 4 *
|
599
|
-
3)); /* let 3/4ths of the stack be used only */
|
587
|
+
pi.stack_min = (void *)((char *)&obj - (lim.rlim_cur / 4 * 3)); /* let 3/4ths of the stack be used only */
|
600
588
|
} else {
|
601
589
|
pi.stack_min = 0; /* indicates not to check stack limit */
|
602
590
|
}
|
@@ -633,7 +621,7 @@ static void saj_parse(VALUE handler, char *json) {
|
|
633
621
|
*/
|
634
622
|
VALUE
|
635
623
|
oj_saj_parse(int argc, VALUE *argv, VALUE self) {
|
636
|
-
char
|
624
|
+
char *json = 0;
|
637
625
|
size_t len = 0;
|
638
626
|
VALUE input = argv[1];
|
639
627
|
|
data/ext/oj/stream_writer.c
CHANGED
@@ -315,8 +315,10 @@ static VALUE stream_writer_flush(VALUE self) {
|
|
315
315
|
* will create that element in the JSON document and subsequent pushes will add
|
316
316
|
* the elements to that array or object until a pop() is called.
|
317
317
|
*/
|
318
|
-
void oj_stream_writer_init() {
|
318
|
+
void oj_stream_writer_init(void) {
|
319
319
|
oj_stream_writer_class = rb_define_class_under(Oj, "StreamWriter", rb_cObject);
|
320
|
+
rb_gc_register_address(&oj_stream_writer_class);
|
321
|
+
rb_undef_alloc_func(oj_stream_writer_class);
|
320
322
|
rb_define_module_function(oj_stream_writer_class, "new", stream_writer_new, -1);
|
321
323
|
rb_define_method(oj_stream_writer_class, "push_key", stream_writer_push_key, 1);
|
322
324
|
rb_define_method(oj_stream_writer_class, "push_object", stream_writer_push_object, -1);
|
data/ext/oj/string_writer.c
CHANGED
@@ -53,10 +53,13 @@ void oj_str_writer_init(StrWriter sw, int buf_size) {
|
|
53
53
|
} else if (buf_size < 1024) {
|
54
54
|
buf_size = 1024;
|
55
55
|
}
|
56
|
+
// Must be allocated. Using the out.stack_buffer results in double frees
|
57
|
+
// and I haven't figured out why yet.
|
56
58
|
sw->out.buf = ALLOC_N(char, buf_size);
|
57
|
-
sw->out.end = sw->out.buf + buf_size - 10;
|
58
|
-
sw->out.allocated = true;
|
59
59
|
sw->out.cur = sw->out.buf;
|
60
|
+
sw->out.end = sw->out.buf + buf_size - BUFFER_EXTRA;
|
61
|
+
sw->out.allocated = true;
|
62
|
+
|
60
63
|
*sw->out.cur = '\0';
|
61
64
|
sw->out.circ_cache = NULL;
|
62
65
|
sw->out.circ_cnt = 0;
|
@@ -229,7 +232,9 @@ static void str_writer_free(void *ptr) {
|
|
229
232
|
return;
|
230
233
|
}
|
231
234
|
sw = (StrWriter)ptr;
|
232
|
-
|
235
|
+
|
236
|
+
oj_out_free(&sw->out);
|
237
|
+
|
233
238
|
xfree(sw->types);
|
234
239
|
xfree(ptr);
|
235
240
|
}
|
@@ -449,7 +454,7 @@ static VALUE str_writer_to_s(VALUE self) {
|
|
449
454
|
* Returns the contents of the writer as a JSON element. If called from inside
|
450
455
|
* an array or hash by Oj the raw buffer will be used othersize a more
|
451
456
|
* inefficient parse of the contents and a return of the result is
|
452
|
-
* completed. The parse uses the
|
457
|
+
* completed. The parse uses the strict mode.
|
453
458
|
*
|
454
459
|
* *return* [_Hash_|_Array_|_String_|_Integer_|_Float_|_True_|_False_|_nil|)
|
455
460
|
*/
|
@@ -469,8 +474,10 @@ static VALUE str_writer_as_json(VALUE self) {
|
|
469
474
|
* calling to_s() will return the JSON document. Note that calling to_s() before
|
470
475
|
* construction is complete will return the document in it's current state.
|
471
476
|
*/
|
472
|
-
void oj_string_writer_init() {
|
477
|
+
void oj_string_writer_init(void) {
|
473
478
|
oj_string_writer_class = rb_define_class_under(Oj, "StringWriter", rb_cObject);
|
479
|
+
rb_gc_register_address(&oj_string_writer_class);
|
480
|
+
rb_undef_alloc_func(oj_string_writer_class);
|
474
481
|
rb_define_module_function(oj_string_writer_class, "new", str_writer_new, -1);
|
475
482
|
rb_define_method(oj_string_writer_class, "push_key", str_writer_push_key, 1);
|
476
483
|
rb_define_method(oj_string_writer_class, "push_object", str_writer_push_object, -1);
|
data/ext/oj/wab.c
CHANGED
@@ -35,7 +35,7 @@ static VALUE uri_http_clas = Qundef;
|
|
35
35
|
|
36
36
|
///// dump functions /////
|
37
37
|
|
38
|
-
static VALUE resolve_wab_uuid_class() {
|
38
|
+
static VALUE resolve_wab_uuid_class(void) {
|
39
39
|
if (Qundef == wab_uuid_clas) {
|
40
40
|
volatile VALUE wab_module;
|
41
41
|
|
@@ -50,7 +50,7 @@ static VALUE resolve_wab_uuid_class() {
|
|
50
50
|
return wab_uuid_clas;
|
51
51
|
}
|
52
52
|
|
53
|
-
static VALUE resolve_uri_class() {
|
53
|
+
static VALUE resolve_uri_class(void) {
|
54
54
|
if (Qundef == uri_clas) {
|
55
55
|
uri_clas = Qnil;
|
56
56
|
if (rb_const_defined_at(rb_cObject, rb_intern("URI"))) {
|
@@ -60,7 +60,7 @@ static VALUE resolve_uri_class() {
|
|
60
60
|
return uri_clas;
|
61
61
|
}
|
62
62
|
|
63
|
-
static VALUE resolve_uri_http_class() {
|
63
|
+
static VALUE resolve_uri_http_class(void) {
|
64
64
|
if (Qundef == uri_http_clas) {
|
65
65
|
volatile VALUE uri_module;
|
66
66
|
|
@@ -124,11 +124,11 @@ static void dump_array(VALUE a, int depth, Out out, bool as_ok) {
|
|
124
124
|
*out->cur++ = ']';
|
125
125
|
} else {
|
126
126
|
size = d2 * out->indent + 2;
|
127
|
+
assure_size(out, size * cnt);
|
127
128
|
cnt--;
|
128
129
|
for (i = 0; i <= cnt; i++) {
|
129
|
-
assure_size(out, size);
|
130
130
|
fill_indent(out, d2);
|
131
|
-
oj_dump_wab_val(
|
131
|
+
oj_dump_wab_val(RARRAY_AREF(a, i), d2, out);
|
132
132
|
if (i < cnt) {
|
133
133
|
*out->cur++ = ',';
|
134
134
|
}
|
@@ -201,12 +201,12 @@ static void dump_time(VALUE obj, Out out) {
|
|
201
201
|
sec = ts.tv_sec;
|
202
202
|
nsec = ts.tv_nsec;
|
203
203
|
} else {
|
204
|
-
sec =
|
205
|
-
nsec =
|
204
|
+
sec = NUM2LL(rb_funcall2(obj, oj_tv_sec_id, 0, 0));
|
205
|
+
nsec = NUM2LL(rb_funcall2(obj, oj_tv_nsec_id, 0, 0));
|
206
206
|
}
|
207
207
|
#else
|
208
|
-
sec =
|
209
|
-
nsec =
|
208
|
+
sec = NUM2LL(rb_funcall2(obj, oj_tv_sec_id, 0, 0));
|
209
|
+
nsec = NUM2LL(rb_funcall2(obj, oj_tv_nsec_id, 0, 0));
|
210
210
|
#endif
|
211
211
|
|
212
212
|
assure_size(out, 36);
|