oj 3.11.5 → 3.16.5
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 +1421 -0
- data/README.md +19 -5
- data/RELEASE_NOTES.md +61 -0
- data/ext/oj/buf.h +20 -6
- data/ext/oj/cache.c +329 -0
- data/ext/oj/cache.h +22 -0
- data/ext/oj/cache8.c +10 -9
- data/ext/oj/circarray.c +8 -6
- data/ext/oj/circarray.h +2 -2
- data/ext/oj/code.c +19 -33
- data/ext/oj/code.h +2 -2
- data/ext/oj/compat.c +27 -77
- data/ext/oj/custom.c +86 -179
- data/ext/oj/debug.c +126 -0
- data/ext/oj/dump.c +256 -249
- data/ext/oj/dump.h +26 -12
- data/ext/oj/dump_compat.c +565 -642
- data/ext/oj/dump_leaf.c +17 -63
- data/ext/oj/dump_object.c +65 -187
- data/ext/oj/dump_strict.c +27 -51
- data/ext/oj/encoder.c +43 -0
- data/ext/oj/err.c +2 -13
- data/ext/oj/err.h +24 -8
- data/ext/oj/extconf.rb +21 -6
- data/ext/oj/fast.c +149 -149
- data/ext/oj/intern.c +313 -0
- data/ext/oj/intern.h +22 -0
- data/ext/oj/mem.c +318 -0
- data/ext/oj/mem.h +53 -0
- data/ext/oj/mimic_json.c +121 -106
- data/ext/oj/object.c +85 -162
- data/ext/oj/odd.c +89 -67
- data/ext/oj/odd.h +15 -15
- data/ext/oj/oj.c +542 -411
- data/ext/oj/oj.h +99 -73
- data/ext/oj/parse.c +175 -187
- data/ext/oj/parse.h +26 -24
- data/ext/oj/parser.c +1600 -0
- data/ext/oj/parser.h +101 -0
- data/ext/oj/rails.c +112 -159
- data/ext/oj/rails.h +1 -1
- data/ext/oj/reader.c +11 -14
- data/ext/oj/reader.h +4 -2
- data/ext/oj/resolve.c +5 -24
- data/ext/oj/rxclass.c +7 -6
- data/ext/oj/rxclass.h +1 -1
- data/ext/oj/saj.c +22 -33
- data/ext/oj/saj2.c +584 -0
- data/ext/oj/saj2.h +23 -0
- data/ext/oj/scp.c +5 -28
- data/ext/oj/sparse.c +28 -72
- data/ext/oj/stream_writer.c +50 -40
- data/ext/oj/strict.c +56 -61
- data/ext/oj/string_writer.c +72 -39
- data/ext/oj/trace.h +31 -4
- data/ext/oj/usual.c +1218 -0
- data/ext/oj/usual.h +69 -0
- data/ext/oj/util.h +1 -1
- data/ext/oj/val_stack.c +14 -3
- data/ext/oj/val_stack.h +8 -7
- data/ext/oj/validate.c +46 -0
- data/ext/oj/wab.c +63 -88
- 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 +1 -2
- data/lib/oj/json.rb +162 -150
- data/lib/oj/mimic.rb +9 -7
- data/lib/oj/saj.rb +20 -6
- data/lib/oj/schandler.rb +5 -4
- data/lib/oj/state.rb +12 -8
- data/lib/oj/version.rb +1 -2
- data/lib/oj.rb +2 -0
- data/pages/Compatibility.md +1 -1
- data/pages/InstallOptions.md +20 -0
- data/pages/JsonGem.md +15 -0
- data/pages/Modes.md +8 -3
- data/pages/Options.md +43 -5
- data/pages/Parser.md +309 -0
- data/pages/Rails.md +14 -2
- 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/{activesupport5 → activesupport7}/abstract_unit.rb +16 -12
- data/test/{activesupport5 → activesupport7}/decoding_test.rb +2 -10
- data/test/{activesupport5 → activesupport7}/encoding_test.rb +86 -50
- data/test/{activesupport5 → activesupport7}/encoding_test_cases.rb +6 -0
- data/test/{activesupport5 → activesupport7}/time_zone_test_helpers.rb +8 -0
- data/test/files.rb +15 -15
- data/test/foo.rb +16 -45
- data/test/helper.rb +11 -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 +56 -38
- data/test/json_gem/json_generic_object_test.rb +11 -11
- data/test/json_gem/json_parser_test.rb +54 -47
- data/test/json_gem/json_string_matching_test.rb +9 -9
- data/test/json_gem/test_helper.rb +7 -3
- data/test/mem.rb +34 -0
- data/test/perf.rb +22 -27
- data/test/perf_compat.rb +31 -33
- data/test/perf_dump.rb +50 -0
- 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 +59 -0
- data/test/perf_parser.rb +183 -0
- data/test/perf_saj.rb +46 -54
- data/test/perf_scp.rb +58 -69
- data/test/perf_simple.rb +41 -39
- data/test/perf_strict.rb +74 -82
- 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 +95 -43
- data/test/test_custom.rb +73 -51
- data/test/test_debian.rb +7 -10
- data/test/test_fast.rb +135 -79
- data/test/test_file.rb +41 -30
- data/test/test_gc.rb +16 -5
- data/test/test_generate.rb +5 -5
- data/test/test_hash.rb +5 -5
- data/test/test_integer_range.rb +9 -9
- data/test/test_null.rb +20 -20
- data/test/test_object.rb +99 -96
- data/test/test_parser.rb +11 -0
- data/test/test_parser_debug.rb +27 -0
- data/test/test_parser_saj.rb +337 -0
- data/test/test_parser_usual.rb +251 -0
- data/test/test_rails.rb +2 -2
- data/test/test_saj.rb +10 -8
- data/test/test_scp.rb +37 -39
- data/test/test_strict.rb +40 -32
- data/test/test_various.rb +165 -84
- data/test/test_wab.rb +48 -44
- data/test/test_writer.rb +47 -47
- data/test/tests.rb +13 -5
- data/test/tests_mimic.rb +12 -3
- data/test/tests_mimic_addition.rb +12 -3
- metadata +74 -128
- data/ext/oj/hash.c +0 -131
- data/ext/oj/hash.h +0 -19
- data/ext/oj/hash_test.c +0 -491
- 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/test_helper.rb +0 -72
- data/test/bar.rb +0 -35
- data/test/baz.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
|
@@ -157,9 +158,9 @@ static void dump_struct(VALUE obj, int depth, Out out, bool as_ok) {
|
|
157
158
|
assure_size(out, 2);
|
158
159
|
*out->cur++ = '{';
|
159
160
|
for (i = 0; i < cnt; i++) {
|
160
|
-
volatile VALUE s =
|
161
|
+
volatile VALUE s = rb_sym2str(RARRAY_AREF(ma, i));
|
161
162
|
|
162
|
-
name =
|
163
|
+
name = RSTRING_PTR(s);
|
163
164
|
len = (int)RSTRING_LEN(s);
|
164
165
|
assure_size(out, size + sep_len + 6);
|
165
166
|
if (0 < i) {
|
@@ -167,17 +168,14 @@ static void dump_struct(VALUE obj, int depth, Out out, bool as_ok) {
|
|
167
168
|
}
|
168
169
|
fill_indent(out, d3);
|
169
170
|
*out->cur++ = '"';
|
170
|
-
|
171
|
-
out->cur += len;
|
171
|
+
APPEND_CHARS(out->cur, name, len);
|
172
172
|
*out->cur++ = '"';
|
173
173
|
if (0 < out->opts->dump_opts.before_size) {
|
174
|
-
|
175
|
-
out->cur += out->opts->dump_opts.before_size;
|
174
|
+
APPEND_CHARS(out->cur, out->opts->dump_opts.before_sep, out->opts->dump_opts.before_size);
|
176
175
|
}
|
177
176
|
*out->cur++ = ':';
|
178
177
|
if (0 < out->opts->dump_opts.after_size) {
|
179
|
-
|
180
|
-
out->cur += out->opts->dump_opts.after_size;
|
178
|
+
APPEND_CHARS(out->cur, out->opts->dump_opts.after_sep, out->opts->dump_opts.after_size);
|
181
179
|
}
|
182
180
|
#ifdef RSTRUCT_LEN
|
183
181
|
v = RSTRUCT_GET(obj, i);
|
@@ -201,8 +199,8 @@ static void dump_enumerable(VALUE obj, int depth, Out out, bool as_ok) {
|
|
201
199
|
}
|
202
200
|
|
203
201
|
static void dump_bigdecimal(VALUE obj, int depth, Out out, bool as_ok) {
|
204
|
-
volatile VALUE rstr =
|
205
|
-
const char
|
202
|
+
volatile VALUE rstr = oj_safe_string_convert(obj);
|
203
|
+
const char *str = RSTRING_PTR(rstr);
|
206
204
|
|
207
205
|
if ('I' == *str || 'N' == *str || ('-' == *str && 'I' == str[1])) {
|
208
206
|
oj_dump_nil(Qnil, depth, out, false);
|
@@ -265,14 +263,7 @@ static void dump_sec_nano(VALUE obj, int64_t sec, long nsec, Out out) {
|
|
265
263
|
tzmin);
|
266
264
|
} else if (0 == out->opts->sec_prec) {
|
267
265
|
if (0 == tzsecs && rb_funcall2(obj, oj_utcq_id, 0, 0)) {
|
268
|
-
len = sprintf(buf,
|
269
|
-
"%04d-%02d-%02dT%02d:%02d:%02dZ",
|
270
|
-
ti.year,
|
271
|
-
ti.mon,
|
272
|
-
ti.day,
|
273
|
-
ti.hour,
|
274
|
-
ti.min,
|
275
|
-
ti.sec);
|
266
|
+
len = sprintf(buf, "%04d-%02d-%02dT%02d:%02d:%02dZ", ti.year, ti.mon, ti.day, ti.hour, ti.min, ti.sec);
|
276
267
|
} else {
|
277
268
|
len = sprintf(buf,
|
278
269
|
"%04d-%02d-%02dT%02d:%02d:%02d%c%02d:%02d",
|
@@ -303,18 +294,7 @@ static void dump_sec_nano(VALUE obj, int64_t sec, long nsec, Out out) {
|
|
303
294
|
format[32] = '0' + out->opts->sec_prec;
|
304
295
|
len -= 9 - out->opts->sec_prec;
|
305
296
|
}
|
306
|
-
len = sprintf(buf,
|
307
|
-
format,
|
308
|
-
ti.year,
|
309
|
-
ti.mon,
|
310
|
-
ti.day,
|
311
|
-
ti.hour,
|
312
|
-
ti.min,
|
313
|
-
ti.sec,
|
314
|
-
nsec,
|
315
|
-
tzsign,
|
316
|
-
tzhour,
|
317
|
-
tzmin);
|
297
|
+
len = sprintf(buf, format, ti.year, ti.mon, ti.day, ti.hour, ti.min, ti.sec, nsec, tzsign, tzhour, tzmin);
|
318
298
|
}
|
319
299
|
oj_dump_cstr(buf, len, 0, 0, out);
|
320
300
|
}
|
@@ -323,20 +303,15 @@ static void dump_time(VALUE obj, int depth, Out out, bool as_ok) {
|
|
323
303
|
long long sec;
|
324
304
|
long long nsec;
|
325
305
|
|
326
|
-
#ifdef HAVE_RB_TIME_TIMESPEC
|
327
306
|
if (16 <= sizeof(struct timespec)) {
|
328
307
|
struct timespec ts = rb_time_timespec(obj);
|
329
308
|
|
330
309
|
sec = (long long)ts.tv_sec;
|
331
310
|
nsec = ts.tv_nsec;
|
332
311
|
} else {
|
333
|
-
sec =
|
334
|
-
nsec =
|
312
|
+
sec = NUM2LL(rb_funcall2(obj, oj_tv_sec_id, 0, 0));
|
313
|
+
nsec = NUM2LL(rb_funcall2(obj, oj_tv_nsec_id, 0, 0));
|
335
314
|
}
|
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
315
|
dump_sec_nano(obj, sec, nsec, out);
|
341
316
|
}
|
342
317
|
|
@@ -345,17 +320,17 @@ static void dump_timewithzone(VALUE obj, int depth, Out out, bool as_ok) {
|
|
345
320
|
long long nsec = 0;
|
346
321
|
|
347
322
|
if (rb_respond_to(obj, oj_tv_nsec_id)) {
|
348
|
-
nsec =
|
323
|
+
nsec = NUM2LL(rb_funcall2(obj, oj_tv_nsec_id, 0, 0));
|
349
324
|
} else if (rb_respond_to(obj, oj_tv_usec_id)) {
|
350
|
-
nsec =
|
325
|
+
nsec = NUM2LL(rb_funcall2(obj, oj_tv_usec_id, 0, 0)) * 1000;
|
351
326
|
}
|
352
327
|
dump_sec_nano(obj, sec, nsec, out);
|
353
328
|
}
|
354
329
|
|
355
330
|
static void dump_to_s(VALUE obj, int depth, Out out, bool as_ok) {
|
356
|
-
volatile VALUE rstr =
|
331
|
+
volatile VALUE rstr = oj_safe_string_convert(obj);
|
357
332
|
|
358
|
-
oj_dump_cstr(
|
333
|
+
oj_dump_cstr(RSTRING_PTR(rstr), (int)RSTRING_LEN(rstr), 0, 0, out);
|
359
334
|
}
|
360
335
|
|
361
336
|
static ID parameters_id = 0;
|
@@ -363,7 +338,7 @@ static ID parameters_id = 0;
|
|
363
338
|
typedef struct _strLen {
|
364
339
|
const char *str;
|
365
340
|
int len;
|
366
|
-
} *
|
341
|
+
} *StrLen;
|
367
342
|
|
368
343
|
static void dump_actioncontroller_parameters(VALUE obj, int depth, Out out, bool as_ok) {
|
369
344
|
if (0 == parameters_id) {
|
@@ -381,11 +356,11 @@ static StrLen columns_array(VALUE rcols, int *ccnt) {
|
|
381
356
|
int cnt = (int)RARRAY_LEN(rcols);
|
382
357
|
|
383
358
|
*ccnt = cnt;
|
384
|
-
cols =
|
359
|
+
cols = OJ_R_ALLOC_N(struct _strLen, cnt);
|
385
360
|
for (i = 0, cp = cols; i < cnt; i++, cp++) {
|
386
|
-
v =
|
361
|
+
v = RARRAY_AREF(rcols, i);
|
387
362
|
if (T_STRING != rb_type(v)) {
|
388
|
-
v =
|
363
|
+
v = oj_safe_string_convert(v);
|
389
364
|
}
|
390
365
|
cp->str = StringValuePtr(v);
|
391
366
|
cp->len = (int)RSTRING_LEN(v);
|
@@ -405,14 +380,12 @@ static void dump_row(VALUE row, StrLen cols, int ccnt, int depth, Out out) {
|
|
405
380
|
assure_size(out, size);
|
406
381
|
if (out->opts->dump_opts.use) {
|
407
382
|
if (0 < out->opts->dump_opts.array_size) {
|
408
|
-
|
409
|
-
out->cur += out->opts->dump_opts.array_size;
|
383
|
+
APPEND_CHARS(out->cur, out->opts->dump_opts.array_nl, out->opts->dump_opts.array_size);
|
410
384
|
}
|
411
385
|
if (0 < out->opts->dump_opts.indent_size) {
|
412
386
|
int i;
|
413
387
|
for (i = d2; 0 < i; i--) {
|
414
|
-
|
415
|
-
out->cur += out->opts->dump_opts.indent_size;
|
388
|
+
APPEND_CHARS(out->cur, out->opts->dump_opts.indent_str, out->opts->dump_opts.indent_size);
|
416
389
|
}
|
417
390
|
}
|
418
391
|
} else {
|
@@ -420,7 +393,7 @@ static void dump_row(VALUE row, StrLen cols, int ccnt, int depth, Out out) {
|
|
420
393
|
}
|
421
394
|
oj_dump_cstr(cols->str, cols->len, 0, 0, out);
|
422
395
|
*out->cur++ = ':';
|
423
|
-
dump_rails_val(
|
396
|
+
dump_rails_val(RARRAY_AREF(row, i), depth, out, true);
|
424
397
|
if (i < ccnt - 1) {
|
425
398
|
*out->cur++ = ',';
|
426
399
|
}
|
@@ -429,15 +402,13 @@ static void dump_row(VALUE row, StrLen cols, int ccnt, int depth, Out out) {
|
|
429
402
|
assure_size(out, size);
|
430
403
|
if (out->opts->dump_opts.use) {
|
431
404
|
if (0 < out->opts->dump_opts.array_size) {
|
432
|
-
|
433
|
-
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);
|
434
406
|
}
|
435
407
|
if (0 < out->opts->dump_opts.indent_size) {
|
436
408
|
int i;
|
437
409
|
|
438
410
|
for (i = depth; 0 < i; i--) {
|
439
|
-
|
440
|
-
out->cur += out->opts->dump_opts.indent_size;
|
411
|
+
APPEND_CHARS(out->cur, out->opts->dump_opts.indent_str, out->opts->dump_opts.indent_size);
|
441
412
|
}
|
442
413
|
}
|
443
414
|
} else {
|
@@ -477,38 +448,34 @@ static void dump_activerecord_result(VALUE obj, int depth, Out out, bool as_ok)
|
|
477
448
|
assure_size(out, size);
|
478
449
|
if (out->opts->dump_opts.use) {
|
479
450
|
if (0 < out->opts->dump_opts.array_size) {
|
480
|
-
|
481
|
-
out->cur += out->opts->dump_opts.array_size;
|
451
|
+
APPEND_CHARS(out->cur, out->opts->dump_opts.array_nl, out->opts->dump_opts.array_size);
|
482
452
|
}
|
483
453
|
if (0 < out->opts->dump_opts.indent_size) {
|
484
454
|
int i;
|
485
455
|
for (i = d2; 0 < i; i--) {
|
486
|
-
|
487
|
-
out->cur += out->opts->dump_opts.indent_size;
|
456
|
+
APPEND_CHARS(out->cur, out->opts->dump_opts.indent_str, out->opts->dump_opts.indent_size);
|
488
457
|
}
|
489
458
|
}
|
490
459
|
} else {
|
491
460
|
fill_indent(out, d2);
|
492
461
|
}
|
493
|
-
dump_row(
|
462
|
+
dump_row(RARRAY_AREF(rows, i), cols, ccnt, d2, out);
|
494
463
|
if (i < rcnt - 1) {
|
495
464
|
*out->cur++ = ',';
|
496
465
|
}
|
497
466
|
}
|
498
|
-
|
467
|
+
OJ_R_FREE(cols);
|
499
468
|
size = depth * out->indent + 1;
|
500
469
|
assure_size(out, size);
|
501
470
|
if (out->opts->dump_opts.use) {
|
502
471
|
if (0 < out->opts->dump_opts.array_size) {
|
503
|
-
|
504
|
-
out->cur += out->opts->dump_opts.array_size;
|
472
|
+
APPEND_CHARS(out->cur, out->opts->dump_opts.array_nl, out->opts->dump_opts.array_size);
|
505
473
|
}
|
506
474
|
if (0 < out->opts->dump_opts.indent_size) {
|
507
475
|
int i;
|
508
476
|
|
509
477
|
for (i = depth; 0 < i; i--) {
|
510
|
-
|
511
|
-
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);
|
512
479
|
}
|
513
480
|
}
|
514
481
|
} else {
|
@@ -520,7 +487,7 @@ static void dump_activerecord_result(VALUE obj, int depth, Out out, bool as_ok)
|
|
520
487
|
typedef struct _namedFunc {
|
521
488
|
const char *name;
|
522
489
|
DumpFunc func;
|
523
|
-
} *
|
490
|
+
} *NamedFunc;
|
524
491
|
|
525
492
|
static void dump_as_string(VALUE obj, int depth, Out out, bool as_ok) {
|
526
493
|
if (oj_code_dump(oj_compat_codes, obj, depth, out)) {
|
@@ -533,9 +500,7 @@ static void dump_as_string(VALUE obj, int depth, Out out, bool as_ok) {
|
|
533
500
|
static void dump_as_json(VALUE obj, int depth, Out out, bool as_ok) {
|
534
501
|
volatile VALUE ja;
|
535
502
|
|
536
|
-
|
537
|
-
oj_trace("as_json", obj, __FILE__, __LINE__, depth + 1, TraceRubyIn);
|
538
|
-
}
|
503
|
+
TRACE(out->opts->trace, "as_json", obj, depth + 1, TraceRubyIn);
|
539
504
|
// Some classes elect to not take an options argument so check the arity
|
540
505
|
// of as_json.
|
541
506
|
if (0 == rb_obj_method_arity(obj, oj_as_json_id)) {
|
@@ -543,9 +508,7 @@ static void dump_as_json(VALUE obj, int depth, Out out, bool as_ok) {
|
|
543
508
|
} else {
|
544
509
|
ja = rb_funcall2(obj, oj_as_json_id, out->argc, out->argv);
|
545
510
|
}
|
546
|
-
|
547
|
-
oj_trace("as_json", obj, __FILE__, __LINE__, depth + 1, TraceRubyOut);
|
548
|
-
}
|
511
|
+
TRACE(out->opts->trace, "as_json", obj, depth + 1, TraceRubyOut);
|
549
512
|
|
550
513
|
out->argc = 0;
|
551
514
|
if (ja == obj || !as_ok) {
|
@@ -603,11 +566,11 @@ static ROpt create_opt(ROptTable rot, VALUE clas) {
|
|
603
566
|
rot->len++;
|
604
567
|
if (NULL == rot->table) {
|
605
568
|
rot->alen = 256;
|
606
|
-
rot->table =
|
569
|
+
rot->table = OJ_R_ALLOC_N(struct _rOpt, rot->alen);
|
607
570
|
memset(rot->table, 0, sizeof(struct _rOpt) * rot->alen);
|
608
571
|
} else if (rot->alen <= rot->len) {
|
609
572
|
rot->alen *= 2;
|
610
|
-
|
573
|
+
OJ_R_REALLOC_N(rot->table, struct _rOpt, rot->alen);
|
611
574
|
memset(rot->table + olen, 0, sizeof(struct _rOpt) * olen);
|
612
575
|
}
|
613
576
|
if (0 == olen) {
|
@@ -660,9 +623,9 @@ static void encoder_free(void *ptr) {
|
|
660
623
|
Encoder e = (Encoder)ptr;
|
661
624
|
|
662
625
|
if (NULL != e->ropts.table) {
|
663
|
-
|
626
|
+
OJ_R_FREE(e->ropts.table);
|
664
627
|
}
|
665
|
-
|
628
|
+
OJ_R_FREE(ptr);
|
666
629
|
}
|
667
630
|
}
|
668
631
|
|
@@ -676,6 +639,17 @@ static void encoder_mark(void *ptr) {
|
|
676
639
|
}
|
677
640
|
}
|
678
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
|
+
|
679
653
|
/* Document-method: new
|
680
654
|
* call-seq: new(options=nil)
|
681
655
|
*
|
@@ -683,7 +657,7 @@ static void encoder_mark(void *ptr) {
|
|
683
657
|
* - *options* [_Hash_] formatting options
|
684
658
|
*/
|
685
659
|
static VALUE encoder_new(int argc, VALUE *argv, VALUE self) {
|
686
|
-
Encoder e =
|
660
|
+
Encoder e = OJ_R_ALLOC(struct _encoder);
|
687
661
|
|
688
662
|
e->opts = oj_default_options;
|
689
663
|
e->arg = Qnil;
|
@@ -693,14 +667,14 @@ static VALUE encoder_new(int argc, VALUE *argv, VALUE self) {
|
|
693
667
|
oj_parse_options(*argv, &e->opts);
|
694
668
|
e->arg = *argv;
|
695
669
|
}
|
696
|
-
return
|
670
|
+
return TypedData_Wrap_Struct(encoder_class, &oj_encoder_type, e);
|
697
671
|
}
|
698
672
|
|
699
673
|
static VALUE resolve_classpath(const char *name) {
|
700
674
|
char class_name[1024];
|
701
675
|
VALUE clas;
|
702
|
-
char
|
703
|
-
char
|
676
|
+
char *end = class_name + sizeof(class_name) - 1;
|
677
|
+
char *s;
|
704
678
|
const char *n = name;
|
705
679
|
ID cid;
|
706
680
|
|
@@ -766,8 +740,7 @@ static void optimize(int argc, VALUE *argv, ROptTable rot, bool on) {
|
|
766
740
|
oj_rails_float_opt = on;
|
767
741
|
} else if (oj_string_writer_class == *argv) {
|
768
742
|
string_writer_optimized = on;
|
769
|
-
} else if (NULL != (ro = oj_rails_get_opt(rot, *argv)) ||
|
770
|
-
NULL != (ro = create_opt(rot, *argv))) {
|
743
|
+
} else if (NULL != (ro = oj_rails_get_opt(rot, *argv)) || NULL != (ro = create_opt(rot, *argv))) {
|
771
744
|
ro->on = on;
|
772
745
|
}
|
773
746
|
}
|
@@ -786,7 +759,8 @@ static void optimize(int argc, VALUE *argv, ROptTable rot, bool on) {
|
|
786
759
|
* - *classes* [_Class_] a list of classes to optimize
|
787
760
|
*/
|
788
761
|
static VALUE encoder_optimize(int argc, VALUE *argv, VALUE self) {
|
789
|
-
Encoder e
|
762
|
+
Encoder e;
|
763
|
+
TypedData_Get_Struct(self, struct _encoder, &oj_encoder_type, e);
|
790
764
|
|
791
765
|
optimize(argc, argv, &e->ropts, true);
|
792
766
|
|
@@ -828,6 +802,7 @@ rails_mimic_json(VALUE self) {
|
|
828
802
|
json = rb_define_module("JSON");
|
829
803
|
}
|
830
804
|
oj_mimic_json_methods(json);
|
805
|
+
// Setting the default mode breaks the prmoise in the docs not to.
|
831
806
|
// oj_default_options.mode = RailsMode;
|
832
807
|
|
833
808
|
return Qnil;
|
@@ -841,7 +816,8 @@ rails_mimic_json(VALUE self) {
|
|
841
816
|
* - *classes* [_Class_] a list of classes to deoptimize
|
842
817
|
*/
|
843
818
|
static VALUE encoder_deoptimize(int argc, VALUE *argv, VALUE self) {
|
844
|
-
Encoder e
|
819
|
+
Encoder e;
|
820
|
+
TypedData_Get_Struct(self, struct _encoder, &oj_encoder_type, e);
|
845
821
|
|
846
822
|
optimize(argc, argv, &e->ropts, false);
|
847
823
|
|
@@ -870,8 +846,11 @@ static VALUE rails_deoptimize(int argc, VALUE *argv, VALUE self) {
|
|
870
846
|
* @return true if the class is being optimized for rails and false otherwise
|
871
847
|
*/
|
872
848
|
static VALUE encoder_optimized(VALUE self, VALUE clas) {
|
873
|
-
Encoder e
|
874
|
-
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);
|
875
854
|
|
876
855
|
if (NULL == ro) {
|
877
856
|
return Qfalse;
|
@@ -896,7 +875,7 @@ static VALUE rails_optimized(VALUE self, VALUE clas) {
|
|
896
875
|
typedef struct _oo {
|
897
876
|
Out out;
|
898
877
|
VALUE obj;
|
899
|
-
} *
|
878
|
+
} *OO;
|
900
879
|
|
901
880
|
static VALUE protect_dump(VALUE ov) {
|
902
881
|
OO oo = (OO)ov;
|
@@ -907,7 +886,6 @@ static VALUE protect_dump(VALUE ov) {
|
|
907
886
|
}
|
908
887
|
|
909
888
|
static VALUE encode(VALUE obj, ROptTable ropts, Options opts, int argc, VALUE *argv) {
|
910
|
-
char buf[4096];
|
911
889
|
struct _out out;
|
912
890
|
struct _options copts = *opts;
|
913
891
|
volatile VALUE rstr = Qnil;
|
@@ -924,19 +902,18 @@ static VALUE encode(VALUE obj, ROptTable ropts, Options opts, int argc, VALUE *a
|
|
924
902
|
} else {
|
925
903
|
copts.escape_mode = RailsEsc;
|
926
904
|
}
|
927
|
-
|
928
|
-
out
|
929
|
-
|
930
|
-
out.omit_nil
|
931
|
-
out.
|
932
|
-
out.
|
933
|
-
out.
|
934
|
-
out.
|
935
|
-
out.
|
936
|
-
out.
|
937
|
-
out.
|
938
|
-
out.
|
939
|
-
out.ropts = ropts;
|
905
|
+
|
906
|
+
oj_out_init(&out);
|
907
|
+
|
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;
|
940
917
|
if (Yes == copts.circular) {
|
941
918
|
oj_cache8_new(&out.circ_cache);
|
942
919
|
}
|
@@ -962,9 +939,9 @@ static VALUE encode(VALUE obj, ROptTable ropts, Options opts, int argc, VALUE *a
|
|
962
939
|
if (Yes == copts.circular) {
|
963
940
|
oj_cache8_delete(out.circ_cache);
|
964
941
|
}
|
965
|
-
|
966
|
-
|
967
|
-
|
942
|
+
|
943
|
+
oj_out_free(&out);
|
944
|
+
|
968
945
|
if (0 != line) {
|
969
946
|
rb_jump_tag(line);
|
970
947
|
}
|
@@ -979,7 +956,8 @@ static VALUE encode(VALUE obj, ROptTable ropts, Options opts, int argc, VALUE *a
|
|
979
956
|
* Returns encoded object as a JSON string.
|
980
957
|
*/
|
981
958
|
static VALUE encoder_encode(VALUE self, VALUE obj) {
|
982
|
-
Encoder e
|
959
|
+
Encoder e;
|
960
|
+
TypedData_Get_Struct(self, struct _encoder, &oj_encoder_type, e);
|
983
961
|
|
984
962
|
if (Qnil != e->arg) {
|
985
963
|
VALUE argv[1] = {e->arg};
|
@@ -1081,28 +1059,16 @@ static VALUE rails_set_encoder(VALUE self) {
|
|
1081
1059
|
verbose = rb_gv_get("$VERBOSE");
|
1082
1060
|
rb_gv_set("$VERBOSE", Qfalse);
|
1083
1061
|
rb_undef_method(encoding, "use_standard_json_time_format=");
|
1084
|
-
rb_define_module_function(encoding,
|
1085
|
-
"use_standard_json_time_format=",
|
1086
|
-
rails_use_standard_json_time_format,
|
1087
|
-
1);
|
1062
|
+
rb_define_module_function(encoding, "use_standard_json_time_format=", rails_use_standard_json_time_format, 1);
|
1088
1063
|
rb_undef_method(encoding, "use_standard_json_time_format");
|
1089
|
-
rb_define_module_function(encoding,
|
1090
|
-
"use_standard_json_time_format",
|
1091
|
-
rails_use_standard_json_time_format_get,
|
1092
|
-
0);
|
1064
|
+
rb_define_module_function(encoding, "use_standard_json_time_format", rails_use_standard_json_time_format_get, 0);
|
1093
1065
|
|
1094
1066
|
pv = rb_iv_get(encoding, "@escape_html_entities_in_json");
|
1095
1067
|
escape_html = Qtrue == pv;
|
1096
1068
|
rb_undef_method(encoding, "escape_html_entities_in_json=");
|
1097
|
-
rb_define_module_function(encoding,
|
1098
|
-
"escape_html_entities_in_json=",
|
1099
|
-
rails_escape_html_entities_in_json,
|
1100
|
-
1);
|
1069
|
+
rb_define_module_function(encoding, "escape_html_entities_in_json=", rails_escape_html_entities_in_json, 1);
|
1101
1070
|
rb_undef_method(encoding, "escape_html_entities_in_json");
|
1102
|
-
rb_define_module_function(encoding,
|
1103
|
-
"escape_html_entities_in_json",
|
1104
|
-
rails_escape_html_entities_in_json_get,
|
1105
|
-
0);
|
1071
|
+
rb_define_module_function(encoding, "escape_html_entities_in_json", rails_escape_html_entities_in_json_get, 0);
|
1106
1072
|
|
1107
1073
|
pv = rb_iv_get(encoding, "@time_precision");
|
1108
1074
|
oj_default_options.sec_prec = NUM2INT(pv);
|
@@ -1174,12 +1140,15 @@ oj_optimize_rails(VALUE self) {
|
|
1174
1140
|
*
|
1175
1141
|
* The Oj ActiveSupport compliant encoder.
|
1176
1142
|
*/
|
1177
|
-
void oj_mimic_rails_init() {
|
1143
|
+
void oj_mimic_rails_init(void) {
|
1178
1144
|
VALUE rails = rb_define_module_under(Oj, "Rails");
|
1179
1145
|
|
1180
1146
|
rb_define_module_function(rails, "encode", rails_encode, -1);
|
1181
1147
|
|
1182
1148
|
encoder_class = rb_define_class_under(rails, "Encoder", rb_cObject);
|
1149
|
+
rb_gc_register_address(&encoder_class);
|
1150
|
+
rb_undef_alloc_func(encoder_class);
|
1151
|
+
|
1183
1152
|
rb_define_module_function(encoder_class, "new", encoder_new, -1);
|
1184
1153
|
rb_define_module_function(rails, "optimize", rails_optimize, -1);
|
1185
1154
|
rb_define_module_function(rails, "deoptimize", rails_deoptimize, -1);
|
@@ -1201,7 +1170,7 @@ static void dump_to_hash(VALUE obj, int depth, Out out) {
|
|
1201
1170
|
|
1202
1171
|
static void dump_float(VALUE obj, int depth, Out out, bool as_ok) {
|
1203
1172
|
char buf[64];
|
1204
|
-
char
|
1173
|
+
char *b;
|
1205
1174
|
double d = rb_num2dbl(obj);
|
1206
1175
|
int cnt = 0;
|
1207
1176
|
|
@@ -1221,9 +1190,9 @@ static void dump_float(VALUE obj, int depth, Out out, bool as_ok) {
|
|
1221
1190
|
} else if (oj_rails_float_opt) {
|
1222
1191
|
cnt = oj_dump_float_printf(buf, sizeof(buf), obj, d, "%0.16g");
|
1223
1192
|
} else {
|
1224
|
-
volatile VALUE rstr =
|
1193
|
+
volatile VALUE rstr = oj_safe_string_convert(obj);
|
1225
1194
|
|
1226
|
-
strcpy(buf,
|
1195
|
+
strcpy(buf, RSTRING_PTR(rstr));
|
1227
1196
|
cnt = (int)RSTRING_LEN(rstr);
|
1228
1197
|
}
|
1229
1198
|
}
|
@@ -1262,25 +1231,23 @@ static void dump_array(VALUE a, int depth, Out out, bool as_ok) {
|
|
1262
1231
|
} else {
|
1263
1232
|
size = d2 * out->indent + 2;
|
1264
1233
|
}
|
1234
|
+
assure_size(out, size * cnt);
|
1265
1235
|
cnt--;
|
1266
1236
|
for (i = 0; i <= cnt; i++) {
|
1267
|
-
assure_size(out, size);
|
1268
1237
|
if (out->opts->dump_opts.use) {
|
1269
1238
|
if (0 < out->opts->dump_opts.array_size) {
|
1270
|
-
|
1271
|
-
out->cur += out->opts->dump_opts.array_size;
|
1239
|
+
APPEND_CHARS(out->cur, out->opts->dump_opts.array_nl, out->opts->dump_opts.array_size);
|
1272
1240
|
}
|
1273
1241
|
if (0 < out->opts->dump_opts.indent_size) {
|
1274
1242
|
int i;
|
1275
1243
|
for (i = d2; 0 < i; i--) {
|
1276
|
-
|
1277
|
-
out->cur += out->opts->dump_opts.indent_size;
|
1244
|
+
APPEND_CHARS(out->cur, out->opts->dump_opts.indent_str, out->opts->dump_opts.indent_size);
|
1278
1245
|
}
|
1279
1246
|
}
|
1280
1247
|
} else {
|
1281
1248
|
fill_indent(out, d2);
|
1282
1249
|
}
|
1283
|
-
dump_rails_val(
|
1250
|
+
dump_rails_val(RARRAY_AREF(a, i), d2, out, true);
|
1284
1251
|
if (i < cnt) {
|
1285
1252
|
*out->cur++ = ',';
|
1286
1253
|
}
|
@@ -1289,15 +1256,13 @@ static void dump_array(VALUE a, int depth, Out out, bool as_ok) {
|
|
1289
1256
|
assure_size(out, size);
|
1290
1257
|
if (out->opts->dump_opts.use) {
|
1291
1258
|
if (0 < out->opts->dump_opts.array_size) {
|
1292
|
-
|
1293
|
-
out->cur += out->opts->dump_opts.array_size;
|
1259
|
+
APPEND_CHARS(out->cur, out->opts->dump_opts.array_nl, out->opts->dump_opts.array_size);
|
1294
1260
|
}
|
1295
1261
|
if (0 < out->opts->dump_opts.indent_size) {
|
1296
1262
|
int i;
|
1297
1263
|
|
1298
1264
|
for (i = depth; 0 < i; i--) {
|
1299
|
-
|
1300
|
-
out->cur += out->opts->dump_opts.indent_size;
|
1265
|
+
APPEND_CHARS(out->cur, out->opts->dump_opts.indent_str, out->opts->dump_opts.indent_size);
|
1301
1266
|
}
|
1302
1267
|
}
|
1303
1268
|
} else {
|
@@ -1318,7 +1283,7 @@ static int hash_cb(VALUE key, VALUE value, VALUE ov) {
|
|
1318
1283
|
return ST_CONTINUE;
|
1319
1284
|
}
|
1320
1285
|
if (rtype != T_STRING && rtype != T_SYMBOL) {
|
1321
|
-
key =
|
1286
|
+
key = oj_safe_string_convert(key);
|
1322
1287
|
rtype = rb_type(key);
|
1323
1288
|
}
|
1324
1289
|
if (!out->opts->dump_opts.use) {
|
@@ -1335,14 +1300,12 @@ static int hash_cb(VALUE key, VALUE value, VALUE ov) {
|
|
1335
1300
|
size = depth * out->opts->dump_opts.indent_size + out->opts->dump_opts.hash_size + 1;
|
1336
1301
|
assure_size(out, size);
|
1337
1302
|
if (0 < out->opts->dump_opts.hash_size) {
|
1338
|
-
|
1339
|
-
out->cur += out->opts->dump_opts.hash_size;
|
1303
|
+
APPEND_CHARS(out->cur, out->opts->dump_opts.hash_nl, out->opts->dump_opts.hash_size);
|
1340
1304
|
}
|
1341
1305
|
if (0 < out->opts->dump_opts.indent_size) {
|
1342
1306
|
int i;
|
1343
1307
|
for (i = depth; 0 < i; i--) {
|
1344
|
-
|
1345
|
-
out->cur += out->opts->dump_opts.indent_size;
|
1308
|
+
APPEND_CHARS(out->cur, out->opts->dump_opts.indent_str, out->opts->dump_opts.indent_size);
|
1346
1309
|
}
|
1347
1310
|
}
|
1348
1311
|
if (rtype == T_STRING) {
|
@@ -1353,13 +1316,11 @@ static int hash_cb(VALUE key, VALUE value, VALUE ov) {
|
|
1353
1316
|
size = out->opts->dump_opts.before_size + out->opts->dump_opts.after_size + 2;
|
1354
1317
|
assure_size(out, size);
|
1355
1318
|
if (0 < out->opts->dump_opts.before_size) {
|
1356
|
-
|
1357
|
-
out->cur += out->opts->dump_opts.before_size;
|
1319
|
+
APPEND_CHARS(out->cur, out->opts->dump_opts.before_sep, out->opts->dump_opts.before_size);
|
1358
1320
|
}
|
1359
1321
|
*out->cur++ = ':';
|
1360
1322
|
if (0 < out->opts->dump_opts.after_size) {
|
1361
|
-
|
1362
|
-
out->cur += out->opts->dump_opts.after_size;
|
1323
|
+
APPEND_CHARS(out->cur, out->opts->dump_opts.after_sep, out->opts->dump_opts.after_size);
|
1363
1324
|
}
|
1364
1325
|
}
|
1365
1326
|
dump_rails_val(value, depth, out, true);
|
@@ -1402,15 +1363,13 @@ static void dump_hash(VALUE obj, int depth, Out out, bool as_ok) {
|
|
1402
1363
|
size = depth * out->opts->dump_opts.indent_size + out->opts->dump_opts.hash_size + 1;
|
1403
1364
|
assure_size(out, size);
|
1404
1365
|
if (0 < out->opts->dump_opts.hash_size) {
|
1405
|
-
|
1406
|
-
out->cur += out->opts->dump_opts.hash_size;
|
1366
|
+
APPEND_CHARS(out->cur, out->opts->dump_opts.hash_nl, out->opts->dump_opts.hash_size);
|
1407
1367
|
}
|
1408
1368
|
if (0 < out->opts->dump_opts.indent_size) {
|
1409
1369
|
int i;
|
1410
1370
|
|
1411
1371
|
for (i = depth; 0 < i; i--) {
|
1412
|
-
|
1413
|
-
out->cur += out->opts->dump_opts.indent_size;
|
1372
|
+
APPEND_CHARS(out->cur, out->opts->dump_opts.indent_str, out->opts->dump_opts.indent_size);
|
1414
1373
|
}
|
1415
1374
|
}
|
1416
1375
|
}
|
@@ -1487,9 +1446,7 @@ static DumpFunc rails_funcs[] = {
|
|
1487
1446
|
static void dump_rails_val(VALUE obj, int depth, Out out, bool as_ok) {
|
1488
1447
|
int type = rb_type(obj);
|
1489
1448
|
|
1490
|
-
|
1491
|
-
oj_trace("dump", obj, __FILE__, __LINE__, depth, TraceIn);
|
1492
|
-
}
|
1449
|
+
TRACE(out->opts->trace, "dump", obj, depth, TraceIn);
|
1493
1450
|
if (MAX_DEPTH < depth) {
|
1494
1451
|
rb_raise(rb_eNoMemError, "Too deeply nested.\n");
|
1495
1452
|
}
|
@@ -1498,16 +1455,12 @@ static void dump_rails_val(VALUE obj, int depth, Out out, bool as_ok) {
|
|
1498
1455
|
|
1499
1456
|
if (NULL != f) {
|
1500
1457
|
f(obj, depth, out, as_ok);
|
1501
|
-
|
1502
|
-
oj_trace("dump", obj, __FILE__, __LINE__, depth, TraceOut);
|
1503
|
-
}
|
1458
|
+
TRACE(out->opts->trace, "dump", obj, depth, TraceOut);
|
1504
1459
|
return;
|
1505
1460
|
}
|
1506
1461
|
}
|
1507
1462
|
oj_dump_nil(Qnil, depth, out, false);
|
1508
|
-
|
1509
|
-
oj_trace("dump", Qnil, __FILE__, __LINE__, depth, TraceOut);
|
1510
|
-
}
|
1463
|
+
TRACE(out->opts->trace, "dump", Qnil, depth, TraceOut);
|
1511
1464
|
}
|
1512
1465
|
|
1513
1466
|
void oj_dump_rails_val(VALUE obj, int depth, Out out) {
|