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/object.c
CHANGED
@@ -7,7 +7,7 @@
|
|
7
7
|
|
8
8
|
#include "encode.h"
|
9
9
|
#include "err.h"
|
10
|
-
#include "
|
10
|
+
#include "intern.h"
|
11
11
|
#include "odd.h"
|
12
12
|
#include "oj.h"
|
13
13
|
#include "parse.h"
|
@@ -32,16 +32,17 @@ static VALUE calc_hash_key(ParseInfo pi, Val kval, char k1) {
|
|
32
32
|
volatile VALUE rkey;
|
33
33
|
|
34
34
|
if (':' == k1) {
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
rkey = rb_str_new(kval->key, kval->klen);
|
40
|
-
rkey = oj_encode(rkey);
|
41
|
-
if (Yes == pi->options.sym_key) {
|
42
|
-
rkey = rb_str_intern(rkey);
|
43
|
-
}
|
35
|
+
return ID2SYM(rb_intern3(kval->key + 1, kval->klen - 1, oj_utf8_encoding));
|
36
|
+
}
|
37
|
+
if (Yes == pi->options.sym_key) {
|
38
|
+
return ID2SYM(rb_intern3(kval->key, kval->klen, oj_utf8_encoding));
|
44
39
|
}
|
40
|
+
#if HAVE_RB_ENC_INTERNED_STR
|
41
|
+
rkey = rb_enc_interned_str(kval->key, kval->klen, oj_utf8_encoding);
|
42
|
+
#else
|
43
|
+
rkey = rb_utf8_str_new(kval->key, kval->klen);
|
44
|
+
OBJ_FREEZE(rkey);
|
45
|
+
#endif
|
45
46
|
return rkey;
|
46
47
|
}
|
47
48
|
|
@@ -49,9 +50,7 @@ static VALUE str_to_value(ParseInfo pi, const char *str, size_t len, const char
|
|
49
50
|
volatile VALUE rstr = Qnil;
|
50
51
|
|
51
52
|
if (':' == *orig && 0 < len) {
|
52
|
-
rstr =
|
53
|
-
rstr = oj_encode(rstr);
|
54
|
-
rstr = rb_funcall(rstr, oj_to_sym_id, 0);
|
53
|
+
rstr = ID2SYM(rb_intern3(str + 1, len - 1, oj_utf8_encoding));
|
55
54
|
} else if (pi->circ_array && 3 <= len && '^' == *orig && 'r' == orig[1]) {
|
56
55
|
long i = read_long(str + 2, len - 2);
|
57
56
|
|
@@ -61,17 +60,11 @@ static VALUE str_to_value(ParseInfo pi, const char *str, size_t len, const char
|
|
61
60
|
}
|
62
61
|
rstr = oj_circ_array_get(pi->circ_array, i);
|
63
62
|
} else {
|
64
|
-
rstr =
|
65
|
-
rstr = oj_encode(rstr);
|
63
|
+
rstr = rb_utf8_str_new(str, len);
|
66
64
|
}
|
67
65
|
return rstr;
|
68
66
|
}
|
69
67
|
|
70
|
-
#if (RUBY_VERSION_MAJOR == 1 && RUBY_VERSION_MINOR == 8)
|
71
|
-
static VALUE oj_parse_xml_time(const char *str, int len) {
|
72
|
-
return rb_funcall(rb_cTime, oj_parse_id, 1, rb_str_new(str, len));
|
73
|
-
}
|
74
|
-
#else
|
75
68
|
// The much faster approach (4x faster)
|
76
69
|
static int parse_num(const char *str, const char *end, int cnt) {
|
77
70
|
int n = 0;
|
@@ -90,8 +83,9 @@ static int parse_num(const char *str, const char *end, int cnt) {
|
|
90
83
|
|
91
84
|
VALUE
|
92
85
|
oj_parse_xml_time(const char *str, int len) {
|
93
|
-
VALUE args[
|
94
|
-
const char *end
|
86
|
+
VALUE args[7];
|
87
|
+
const char *end = str + len;
|
88
|
+
const char *orig = str;
|
95
89
|
int n;
|
96
90
|
|
97
91
|
// year
|
@@ -151,7 +145,9 @@ oj_parse_xml_time(const char *str, int len) {
|
|
151
145
|
char c = *str++;
|
152
146
|
|
153
147
|
if ('.' == c) {
|
154
|
-
long long
|
148
|
+
unsigned long long num = 0;
|
149
|
+
unsigned long long den = 1;
|
150
|
+
const unsigned long long last_den_limit = ULLONG_MAX / 10;
|
155
151
|
|
156
152
|
for (; str < end; str++) {
|
157
153
|
c = *str;
|
@@ -159,9 +155,14 @@ oj_parse_xml_time(const char *str, int len) {
|
|
159
155
|
str++;
|
160
156
|
break;
|
161
157
|
}
|
162
|
-
|
158
|
+
if (den > last_den_limit) {
|
159
|
+
// bail to Time.parse if there are more fractional digits than a ULLONG rational can hold
|
160
|
+
return rb_funcall(rb_cTime, oj_parse_id, 1, rb_str_new(orig, len));
|
161
|
+
}
|
162
|
+
num = num * 10 + (c - '0');
|
163
|
+
den *= 10;
|
163
164
|
}
|
164
|
-
args[5] =
|
165
|
+
args[5] = rb_funcall(INT2NUM(n), oj_plus_id, 1, rb_rational_new(ULL2NUM(num), ULL2NUM(den)));
|
165
166
|
} else {
|
166
167
|
args[5] = rb_ll2inum(n);
|
167
168
|
}
|
@@ -203,7 +204,6 @@ oj_parse_xml_time(const char *str, int len) {
|
|
203
204
|
}
|
204
205
|
return rb_funcall2(rb_cTime, oj_new_id, 7, args);
|
205
206
|
}
|
206
|
-
#endif
|
207
207
|
|
208
208
|
static int hat_cstr(ParseInfo pi, Val parent, Val kval, const char *str, size_t len) {
|
209
209
|
const char *key = kval->key;
|
@@ -228,16 +228,10 @@ static int hat_cstr(ParseInfo pi, Val parent, Val kval, const char *str, size_t
|
|
228
228
|
}
|
229
229
|
parent->val = odd->clas;
|
230
230
|
parent->odd_args = oj_odd_alloc_args(odd);
|
231
|
-
} break;
|
232
|
-
case 'm':
|
233
|
-
parent->val = rb_str_new(str + 1, len - 1);
|
234
|
-
parent->val = oj_encode(parent->val);
|
235
|
-
parent->val = rb_funcall(parent->val, oj_to_sym_id, 0);
|
236
|
-
break;
|
237
|
-
case 's':
|
238
|
-
parent->val = rb_str_new(str, len);
|
239
|
-
parent->val = oj_encode(parent->val);
|
240
231
|
break;
|
232
|
+
}
|
233
|
+
case 'm': parent->val = ID2SYM(rb_intern3(str + 1, len - 1, oj_utf8_encoding)); break;
|
234
|
+
case 's': parent->val = rb_utf8_str_new(str, len); break;
|
241
235
|
case 'c': // class
|
242
236
|
{
|
243
237
|
VALUE clas = oj_name2class(pi, str, len, Yes == pi->options.auto_define, rb_eArgError);
|
@@ -247,7 +241,8 @@ static int hat_cstr(ParseInfo pi, Val parent, Val kval, const char *str, size_t
|
|
247
241
|
} else {
|
248
242
|
parent->val = clas;
|
249
243
|
}
|
250
|
-
|
244
|
+
break;
|
245
|
+
}
|
251
246
|
case 't': // time
|
252
247
|
parent->val = oj_parse_xml_time(str, (int)len);
|
253
248
|
break;
|
@@ -277,32 +272,22 @@ static int hat_num(ParseInfo pi, Val parent, Val kval, NumInfo ni) {
|
|
277
272
|
}
|
278
273
|
if (86400 == ni->exp) { // UTC time
|
279
274
|
parent->val = rb_time_nano_new(ni->i, (long)nsec);
|
280
|
-
// Since the ruby C routines
|
275
|
+
// Since the ruby C routines always create local time, the
|
281
276
|
// offset and then a conversion to UTC keeps makes the time
|
282
277
|
// match the expected value.
|
283
278
|
parent->val = rb_funcall2(parent->val, oj_utc_id, 0, 0);
|
284
279
|
} else if (ni->has_exp) {
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
sec_as_time(t, &ti);
|
290
|
-
args[0] = LONG2NUM((long)(ti.year));
|
291
|
-
args[1] = LONG2NUM(ti.mon);
|
292
|
-
args[2] = LONG2NUM(ti.day);
|
293
|
-
args[3] = LONG2NUM(ti.hour);
|
294
|
-
args[4] = LONG2NUM(ti.min);
|
295
|
-
args[5] = rb_float_new((double)ti.sec + ((double)nsec + 0.5) / 1000000000.0);
|
296
|
-
args[6] = LONG2NUM(ni->exp);
|
297
|
-
parent->val = rb_funcall2(rb_cTime, oj_new_id, 7, args);
|
280
|
+
struct timespec ts;
|
281
|
+
ts.tv_sec = ni->i;
|
282
|
+
ts.tv_nsec = nsec;
|
283
|
+
parent->val = rb_time_timespec_new(&ts, (int)ni->exp);
|
298
284
|
} else {
|
299
285
|
parent->val = rb_time_nano_new(ni->i, (long)nsec);
|
300
286
|
}
|
301
287
|
}
|
302
288
|
break;
|
303
|
-
case 'i':
|
304
|
-
if (!ni->infinity && !ni->neg && 1 == ni->div && 0 == ni->exp &&
|
305
|
-
0 != pi->circ_array) { // fixnum
|
289
|
+
case 'i': // circular index
|
290
|
+
if (!ni->infinity && !ni->neg && 1 == ni->div && 0 == ni->exp && 0 != pi->circ_array) { // fixnum
|
306
291
|
if (Qnil == parent->val) {
|
307
292
|
parent->val = rb_hash_new();
|
308
293
|
}
|
@@ -331,7 +316,7 @@ static int hat_value(ParseInfo pi, Val parent, const char *key, size_t klen, vol
|
|
331
316
|
oj_set_error_at(pi, oj_parse_error_class, __FILE__, __LINE__, "Invalid struct data");
|
332
317
|
return 1;
|
333
318
|
}
|
334
|
-
e1 = *
|
319
|
+
e1 = *RARRAY_CONST_PTR(value);
|
335
320
|
// check for anonymous Struct
|
336
321
|
if (T_ARRAY == rb_type(e1)) {
|
337
322
|
VALUE args[1024];
|
@@ -339,46 +324,50 @@ static int hat_value(ParseInfo pi, Val parent, const char *key, size_t klen, vol
|
|
339
324
|
int i, cnt = (int)RARRAY_LEN(e1);
|
340
325
|
|
341
326
|
for (i = 0; i < cnt; i++) {
|
342
|
-
rstr =
|
327
|
+
rstr = RARRAY_AREF(e1, i);
|
343
328
|
args[i] = rb_funcall(rstr, oj_to_sym_id, 0);
|
344
329
|
}
|
345
330
|
sc = rb_funcall2(rb_cStruct, oj_new_id, cnt, args);
|
346
331
|
} else {
|
347
332
|
// If struct is not defined then we let this fail and raise an exception.
|
348
|
-
sc = oj_name2struct(pi, *
|
333
|
+
sc = oj_name2struct(pi, *RARRAY_CONST_PTR(value), rb_eArgError);
|
349
334
|
}
|
350
|
-
|
351
|
-
|
352
|
-
|
335
|
+
if (sc == rb_cRange) {
|
336
|
+
parent->val = rb_class_new_instance(len - 1, RARRAY_CONST_PTR(value) + 1, rb_cRange);
|
337
|
+
} else {
|
338
|
+
// Create a properly initialized struct instance without calling the initialize method.
|
339
|
+
parent->val = rb_obj_alloc(sc);
|
340
|
+
// If the JSON array has more entries than the struct class allows, we record an error.
|
353
341
|
#ifdef RSTRUCT_LEN
|
354
342
|
#if RSTRUCT_LEN_RETURNS_INTEGER_OBJECT
|
355
|
-
|
343
|
+
slen = (int)NUM2LONG(RSTRUCT_LEN(parent->val));
|
356
344
|
#else // RSTRUCT_LEN_RETURNS_INTEGER_OBJECT
|
357
|
-
|
345
|
+
slen = (int)RSTRUCT_LEN(parent->val);
|
358
346
|
#endif // RSTRUCT_LEN_RETURNS_INTEGER_OBJECT
|
359
347
|
#else
|
360
|
-
|
348
|
+
slen = FIX2INT(rb_funcall2(parent->val, oj_length_id, 0, 0));
|
361
349
|
#endif
|
362
|
-
|
363
|
-
|
364
|
-
|
365
|
-
|
366
|
-
|
350
|
+
// MRI >= 1.9
|
351
|
+
if (len - 1 > slen) {
|
352
|
+
oj_set_error_at(pi, oj_parse_error_class, __FILE__, __LINE__, "Invalid struct data");
|
353
|
+
} else {
|
354
|
+
int i;
|
367
355
|
|
368
|
-
|
369
|
-
|
356
|
+
for (i = 0; i < len - 1; i++) {
|
357
|
+
rb_struct_aset(parent->val, INT2FIX(i), RARRAY_CONST_PTR(value)[i + 1]);
|
358
|
+
}
|
370
359
|
}
|
371
360
|
}
|
372
361
|
return 1;
|
373
362
|
} else if (3 <= klen && '#' == key[1]) {
|
374
|
-
volatile VALUE *a;
|
363
|
+
volatile const VALUE *a;
|
375
364
|
|
376
365
|
if (2 != len) {
|
377
366
|
oj_set_error_at(pi, oj_parse_error_class, __FILE__, __LINE__, "invalid hash pair");
|
378
367
|
return 1;
|
379
368
|
}
|
380
369
|
parent->val = rb_hash_new();
|
381
|
-
a =
|
370
|
+
a = RARRAY_CONST_PTR(value);
|
382
371
|
rb_hash_aset(parent->val, *a, a[1]);
|
383
372
|
|
384
373
|
return 1;
|
@@ -388,55 +377,17 @@ static int hat_value(ParseInfo pi, Val parent, const char *key, size_t klen, vol
|
|
388
377
|
}
|
389
378
|
|
390
379
|
void oj_set_obj_ivar(Val parent, Val kval, VALUE value) {
|
391
|
-
|
392
|
-
|
393
|
-
|
394
|
-
|
395
|
-
|
396
|
-
|
397
|
-
pthread_mutex_lock(&oj_cache_mutex);
|
398
|
-
#else
|
399
|
-
rb_mutex_lock(oj_cache_mutex);
|
400
|
-
#endif
|
401
|
-
if (0 == (var_id = oj_attr_hash_get(key, klen, &slot))) {
|
402
|
-
char attr[256];
|
403
|
-
|
404
|
-
if ((int)sizeof(attr) <= klen + 2) {
|
405
|
-
char *buf = ALLOC_N(char, klen + 2);
|
406
|
-
|
407
|
-
if ('~' == *key) {
|
408
|
-
strncpy(buf, key + 1, klen - 1);
|
409
|
-
buf[klen - 1] = '\0';
|
410
|
-
} else {
|
411
|
-
*buf = '@';
|
412
|
-
strncpy(buf + 1, key, klen);
|
413
|
-
buf[klen + 1] = '\0';
|
414
|
-
}
|
415
|
-
var_id = rb_intern(buf);
|
416
|
-
xfree(buf);
|
417
|
-
} else {
|
418
|
-
if ('~' == *key) {
|
419
|
-
strncpy(attr, key + 1, klen - 1);
|
420
|
-
attr[klen - 1] = '\0';
|
421
|
-
} else {
|
422
|
-
*attr = '@';
|
423
|
-
strncpy(attr + 1, key, klen);
|
424
|
-
attr[klen + 1] = '\0';
|
425
|
-
}
|
426
|
-
var_id = rb_intern(attr);
|
427
|
-
}
|
428
|
-
*slot = var_id;
|
380
|
+
if (kval->klen == 5 && strncmp("~mesg", kval->key, 5) == 0 && rb_obj_is_kind_of(parent->val, rb_eException)) {
|
381
|
+
parent->val = rb_funcall(parent->val, rb_intern("exception"), 1, value);
|
382
|
+
} else if (kval->klen == 3 && strncmp("~bt", kval->key, 3) == 0 && rb_obj_is_kind_of(parent->val, rb_eException)) {
|
383
|
+
rb_funcall(parent->val, rb_intern("set_backtrace"), 1, value);
|
384
|
+
} else {
|
385
|
+
rb_ivar_set(parent->val, oj_attr_intern(kval->key, kval->klen), value);
|
429
386
|
}
|
430
|
-
#ifdef HAVE_PTHREAD_MUTEX_INIT
|
431
|
-
pthread_mutex_unlock(&oj_cache_mutex);
|
432
|
-
#else
|
433
|
-
rb_mutex_unlock(oj_cache_mutex);
|
434
|
-
#endif
|
435
|
-
rb_ivar_set(parent->val, var_id, value);
|
436
387
|
}
|
437
388
|
|
438
389
|
static void hash_set_cstr(ParseInfo pi, Val kval, const char *str, size_t len, const char *orig) {
|
439
|
-
const char
|
390
|
+
const char *key = kval->key;
|
440
391
|
int klen = kval->klen;
|
441
392
|
Val parent = stack_peek(&pi->stack);
|
442
393
|
volatile VALUE rval = Qnil;
|
@@ -451,9 +402,7 @@ WHICH_TYPE:
|
|
451
402
|
}
|
452
403
|
break;
|
453
404
|
case T_HASH:
|
454
|
-
rb_hash_aset(parent->val,
|
455
|
-
calc_hash_key(pi, kval, parent->k1),
|
456
|
-
str_to_value(pi, str, len, orig));
|
405
|
+
rb_hash_aset(parent->val, calc_hash_key(pi, kval, parent->k1), str_to_value(pi, str, len, orig));
|
457
406
|
break;
|
458
407
|
case T_STRING:
|
459
408
|
rval = str_to_value(pi, str, len, orig);
|
@@ -505,13 +454,11 @@ WHICH_TYPE:
|
|
505
454
|
rb_class2name(rb_obj_class(parent->val)));
|
506
455
|
return;
|
507
456
|
}
|
508
|
-
|
509
|
-
oj_trace_parse_call("set_string", pi, __FILE__, __LINE__, rval);
|
510
|
-
}
|
457
|
+
TRACE_PARSE_CALL(pi->options.trace, "set_string", pi, rval);
|
511
458
|
}
|
512
459
|
|
513
460
|
static void hash_set_num(ParseInfo pi, Val kval, NumInfo ni) {
|
514
|
-
const char
|
461
|
+
const char *key = kval->key;
|
515
462
|
int klen = kval->klen;
|
516
463
|
Val parent = stack_peek(&pi->stack);
|
517
464
|
volatile VALUE rval = Qnil;
|
@@ -530,8 +477,8 @@ WHICH_TYPE:
|
|
530
477
|
rb_hash_aset(parent->val, calc_hash_key(pi, kval, parent->k1), rval);
|
531
478
|
break;
|
532
479
|
case T_OBJECT:
|
533
|
-
if (2 == klen && '^' == *key && 'i' == key[1] && !ni->infinity && !ni->neg &&
|
534
|
-
|
480
|
+
if (2 == klen && '^' == *key && 'i' == key[1] && !ni->infinity && !ni->neg && 1 == ni->div && 0 == ni->exp &&
|
481
|
+
0 != pi->circ_array) { // fixnum
|
535
482
|
oj_circ_array_set(pi->circ_array, parent->val, ni->i);
|
536
483
|
} else {
|
537
484
|
rval = oj_num_as_value(ni);
|
@@ -576,9 +523,7 @@ WHICH_TYPE:
|
|
576
523
|
rb_class2name(rb_obj_class(parent->val)));
|
577
524
|
return;
|
578
525
|
}
|
579
|
-
|
580
|
-
oj_trace_parse_call("add_number", pi, __FILE__, __LINE__, rval);
|
581
|
-
}
|
526
|
+
TRACE_PARSE_CALL(pi->options.trace, "add_number", pi, rval);
|
582
527
|
}
|
583
528
|
|
584
529
|
static void hash_set_value(ParseInfo pi, Val kval, VALUE value) {
|
@@ -604,15 +549,11 @@ WHICH_TYPE:
|
|
604
549
|
}
|
605
550
|
} else {
|
606
551
|
if (3 <= klen && '^' == *key && '#' == key[1] && T_ARRAY == rb_type(value)) {
|
607
|
-
long
|
608
|
-
volatile VALUE *a =
|
552
|
+
long len = RARRAY_LEN(value);
|
553
|
+
volatile const VALUE *a = RARRAY_CONST_PTR(value);
|
609
554
|
|
610
555
|
if (2 != len) {
|
611
|
-
oj_set_error_at(pi,
|
612
|
-
oj_parse_error_class,
|
613
|
-
__FILE__,
|
614
|
-
__LINE__,
|
615
|
-
"invalid hash pair");
|
556
|
+
oj_set_error_at(pi, oj_parse_error_class, __FILE__, __LINE__, "invalid hash pair");
|
616
557
|
return;
|
617
558
|
}
|
618
559
|
rb_hash_aset(parent->val, *a, a[1]);
|
@@ -666,15 +607,11 @@ WHICH_TYPE:
|
|
666
607
|
rb_class2name(rb_obj_class(parent->val)));
|
667
608
|
return;
|
668
609
|
}
|
669
|
-
|
670
|
-
oj_trace_parse_call("add_value", pi, __FILE__, __LINE__, value);
|
671
|
-
}
|
610
|
+
TRACE_PARSE_CALL(pi->options.trace, "add_value", pi, value);
|
672
611
|
}
|
673
612
|
|
674
613
|
static VALUE start_hash(ParseInfo pi) {
|
675
|
-
|
676
|
-
oj_trace_parse_in("start_hash", pi, __FILE__, __LINE__);
|
677
|
-
}
|
614
|
+
TRACE_PARSE_IN(pi->options.trace, "start_hash", pi);
|
678
615
|
return Qnil;
|
679
616
|
}
|
680
617
|
|
@@ -686,24 +623,18 @@ static void end_hash(ParseInfo pi) {
|
|
686
623
|
} else if (NULL != parent->odd_args) {
|
687
624
|
OddArgs oa = parent->odd_args;
|
688
625
|
|
689
|
-
parent->val = rb_funcall2(oa->odd->create_obj,
|
690
|
-
oa->odd->create_op,
|
691
|
-
oa->odd->attr_cnt,
|
692
|
-
oa->args);
|
626
|
+
parent->val = rb_funcall2(oa->odd->create_obj, oa->odd->create_op, oa->odd->attr_cnt, oa->args);
|
693
627
|
oj_odd_free(oa);
|
694
628
|
parent->odd_args = NULL;
|
695
629
|
}
|
696
|
-
|
697
|
-
oj_trace_parse_hash_end(pi, __FILE__, __LINE__);
|
698
|
-
}
|
630
|
+
TRACE_PARSE_HASH_END(pi->options.trace, pi);
|
699
631
|
}
|
700
632
|
|
701
633
|
static void array_append_cstr(ParseInfo pi, const char *str, size_t len, const char *orig) {
|
702
634
|
volatile VALUE rval = Qnil;
|
703
635
|
|
704
636
|
// orig lets us know whether the string was ^r1 or \u005er1
|
705
|
-
if (3 <= len && 0 != pi->circ_array && '^' == orig[0] &&
|
706
|
-
0 == rb_array_len(stack_peek(&pi->stack)->val)) {
|
637
|
+
if (3 <= len && 0 != pi->circ_array && '^' == orig[0] && 0 == rb_array_len(stack_peek(&pi->stack)->val)) {
|
707
638
|
if ('i' == str[1]) {
|
708
639
|
long i = read_long(str + 2, len - 2);
|
709
640
|
|
@@ -722,32 +653,24 @@ static void array_append_cstr(ParseInfo pi, const char *str, size_t len, const c
|
|
722
653
|
}
|
723
654
|
rval = str_to_value(pi, str, len, orig);
|
724
655
|
rb_ary_push(stack_peek(&pi->stack)->val, rval);
|
725
|
-
|
726
|
-
oj_trace_parse_call("append_string", pi, __FILE__, __LINE__, rval);
|
727
|
-
}
|
656
|
+
TRACE_PARSE_CALL(pi->options.trace, "append_string", pi, rval);
|
728
657
|
}
|
729
658
|
|
730
659
|
static void array_append_num(ParseInfo pi, NumInfo ni) {
|
731
660
|
volatile VALUE rval = oj_num_as_value(ni);
|
732
661
|
|
733
662
|
rb_ary_push(stack_peek(&pi->stack)->val, rval);
|
734
|
-
|
735
|
-
oj_trace_parse_call("append_number", pi, __FILE__, __LINE__, rval);
|
736
|
-
}
|
663
|
+
TRACE_PARSE_CALL(pi->options.trace, "append_number", pi, rval);
|
737
664
|
}
|
738
665
|
|
739
666
|
static void add_cstr(ParseInfo pi, const char *str, size_t len, const char *orig) {
|
740
667
|
pi->stack.head->val = str_to_value(pi, str, len, orig);
|
741
|
-
|
742
|
-
oj_trace_parse_call("add_string", pi, __FILE__, __LINE__, pi->stack.head->val);
|
743
|
-
}
|
668
|
+
TRACE_PARSE_CALL(pi->options.trace, "add_string", pi, pi->stack.head->val);
|
744
669
|
}
|
745
670
|
|
746
671
|
static void add_num(ParseInfo pi, NumInfo ni) {
|
747
672
|
pi->stack.head->val = oj_num_as_value(ni);
|
748
|
-
|
749
|
-
oj_trace_parse_call("add_num", pi, __FILE__, __LINE__, pi->stack.head->val);
|
750
|
-
}
|
673
|
+
TRACE_PARSE_CALL(pi->options.trace, "add_num", pi, pi->stack.head->val);
|
751
674
|
}
|
752
675
|
|
753
676
|
void oj_set_object_callbacks(ParseInfo pi) {
|