oj 3.13.9 → 3.13.12
Sign up to get free protection for your applications and to get access to all the features.
- 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);
|