oj 3.13.9 → 3.16.1
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 +101 -0
- data/README.md +13 -2
- data/ext/oj/buf.h +11 -6
- data/ext/oj/cache.c +25 -24
- 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 +20 -60
- data/ext/oj/custom.c +76 -155
- data/ext/oj/debug.c +3 -9
- data/ext/oj/dump.c +203 -213
- 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 +59 -181
- data/ext/oj/dump_strict.c +24 -48
- data/ext/oj/encoder.c +43 -0
- data/ext/oj/err.c +2 -13
- data/ext/oj/err.h +9 -12
- data/ext/oj/extconf.rb +18 -7
- data/ext/oj/fast.c +83 -108
- data/ext/oj/intern.c +52 -50
- data/ext/oj/intern.h +4 -8
- data/ext/oj/mem.c +318 -0
- data/ext/oj/mem.h +53 -0
- data/ext/oj/mimic_json.c +104 -81
- data/ext/oj/object.c +50 -67
- data/ext/oj/odd.c +89 -67
- data/ext/oj/odd.h +15 -15
- data/ext/oj/oj.c +171 -106
- data/ext/oj/oj.h +96 -74
- data/ext/oj/parse.c +169 -189
- data/ext/oj/parse.h +23 -24
- data/ext/oj/parser.c +89 -34
- data/ext/oj/parser.h +20 -9
- data/ext/oj/rails.c +86 -151
- data/ext/oj/rails.h +1 -1
- data/ext/oj/reader.c +12 -15
- data/ext/oj/reader.h +4 -2
- data/ext/oj/resolve.c +3 -4
- data/ext/oj/rxclass.c +6 -5
- data/ext/oj/rxclass.h +1 -1
- data/ext/oj/saj.c +21 -32
- data/ext/oj/saj2.c +329 -93
- data/ext/oj/saj2.h +23 -0
- data/ext/oj/scp.c +3 -14
- data/ext/oj/sparse.c +26 -70
- data/ext/oj/stream_writer.c +12 -22
- data/ext/oj/strict.c +20 -52
- data/ext/oj/string_writer.c +21 -22
- data/ext/oj/trace.h +31 -4
- data/ext/oj/usual.c +105 -150
- data/ext/oj/usual.h +68 -0
- data/ext/oj/util.h +1 -1
- data/ext/oj/val_stack.c +1 -1
- data/ext/oj/val_stack.h +8 -7
- data/ext/oj/validate.c +21 -26
- data/ext/oj/wab.c +32 -69
- data/lib/oj/active_support_helper.rb +1 -3
- data/lib/oj/bag.rb +7 -1
- data/lib/oj/easy_hash.rb +4 -5
- data/lib/oj/error.rb +0 -1
- data/lib/oj/json.rb +162 -150
- data/lib/oj/mimic.rb +6 -2
- data/lib/oj/saj.rb +20 -6
- data/lib/oj/state.rb +9 -6
- 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 +6 -3
- data/pages/Options.md +10 -0
- data/pages/Rails.md +12 -0
- data/test/_test_active.rb +8 -9
- data/test/_test_active_mimic.rb +7 -8
- data/test/_test_mimic_rails.rb +17 -20
- data/test/activerecord/result_test.rb +5 -6
- data/test/{activesupport5 → activesupport7}/abstract_unit.rb +16 -12
- data/test/{activesupport5 → activesupport7}/decoding_test.rb +2 -10
- data/test/{activesupport5 → activesupport7}/encoding_test.rb +20 -34
- 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 +15 -15
- 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 +49 -37
- 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 +13 -12
- data/test/perf.rb +21 -26
- 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 +12 -11
- data/test/perf_parser.rb +42 -48
- data/test/perf_saj.rb +46 -54
- data/test/perf_scp.rb +57 -69
- data/test/perf_simple.rb +41 -39
- data/test/perf_strict.rb +68 -70
- data/test/perf_wab.rb +67 -69
- data/test/prec.rb +3 -3
- 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 +72 -51
- data/test/test_debian.rb +7 -10
- data/test/test_fast.rb +102 -87
- 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 +4 -4
- data/test/test_integer_range.rb +9 -9
- data/test/test_null.rb +20 -20
- data/test/test_object.rb +85 -96
- data/test/test_parser.rb +6 -22
- data/test/test_parser_debug.rb +27 -0
- data/test/test_parser_saj.rb +115 -23
- data/test/test_parser_usual.rb +6 -6
- 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 +163 -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 +34 -144
- 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 -16
- data/test/baz.rb +0 -16
- data/test/bug.rb +0 -16
- data/test/zoo.rb +0 -13
data/ext/oj/dump.c
CHANGED
@@ -10,8 +10,12 @@
|
|
10
10
|
#include <stdlib.h>
|
11
11
|
#include <string.h>
|
12
12
|
#include <unistd.h>
|
13
|
+
#if !IS_WINDOWS
|
14
|
+
#include <poll.h>
|
15
|
+
#endif
|
13
16
|
|
14
17
|
#include "cache8.h"
|
18
|
+
#include "mem.h"
|
15
19
|
#include "odd.h"
|
16
20
|
#include "oj.h"
|
17
21
|
#include "trace.h"
|
@@ -29,6 +33,7 @@ static const char nan_val[] = NAN_VAL;
|
|
29
33
|
typedef unsigned long ulong;
|
30
34
|
|
31
35
|
static size_t hibit_friendly_size(const uint8_t *str, size_t len);
|
36
|
+
static size_t slash_friendly_size(const uint8_t *str, size_t len);
|
32
37
|
static size_t xss_friendly_size(const uint8_t *str, size_t len);
|
33
38
|
static size_t ascii_friendly_size(const uint8_t *str, size_t len);
|
34
39
|
|
@@ -56,6 +61,17 @@ static char hibit_friendly_chars[256] = "\
|
|
56
61
|
11111111111111111111111111111111\
|
57
62
|
11111111111111111111111111111111";
|
58
63
|
|
64
|
+
// JSON standard but escape forward slashes `/`
|
65
|
+
static char slash_friendly_chars[256] = "\
|
66
|
+
66666666222622666666666666666666\
|
67
|
+
11211111111111121111111111111111\
|
68
|
+
11111111111111111111111111112111\
|
69
|
+
11111111111111111111111111111111\
|
70
|
+
11111111111111111111111111111111\
|
71
|
+
11111111111111111111111111111111\
|
72
|
+
11111111111111111111111111111111\
|
73
|
+
11111111111111111111111111111111";
|
74
|
+
|
59
75
|
// High bit set characters are always encoded as unicode. Worse case is 3
|
60
76
|
// bytes per character in the output. That makes this conservative.
|
61
77
|
static char ascii_friendly_chars[256] = "\
|
@@ -113,49 +129,43 @@ static char rails_friendly_chars[256] = "\
|
|
113
129
|
11111111111111111111111111111111";
|
114
130
|
|
115
131
|
static void raise_strict(VALUE obj) {
|
116
|
-
rb_raise(rb_eTypeError,
|
117
|
-
"Failed to dump %s Object to JSON in strict mode.",
|
118
|
-
rb_class2name(rb_obj_class(obj)));
|
132
|
+
rb_raise(rb_eTypeError, "Failed to dump %s Object to JSON in strict mode.", rb_class2name(rb_obj_class(obj)));
|
119
133
|
}
|
120
134
|
|
121
|
-
inline static size_t
|
135
|
+
inline static size_t calculate_string_size(const uint8_t *str, size_t len, const char *table) {
|
122
136
|
size_t size = 0;
|
123
137
|
size_t i = len;
|
124
138
|
|
125
|
-
for (;
|
126
|
-
size +=
|
139
|
+
for (; 3 < i; i -= 4) {
|
140
|
+
size += table[*str++];
|
141
|
+
size += table[*str++];
|
142
|
+
size += table[*str++];
|
143
|
+
size += table[*str++];
|
144
|
+
}
|
145
|
+
for (; 0 < i; i--) {
|
146
|
+
size += table[*str++];
|
127
147
|
}
|
128
148
|
return size - len * (size_t)'0';
|
129
149
|
}
|
130
150
|
|
151
|
+
inline static size_t newline_friendly_size(const uint8_t *str, size_t len) {
|
152
|
+
return calculate_string_size(str, len, newline_friendly_chars);
|
153
|
+
}
|
154
|
+
|
131
155
|
inline static size_t hibit_friendly_size(const uint8_t *str, size_t len) {
|
132
|
-
|
133
|
-
|
156
|
+
return calculate_string_size(str, len, hibit_friendly_chars);
|
157
|
+
}
|
134
158
|
|
135
|
-
|
136
|
-
|
137
|
-
}
|
138
|
-
return size - len * (size_t)'0';
|
159
|
+
inline static size_t slash_friendly_size(const uint8_t *str, size_t len) {
|
160
|
+
return calculate_string_size(str, len, slash_friendly_chars);
|
139
161
|
}
|
140
162
|
|
141
163
|
inline static size_t ascii_friendly_size(const uint8_t *str, size_t len) {
|
142
|
-
|
143
|
-
size_t i = len;
|
144
|
-
|
145
|
-
for (; 0 < i; str++, i--) {
|
146
|
-
size += ascii_friendly_chars[*str];
|
147
|
-
}
|
148
|
-
return size - len * (size_t)'0';
|
164
|
+
return calculate_string_size(str, len, ascii_friendly_chars);
|
149
165
|
}
|
150
166
|
|
151
167
|
inline static size_t xss_friendly_size(const uint8_t *str, size_t len) {
|
152
|
-
|
153
|
-
size_t i = len;
|
154
|
-
|
155
|
-
for (; 0 < i; str++, i--) {
|
156
|
-
size += xss_friendly_chars[*str];
|
157
|
-
}
|
158
|
-
return size - len * (size_t)'0';
|
168
|
+
return calculate_string_size(str, len, xss_friendly_chars);
|
159
169
|
}
|
160
170
|
|
161
171
|
inline static size_t hixss_friendly_size(const uint8_t *str, size_t len) {
|
@@ -188,13 +198,7 @@ inline static long rails_xss_friendly_size(const uint8_t *str, size_t len) {
|
|
188
198
|
}
|
189
199
|
|
190
200
|
inline static size_t rails_friendly_size(const uint8_t *str, size_t len) {
|
191
|
-
|
192
|
-
size_t i = len;
|
193
|
-
|
194
|
-
for (; 0 < i; str++, i--) {
|
195
|
-
size += rails_friendly_chars[*str];
|
196
|
-
}
|
197
|
-
return size - len * (size_t)'0';
|
201
|
+
return calculate_string_size(str, len, rails_friendly_chars);
|
198
202
|
}
|
199
203
|
|
200
204
|
const char *oj_nan_str(VALUE obj, int opt, int mode, bool plus, int *lenp) {
|
@@ -247,7 +251,7 @@ inline static void dump_hex(uint8_t c, Out out) {
|
|
247
251
|
static void raise_invalid_unicode(const char *str, int len, int pos) {
|
248
252
|
char c;
|
249
253
|
char code[32];
|
250
|
-
char
|
254
|
+
char *cp = code;
|
251
255
|
int i;
|
252
256
|
uint8_t d;
|
253
257
|
|
@@ -302,16 +306,14 @@ static const char *dump_unicode(const char *str, const char *end, Out out, const
|
|
302
306
|
uint32_t c1;
|
303
307
|
|
304
308
|
code -= 0x00010000;
|
305
|
-
c1
|
306
|
-
code
|
307
|
-
|
308
|
-
*out->cur++ = 'u';
|
309
|
+
c1 = ((code >> 10) & 0x000003FF) + 0x0000D800;
|
310
|
+
code = (code & 0x000003FF) + 0x0000DC00;
|
311
|
+
APPEND_CHARS(out->cur, "\\u", 2);
|
309
312
|
for (i = 3; 0 <= i; i--) {
|
310
313
|
*out->cur++ = hex_chars[(uint8_t)(c1 >> (i * 4)) & 0x0F];
|
311
314
|
}
|
312
315
|
}
|
313
|
-
|
314
|
-
*out->cur++ = 'u';
|
316
|
+
APPEND_CHARS(out->cur, "\\u", 2);
|
315
317
|
for (i = 3; 0 <= i; i--) {
|
316
318
|
*out->cur++ = hex_chars[(uint8_t)(code >> (i * 4)) & 0x0F];
|
317
319
|
}
|
@@ -360,9 +362,7 @@ long oj_check_circular(VALUE obj, Out out) {
|
|
360
362
|
} else {
|
361
363
|
if (ObjectMode == out->opts->mode) {
|
362
364
|
assure_size(out, 18);
|
363
|
-
|
364
|
-
*out->cur++ = '^';
|
365
|
-
*out->cur++ = 'r';
|
365
|
+
APPEND_CHARS(out->cur, "\"^r", 3);
|
366
366
|
dump_ulong(id, out);
|
367
367
|
*out->cur++ = '"';
|
368
368
|
}
|
@@ -374,15 +374,14 @@ long oj_check_circular(VALUE obj, Out out) {
|
|
374
374
|
|
375
375
|
void oj_dump_time(VALUE obj, Out out, int withZone) {
|
376
376
|
char buf[64];
|
377
|
-
char
|
377
|
+
char *b = buf + sizeof(buf) - 1;
|
378
378
|
long size;
|
379
|
-
char
|
379
|
+
char *dot;
|
380
380
|
int neg = 0;
|
381
381
|
long one = 1000000000;
|
382
382
|
long long sec;
|
383
383
|
long long nsec;
|
384
384
|
|
385
|
-
#ifdef HAVE_RB_TIME_TIMESPEC
|
386
385
|
// rb_time_timespec as well as rb_time_timeeval have a bug that causes an
|
387
386
|
// exception to be raised if a time is before 1970 on 32 bit systems so
|
388
387
|
// check the timespec size and use the ruby calls if a 32 bit system.
|
@@ -392,13 +391,9 @@ void oj_dump_time(VALUE obj, Out out, int withZone) {
|
|
392
391
|
sec = (long long)ts.tv_sec;
|
393
392
|
nsec = ts.tv_nsec;
|
394
393
|
} else {
|
395
|
-
sec =
|
396
|
-
nsec =
|
394
|
+
sec = NUM2LL(rb_funcall2(obj, oj_tv_sec_id, 0, 0));
|
395
|
+
nsec = NUM2LL(rb_funcall2(obj, oj_tv_nsec_id, 0, 0));
|
397
396
|
}
|
398
|
-
#else
|
399
|
-
sec = rb_num2ll(rb_funcall2(obj, oj_tv_sec_id, 0, 0));
|
400
|
-
nsec = rb_num2ll(rb_funcall2(obj, oj_tv_nsec_id, 0, 0));
|
401
|
-
#endif
|
402
397
|
|
403
398
|
*b-- = '\0';
|
404
399
|
if (withZone) {
|
@@ -464,13 +459,12 @@ void oj_dump_time(VALUE obj, Out out, int withZone) {
|
|
464
459
|
b++;
|
465
460
|
size = sizeof(buf) - (b - buf) - 1;
|
466
461
|
assure_size(out, size);
|
467
|
-
|
468
|
-
out->cur += size;
|
462
|
+
APPEND_CHARS(out->cur, b, size);
|
469
463
|
*out->cur = '\0';
|
470
464
|
}
|
471
465
|
|
472
466
|
void oj_dump_ruby_time(VALUE obj, Out out) {
|
473
|
-
volatile VALUE rstr =
|
467
|
+
volatile VALUE rstr = oj_safe_string_convert(obj);
|
474
468
|
|
475
469
|
oj_dump_cstr(RSTRING_PTR(rstr), (int)RSTRING_LEN(rstr), 0, 0, out);
|
476
470
|
}
|
@@ -485,20 +479,15 @@ void oj_dump_xml_time(VALUE obj, Out out) {
|
|
485
479
|
int tzhour, tzmin;
|
486
480
|
char tzsign = '+';
|
487
481
|
|
488
|
-
#ifdef HAVE_RB_TIME_TIMESPEC
|
489
482
|
if (16 <= sizeof(struct timespec)) {
|
490
483
|
struct timespec ts = rb_time_timespec(obj);
|
491
484
|
|
492
485
|
sec = ts.tv_sec;
|
493
486
|
nsec = ts.tv_nsec;
|
494
487
|
} else {
|
495
|
-
sec =
|
496
|
-
nsec =
|
488
|
+
sec = NUM2LL(rb_funcall2(obj, oj_tv_sec_id, 0, 0));
|
489
|
+
nsec = NUM2LL(rb_funcall2(obj, oj_tv_nsec_id, 0, 0));
|
497
490
|
}
|
498
|
-
#else
|
499
|
-
sec = rb_num2ll(rb_funcall2(obj, oj_tv_sec_id, 0, 0));
|
500
|
-
nsec = rb_num2ll(rb_funcall2(obj, oj_tv_nsec_id, 0, 0));
|
501
|
-
#endif
|
502
491
|
|
503
492
|
assure_size(out, 36);
|
504
493
|
if (9 > out->opts->sec_prec) {
|
@@ -535,14 +524,7 @@ void oj_dump_xml_time(VALUE obj, Out out) {
|
|
535
524
|
}
|
536
525
|
if ((0 == nsec && !out->opts->sec_prec_set) || 0 == out->opts->sec_prec) {
|
537
526
|
if (0 == tzsecs && rb_funcall2(obj, oj_utcq_id, 0, 0)) {
|
538
|
-
int len = sprintf(buf,
|
539
|
-
"%04d-%02d-%02dT%02d:%02d:%02dZ",
|
540
|
-
ti.year,
|
541
|
-
ti.mon,
|
542
|
-
ti.day,
|
543
|
-
ti.hour,
|
544
|
-
ti.min,
|
545
|
-
ti.sec);
|
527
|
+
int len = sprintf(buf, "%04d-%02d-%02dT%02d:%02d:%02dZ", ti.year, ti.mon, ti.day, ti.hour, ti.min, ti.sec);
|
546
528
|
oj_dump_cstr(buf, len, 0, 0, out);
|
547
529
|
} else {
|
548
530
|
int len = sprintf(buf,
|
@@ -574,18 +556,7 @@ void oj_dump_xml_time(VALUE obj, Out out) {
|
|
574
556
|
if (9 > out->opts->sec_prec) {
|
575
557
|
format[32] = '0' + out->opts->sec_prec;
|
576
558
|
}
|
577
|
-
len = sprintf(buf,
|
578
|
-
format,
|
579
|
-
ti.year,
|
580
|
-
ti.mon,
|
581
|
-
ti.day,
|
582
|
-
ti.hour,
|
583
|
-
ti.min,
|
584
|
-
ti.sec,
|
585
|
-
(long)nsec,
|
586
|
-
tzsign,
|
587
|
-
tzhour,
|
588
|
-
tzmin);
|
559
|
+
len = sprintf(buf, format, ti.year, ti.mon, ti.day, ti.hour, ti.min, ti.sec, (long)nsec, tzsign, tzhour, tzmin);
|
589
560
|
oj_dump_cstr(buf, len, 0, 0, out);
|
590
561
|
}
|
591
562
|
}
|
@@ -596,12 +567,8 @@ void oj_dump_obj_to_json(VALUE obj, Options copts, Out out) {
|
|
596
567
|
|
597
568
|
void oj_dump_obj_to_json_using_params(VALUE obj, Options copts, Out out, int argc, VALUE *argv) {
|
598
569
|
if (0 == out->buf) {
|
599
|
-
out
|
600
|
-
// 1 less than end plus extra for possible errors
|
601
|
-
out->end = out->buf + 4095 - BUFFER_EXTRA;
|
602
|
-
out->allocated = true;
|
570
|
+
oj_out_init(out);
|
603
571
|
}
|
604
|
-
out->cur = out->buf;
|
605
572
|
out->circ_cnt = 0;
|
606
573
|
out->opts = copts;
|
607
574
|
out->hash_cnt = 0;
|
@@ -636,38 +603,51 @@ void oj_dump_obj_to_json_using_params(VALUE obj, Options copts, Out out, int arg
|
|
636
603
|
}
|
637
604
|
|
638
605
|
void oj_write_obj_to_file(VALUE obj, const char *path, Options copts) {
|
639
|
-
char buf[4096];
|
640
606
|
struct _out out;
|
641
607
|
size_t size;
|
642
|
-
FILE
|
608
|
+
FILE *f;
|
643
609
|
int ok;
|
644
610
|
|
645
|
-
out
|
646
|
-
|
647
|
-
out.
|
648
|
-
out.omit_nil = copts->dump_opts.omit_nil;
|
611
|
+
oj_out_init(&out);
|
612
|
+
|
613
|
+
out.omit_nil = copts->dump_opts.omit_nil;
|
649
614
|
oj_dump_obj_to_json(obj, copts, &out);
|
650
615
|
size = out.cur - out.buf;
|
651
616
|
if (0 == (f = fopen(path, "w"))) {
|
652
|
-
|
653
|
-
xfree(out.buf);
|
654
|
-
}
|
617
|
+
oj_out_free(&out);
|
655
618
|
rb_raise(rb_eIOError, "%s", strerror(errno));
|
656
619
|
}
|
657
620
|
ok = (size == fwrite(out.buf, 1, size, f));
|
658
|
-
|
659
|
-
|
660
|
-
|
661
|
-
fclose(f);
|
621
|
+
|
622
|
+
oj_out_free(&out);
|
623
|
+
|
662
624
|
if (!ok) {
|
663
625
|
int err = ferror(f);
|
626
|
+
fclose(f);
|
664
627
|
|
665
628
|
rb_raise(rb_eIOError, "Write failed. [%d:%s]", err, strerror(err));
|
666
629
|
}
|
630
|
+
fclose(f);
|
631
|
+
}
|
632
|
+
|
633
|
+
#if !IS_WINDOWS
|
634
|
+
static void write_ready(int fd) {
|
635
|
+
struct pollfd pp;
|
636
|
+
int i;
|
637
|
+
|
638
|
+
pp.fd = fd;
|
639
|
+
pp.events = POLLERR | POLLOUT;
|
640
|
+
pp.revents = 0;
|
641
|
+
if (0 >= (i = poll(&pp, 1, 5000))) {
|
642
|
+
if (0 == i || EAGAIN == errno) {
|
643
|
+
rb_raise(rb_eIOError, "write timed out");
|
644
|
+
}
|
645
|
+
rb_raise(rb_eIOError, "write failed. %d %s.", errno, strerror(errno));
|
646
|
+
}
|
667
647
|
}
|
648
|
+
#endif
|
668
649
|
|
669
650
|
void oj_write_obj_to_stream(VALUE obj, VALUE stream, Options copts) {
|
670
|
-
char buf[4096];
|
671
651
|
struct _out out;
|
672
652
|
ssize_t size;
|
673
653
|
VALUE clas = rb_obj_class(stream);
|
@@ -676,42 +656,49 @@ void oj_write_obj_to_stream(VALUE obj, VALUE stream, Options copts) {
|
|
676
656
|
VALUE s;
|
677
657
|
#endif
|
678
658
|
|
679
|
-
out
|
680
|
-
|
681
|
-
out.
|
682
|
-
out.omit_nil = copts->dump_opts.omit_nil;
|
659
|
+
oj_out_init(&out);
|
660
|
+
|
661
|
+
out.omit_nil = copts->dump_opts.omit_nil;
|
683
662
|
oj_dump_obj_to_json(obj, copts, &out);
|
684
663
|
size = out.cur - out.buf;
|
685
664
|
if (oj_stringio_class == clas) {
|
686
665
|
rb_funcall(stream, oj_write_id, 1, rb_str_new(out.buf, size));
|
687
666
|
#if !IS_WINDOWS
|
688
|
-
} else if (rb_respond_to(stream, oj_fileno_id) &&
|
689
|
-
|
690
|
-
|
691
|
-
|
692
|
-
|
667
|
+
} else if (rb_respond_to(stream, oj_fileno_id) && Qnil != (s = rb_funcall(stream, oj_fileno_id, 0)) &&
|
668
|
+
0 != (fd = FIX2INT(s))) {
|
669
|
+
ssize_t cnt;
|
670
|
+
ssize_t total = 0;
|
671
|
+
|
672
|
+
while (true) {
|
673
|
+
if (0 > (cnt = write(fd, out.buf + total, size - total))) {
|
674
|
+
if (EAGAIN != errno) {
|
675
|
+
rb_raise(rb_eIOError, "write failed. %d %s.", errno, strerror(errno));
|
676
|
+
break;
|
677
|
+
}
|
693
678
|
}
|
694
|
-
|
679
|
+
total += cnt;
|
680
|
+
if (size <= total) {
|
681
|
+
// Completed
|
682
|
+
break;
|
683
|
+
}
|
684
|
+
write_ready(fd);
|
695
685
|
}
|
696
686
|
#endif
|
697
687
|
} else if (rb_respond_to(stream, oj_write_id)) {
|
698
688
|
rb_funcall(stream, oj_write_id, 1, rb_str_new(out.buf, size));
|
699
689
|
} else {
|
700
|
-
|
701
|
-
xfree(out.buf);
|
702
|
-
}
|
690
|
+
oj_out_free(&out);
|
703
691
|
rb_raise(rb_eArgError, "to_stream() expected an IO Object.");
|
704
692
|
}
|
705
|
-
|
706
|
-
xfree(out.buf);
|
707
|
-
}
|
693
|
+
oj_out_free(&out);
|
708
694
|
}
|
709
695
|
|
710
696
|
void oj_dump_str(VALUE obj, int depth, Out out, bool as_ok) {
|
711
|
-
|
697
|
+
int idx = RB_ENCODING_GET(obj);
|
712
698
|
|
713
|
-
if (
|
714
|
-
|
699
|
+
if (oj_utf8_encoding_index != idx) {
|
700
|
+
rb_encoding *enc = rb_enc_from_index(idx);
|
701
|
+
obj = rb_str_conv_enc(obj, enc, oj_utf8_encoding);
|
715
702
|
}
|
716
703
|
oj_dump_cstr(RSTRING_PTR(obj), (int)RSTRING_LEN(obj), 0, 0, out);
|
717
704
|
}
|
@@ -724,7 +711,7 @@ void oj_dump_sym(VALUE obj, int depth, Out out, bool as_ok) {
|
|
724
711
|
|
725
712
|
static void debug_raise(const char *orig, size_t cnt, int line) {
|
726
713
|
char buf[1024];
|
727
|
-
char
|
714
|
+
char *b = buf;
|
728
715
|
const char *s = orig;
|
729
716
|
const char *s_end = s + cnt;
|
730
717
|
|
@@ -750,20 +737,16 @@ void oj_dump_raw_json(VALUE obj, int depth, Out out) {
|
|
750
737
|
} else {
|
751
738
|
volatile VALUE jv;
|
752
739
|
|
753
|
-
|
754
|
-
oj_trace("raw_json", obj, __FILE__, __LINE__, depth + 1, TraceRubyIn);
|
755
|
-
}
|
740
|
+
TRACE(out->opts->trace, "raw_json", obj, depth + 1, TraceRubyIn);
|
756
741
|
jv = rb_funcall(obj, oj_raw_json_id, 2, RB_INT2NUM(depth), RB_INT2NUM(out->indent));
|
757
|
-
|
758
|
-
oj_trace("raw_json", obj, __FILE__, __LINE__, depth + 1, TraceRubyOut);
|
759
|
-
}
|
742
|
+
TRACE(out->opts->trace, "raw_json", obj, depth + 1, TraceRubyOut);
|
760
743
|
oj_dump_raw(RSTRING_PTR(jv), (size_t)RSTRING_LEN(jv), out);
|
761
744
|
}
|
762
745
|
}
|
763
746
|
|
764
747
|
void oj_dump_cstr(const char *str, size_t cnt, bool is_sym, bool escape1, Out out) {
|
765
748
|
size_t size;
|
766
|
-
char
|
749
|
+
char *cmap;
|
767
750
|
const char *orig = str;
|
768
751
|
bool has_hi = false;
|
769
752
|
|
@@ -776,6 +759,11 @@ void oj_dump_cstr(const char *str, size_t cnt, bool is_sym, bool escape1, Out ou
|
|
776
759
|
cmap = ascii_friendly_chars;
|
777
760
|
size = ascii_friendly_size((uint8_t *)str, cnt);
|
778
761
|
break;
|
762
|
+
case SlashEsc:
|
763
|
+
has_hi = true;
|
764
|
+
cmap = slash_friendly_chars;
|
765
|
+
size = slash_friendly_size((uint8_t *)str, cnt);
|
766
|
+
break;
|
779
767
|
case XSSEsc:
|
780
768
|
cmap = xss_friendly_chars;
|
781
769
|
size = xss_friendly_size((uint8_t *)str, cnt);
|
@@ -808,10 +796,7 @@ void oj_dump_cstr(const char *str, size_t cnt, bool is_sym, bool escape1, Out ou
|
|
808
796
|
*out->cur++ = '"';
|
809
797
|
|
810
798
|
if (escape1) {
|
811
|
-
|
812
|
-
*out->cur++ = 'u';
|
813
|
-
*out->cur++ = '0';
|
814
|
-
*out->cur++ = '0';
|
799
|
+
APPEND_CHARS(out->cur, "\\u00", 4);
|
815
800
|
dump_hex((uint8_t)*str, out);
|
816
801
|
cnt--;
|
817
802
|
size--;
|
@@ -822,8 +807,7 @@ void oj_dump_cstr(const char *str, size_t cnt, bool is_sym, bool escape1, Out ou
|
|
822
807
|
if (is_sym) {
|
823
808
|
*out->cur++ = ':';
|
824
809
|
}
|
825
|
-
|
826
|
-
out->cur += cnt;
|
810
|
+
APPEND_CHARS(out->cur, str, cnt);
|
827
811
|
*out->cur++ = '"';
|
828
812
|
} else {
|
829
813
|
const char *end = str + cnt;
|
@@ -835,8 +819,7 @@ void oj_dump_cstr(const char *str, size_t cnt, bool is_sym, bool escape1, Out ou
|
|
835
819
|
for (; str < end; str++) {
|
836
820
|
switch (cmap[(uint8_t)*str]) {
|
837
821
|
case '1':
|
838
|
-
if ((JXEsc == out->opts->escape_mode || RailsXEsc == out->opts->escape_mode) &&
|
839
|
-
check_start <= str) {
|
822
|
+
if ((JXEsc == out->opts->escape_mode || RailsXEsc == out->opts->escape_mode) && check_start <= str) {
|
840
823
|
if (0 != (0x80 & (uint8_t)*str)) {
|
841
824
|
if (0xC0 == (0xC0 & (uint8_t)*str)) {
|
842
825
|
check_start = check_unicode(str, end, orig);
|
@@ -860,11 +843,9 @@ void oj_dump_cstr(const char *str, size_t cnt, bool is_sym, bool escape1, Out ou
|
|
860
843
|
}
|
861
844
|
break;
|
862
845
|
case '3': // Unicode
|
863
|
-
if (0xe2 == (uint8_t)*str &&
|
864
|
-
(JXEsc == out->opts->escape_mode || RailsXEsc == out->opts->escape_mode) &&
|
846
|
+
if (0xe2 == (uint8_t)*str && (JXEsc == out->opts->escape_mode || RailsXEsc == out->opts->escape_mode) &&
|
865
847
|
2 <= end - str) {
|
866
|
-
if (0x80 == (uint8_t)str[1] &&
|
867
|
-
(0xa8 == (uint8_t)str[2] || 0xa9 == (uint8_t)str[2])) {
|
848
|
+
if (0x80 == (uint8_t)str[1] && (0xa8 == (uint8_t)str[2] || 0xa9 == (uint8_t)str[2])) {
|
868
849
|
str = dump_unicode(str, end, out, orig);
|
869
850
|
} else {
|
870
851
|
check_start = check_unicode(str, end, orig);
|
@@ -876,17 +857,15 @@ void oj_dump_cstr(const char *str, size_t cnt, bool is_sym, bool escape1, Out ou
|
|
876
857
|
break;
|
877
858
|
case '6': // control characters
|
878
859
|
if (*(uint8_t *)str < 0x80) {
|
879
|
-
*out->
|
880
|
-
|
881
|
-
|
882
|
-
|
860
|
+
if (0 == (uint8_t)*str && out->opts->dump_opts.omit_null_byte) {
|
861
|
+
break;
|
862
|
+
}
|
863
|
+
APPEND_CHARS(out->cur, "\\u00", 4);
|
883
864
|
dump_hex((uint8_t)*str, out);
|
884
865
|
} else {
|
885
866
|
if (0xe2 == (uint8_t)*str &&
|
886
|
-
(JXEsc == out->opts->escape_mode || RailsXEsc == out->opts->escape_mode) &&
|
887
|
-
2
|
888
|
-
if (0x80 == (uint8_t)str[1] &&
|
889
|
-
(0xa8 == (uint8_t)str[2] || 0xa9 == (uint8_t)str[2])) {
|
867
|
+
(JXEsc == out->opts->escape_mode || RailsXEsc == out->opts->escape_mode) && 2 <= end - str) {
|
868
|
+
if (0x80 == (uint8_t)str[1] && (0xa8 == (uint8_t)str[2] || 0xa9 == (uint8_t)str[2])) {
|
890
869
|
str = dump_unicode(str, end, out, orig);
|
891
870
|
} else {
|
892
871
|
check_start = check_unicode(str, end, orig);
|
@@ -902,8 +881,8 @@ void oj_dump_cstr(const char *str, size_t cnt, bool is_sym, bool escape1, Out ou
|
|
902
881
|
}
|
903
882
|
*out->cur++ = '"';
|
904
883
|
}
|
905
|
-
if ((JXEsc == out->opts->escape_mode || RailsXEsc == out->opts->escape_mode) &&
|
906
|
-
0
|
884
|
+
if ((JXEsc == out->opts->escape_mode || RailsXEsc == out->opts->escape_mode) && 0 < str - orig &&
|
885
|
+
0 != (0x80 & *(str - 1))) {
|
907
886
|
uint8_t c = (uint8_t) * (str - 1);
|
908
887
|
int i;
|
909
888
|
int scnt = (int)(str - orig);
|
@@ -953,31 +932,43 @@ void oj_dump_class(VALUE obj, int depth, Out out, bool as_ok) {
|
|
953
932
|
}
|
954
933
|
|
955
934
|
void oj_dump_obj_to_s(VALUE obj, Out out) {
|
956
|
-
volatile VALUE rstr =
|
935
|
+
volatile VALUE rstr = oj_safe_string_convert(obj);
|
957
936
|
|
958
937
|
oj_dump_cstr(RSTRING_PTR(rstr), (int)RSTRING_LEN(rstr), 0, 0, out);
|
959
938
|
}
|
960
939
|
|
961
940
|
void oj_dump_raw(const char *str, size_t cnt, Out out) {
|
962
941
|
assure_size(out, cnt + 10);
|
963
|
-
|
964
|
-
out->cur += cnt;
|
942
|
+
APPEND_CHARS(out->cur, str, cnt);
|
965
943
|
*out->cur = '\0';
|
966
944
|
}
|
967
945
|
|
946
|
+
void oj_out_init(Out out) {
|
947
|
+
out->buf = out->stack_buffer;
|
948
|
+
out->cur = out->buf;
|
949
|
+
out->end = out->buf + sizeof(out->stack_buffer) - BUFFER_EXTRA;
|
950
|
+
out->allocated = false;
|
951
|
+
}
|
952
|
+
|
953
|
+
void oj_out_free(Out out) {
|
954
|
+
if (out->allocated) {
|
955
|
+
OJ_R_FREE(out->buf); // TBD
|
956
|
+
}
|
957
|
+
}
|
958
|
+
|
968
959
|
void oj_grow_out(Out out, size_t len) {
|
969
960
|
size_t size = out->end - out->buf;
|
970
961
|
long pos = out->cur - out->buf;
|
971
|
-
char
|
962
|
+
char *buf = out->buf;
|
972
963
|
|
973
964
|
size *= 2;
|
974
965
|
if (size <= len * 2 + pos) {
|
975
966
|
size += len;
|
976
967
|
}
|
977
968
|
if (out->allocated) {
|
978
|
-
|
969
|
+
OJ_R_REALLOC_N(buf, char, (size + BUFFER_EXTRA));
|
979
970
|
} else {
|
980
|
-
buf =
|
971
|
+
buf = OJ_R_ALLOC_N(char, (size + BUFFER_EXTRA));
|
981
972
|
out->allocated = true;
|
982
973
|
memcpy(buf, out->buf, out->end - out->buf + BUFFER_EXTRA);
|
983
974
|
}
|
@@ -991,37 +982,62 @@ void oj_grow_out(Out out, size_t len) {
|
|
991
982
|
|
992
983
|
void oj_dump_nil(VALUE obj, int depth, Out out, bool as_ok) {
|
993
984
|
assure_size(out, 4);
|
994
|
-
|
995
|
-
*out->cur
|
996
|
-
*out->cur++ = 'l';
|
997
|
-
*out->cur++ = 'l';
|
998
|
-
*out->cur = '\0';
|
985
|
+
APPEND_CHARS(out->cur, "null", 4);
|
986
|
+
*out->cur = '\0';
|
999
987
|
}
|
1000
988
|
|
1001
989
|
void oj_dump_true(VALUE obj, int depth, Out out, bool as_ok) {
|
1002
990
|
assure_size(out, 4);
|
1003
|
-
|
1004
|
-
*out->cur
|
1005
|
-
*out->cur++ = 'u';
|
1006
|
-
*out->cur++ = 'e';
|
1007
|
-
*out->cur = '\0';
|
991
|
+
APPEND_CHARS(out->cur, "true", 4);
|
992
|
+
*out->cur = '\0';
|
1008
993
|
}
|
1009
994
|
|
1010
995
|
void oj_dump_false(VALUE obj, int depth, Out out, bool as_ok) {
|
1011
996
|
assure_size(out, 5);
|
1012
|
-
|
1013
|
-
*out->cur
|
1014
|
-
|
1015
|
-
|
1016
|
-
|
1017
|
-
|
997
|
+
APPEND_CHARS(out->cur, "false", 5);
|
998
|
+
*out->cur = '\0';
|
999
|
+
}
|
1000
|
+
|
1001
|
+
static const char digits_table[] = "\
|
1002
|
+
00010203040506070809\
|
1003
|
+
10111213141516171819\
|
1004
|
+
20212223242526272829\
|
1005
|
+
30313233343536373839\
|
1006
|
+
40414243444546474849\
|
1007
|
+
50515253545556575859\
|
1008
|
+
60616263646566676869\
|
1009
|
+
70717273747576777879\
|
1010
|
+
80818283848586878889\
|
1011
|
+
90919293949596979899";
|
1012
|
+
|
1013
|
+
char *oj_longlong_to_string(long long num, bool negative, char *buf) {
|
1014
|
+
while (100 <= num) {
|
1015
|
+
unsigned idx = num % 100 * 2;
|
1016
|
+
*buf-- = digits_table[idx + 1];
|
1017
|
+
*buf-- = digits_table[idx];
|
1018
|
+
num /= 100;
|
1019
|
+
}
|
1020
|
+
if (num < 10) {
|
1021
|
+
*buf-- = num + '0';
|
1022
|
+
} else {
|
1023
|
+
*buf-- = digits_table[num * 2 + 1];
|
1024
|
+
*buf-- = digits_table[num * 2];
|
1025
|
+
}
|
1026
|
+
|
1027
|
+
if (negative) {
|
1028
|
+
*buf = '-';
|
1029
|
+
} else {
|
1030
|
+
buf++;
|
1031
|
+
}
|
1032
|
+
return buf;
|
1018
1033
|
}
|
1019
1034
|
|
1020
1035
|
void oj_dump_fixnum(VALUE obj, int depth, Out out, bool as_ok) {
|
1021
1036
|
char buf[32];
|
1022
|
-
char
|
1023
|
-
long long num =
|
1024
|
-
|
1037
|
+
char *b = buf + sizeof(buf) - 1;
|
1038
|
+
long long num = NUM2LL(obj);
|
1039
|
+
bool neg = false;
|
1040
|
+
size_t cnt = 0;
|
1025
1041
|
bool dump_as_string = false;
|
1026
1042
|
|
1027
1043
|
if (out->opts->int_range_max != 0 && out->opts->int_range_min != 0 &&
|
@@ -1029,7 +1045,7 @@ void oj_dump_fixnum(VALUE obj, int depth, Out out, bool as_ok) {
|
|
1029
1045
|
dump_as_string = true;
|
1030
1046
|
}
|
1031
1047
|
if (0 > num) {
|
1032
|
-
neg =
|
1048
|
+
neg = true;
|
1033
1049
|
num = -num;
|
1034
1050
|
}
|
1035
1051
|
*b-- = '\0';
|
@@ -1038,24 +1054,16 @@ void oj_dump_fixnum(VALUE obj, int depth, Out out, bool as_ok) {
|
|
1038
1054
|
*b-- = '"';
|
1039
1055
|
}
|
1040
1056
|
if (0 < num) {
|
1041
|
-
|
1042
|
-
*b = (num % 10) + '0';
|
1043
|
-
}
|
1044
|
-
if (neg) {
|
1045
|
-
*b = '-';
|
1046
|
-
} else {
|
1047
|
-
b++;
|
1048
|
-
}
|
1057
|
+
b = oj_longlong_to_string(num, neg, b);
|
1049
1058
|
} else {
|
1050
1059
|
*b = '0';
|
1051
1060
|
}
|
1052
1061
|
if (dump_as_string) {
|
1053
1062
|
*--b = '"';
|
1054
1063
|
}
|
1055
|
-
|
1056
|
-
|
1057
|
-
|
1058
|
-
}
|
1064
|
+
cnt = sizeof(buf) - (b - buf) - 1;
|
1065
|
+
assure_size(out, cnt);
|
1066
|
+
APPEND_CHARS(out->cur, b, cnt);
|
1059
1067
|
*out->cur = '\0';
|
1060
1068
|
}
|
1061
1069
|
|
@@ -1064,16 +1072,14 @@ void oj_dump_bignum(VALUE obj, int depth, Out out, bool as_ok) {
|
|
1064
1072
|
int cnt = (int)RSTRING_LEN(rs);
|
1065
1073
|
bool dump_as_string = false;
|
1066
1074
|
|
1067
|
-
if (out->opts->int_range_max != 0 ||
|
1068
|
-
out->opts->int_range_min != 0) { // Bignum cannot be inside of Fixnum range
|
1075
|
+
if (out->opts->int_range_max != 0 || out->opts->int_range_min != 0) { // Bignum cannot be inside of Fixnum range
|
1069
1076
|
dump_as_string = true;
|
1070
1077
|
assure_size(out, cnt + 2);
|
1071
1078
|
*out->cur++ = '"';
|
1072
1079
|
} else {
|
1073
1080
|
assure_size(out, cnt);
|
1074
1081
|
}
|
1075
|
-
|
1076
|
-
out->cur += cnt;
|
1082
|
+
APPEND_CHARS(out->cur, RSTRING_PTR(rs), cnt);
|
1077
1083
|
if (dump_as_string) {
|
1078
1084
|
*out->cur++ = '"';
|
1079
1085
|
}
|
@@ -1083,7 +1089,7 @@ void oj_dump_bignum(VALUE obj, int depth, Out out, bool as_ok) {
|
|
1083
1089
|
// Removed dependencies on math due to problems with CentOS 5.4.
|
1084
1090
|
void oj_dump_float(VALUE obj, int depth, Out out, bool as_ok) {
|
1085
1091
|
char buf[64];
|
1086
|
-
char
|
1092
|
+
char *b;
|
1087
1093
|
double d = rb_num2dbl(obj);
|
1088
1094
|
int cnt = 0;
|
1089
1095
|
|
@@ -1162,7 +1168,7 @@ void oj_dump_float(VALUE obj, int depth, Out out, bool as_ok) {
|
|
1162
1168
|
} else if (isnan(d)) {
|
1163
1169
|
if (ObjectMode == out->opts->mode) {
|
1164
1170
|
strcpy(buf, nan_val);
|
1165
|
-
cnt = sizeof(
|
1171
|
+
cnt = sizeof(nan_val) - 1;
|
1166
1172
|
} else {
|
1167
1173
|
NanDump nd = out->opts->dump_opts.nan_dump;
|
1168
1174
|
|
@@ -1194,7 +1200,7 @@ void oj_dump_float(VALUE obj, int depth, Out out, bool as_ok) {
|
|
1194
1200
|
} else if (d == (double)(long long int)d) {
|
1195
1201
|
cnt = snprintf(buf, sizeof(buf), "%.1f", d);
|
1196
1202
|
} else if (0 == out->opts->float_prec) {
|
1197
|
-
volatile VALUE rstr =
|
1203
|
+
volatile VALUE rstr = oj_safe_string_convert(obj);
|
1198
1204
|
|
1199
1205
|
cnt = (int)RSTRING_LEN(rstr);
|
1200
1206
|
if ((int)sizeof(buf) <= cnt) {
|
@@ -1206,9 +1212,7 @@ void oj_dump_float(VALUE obj, int depth, Out out, bool as_ok) {
|
|
1206
1212
|
cnt = oj_dump_float_printf(buf, sizeof(buf), obj, d, out->opts->float_fmt);
|
1207
1213
|
}
|
1208
1214
|
assure_size(out, cnt);
|
1209
|
-
|
1210
|
-
*out->cur++ = *b;
|
1211
|
-
}
|
1215
|
+
APPEND_CHARS(out->cur, buf, cnt);
|
1212
1216
|
*out->cur = '\0';
|
1213
1217
|
}
|
1214
1218
|
|
@@ -1218,24 +1222,10 @@ int oj_dump_float_printf(char *buf, size_t blen, VALUE obj, double d, const char
|
|
1218
1222
|
// Round off issues at 16 significant digits so check for obvious ones of
|
1219
1223
|
// 0001 and 9999.
|
1220
1224
|
if (17 <= cnt && (0 == strcmp("0001", buf + cnt - 4) || 0 == strcmp("9999", buf + cnt - 4))) {
|
1221
|
-
volatile VALUE rstr =
|
1225
|
+
volatile VALUE rstr = oj_safe_string_convert(obj);
|
1222
1226
|
|
1223
1227
|
strcpy(buf, RSTRING_PTR(rstr));
|
1224
1228
|
cnt = (int)RSTRING_LEN(rstr);
|
1225
1229
|
}
|
1226
1230
|
return cnt;
|
1227
1231
|
}
|
1228
|
-
|
1229
|
-
bool oj_dump_ignore(Options opts, VALUE obj) {
|
1230
|
-
if (NULL != opts->ignore && (ObjectMode == opts->mode || CustomMode == opts->mode)) {
|
1231
|
-
VALUE *vp = opts->ignore;
|
1232
|
-
VALUE clas = rb_obj_class(obj);
|
1233
|
-
|
1234
|
-
for (; Qnil != *vp; vp++) {
|
1235
|
-
if (clas == *vp) {
|
1236
|
-
return true;
|
1237
|
-
}
|
1238
|
-
}
|
1239
|
-
}
|
1240
|
-
return false;
|
1241
|
-
}
|