json 1.1.9 → 1.2.0
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of json might be problematic. Click here for more details.
- data/CHANGES +7 -0
- data/README +316 -34
- data/Rakefile +48 -28
- data/VERSION +1 -1
- data/ext/json/ext/generator/generator.c +21 -5
- data/ext/json/ext/generator/unicode.c +3 -3
- data/ext/json/ext/parser/parser.c +142 -91
- data/ext/json/ext/parser/parser.rl +68 -17
- data/ext/json/ext/parser/unicode.c +2 -2
- data/lib/json/common.rb +32 -17
- data/lib/json/pure/generator.rb +24 -10
- data/lib/json/pure/parser.rb +35 -1
- data/lib/json/version.rb +1 -1
- data/tests/test_json.rb +25 -17
- data/tests/test_json_encoding.rb +67 -0
- data/tests/test_json_generate.rb +21 -7
- data/tests/test_json_rails.rb +1 -1
- metadata +7 -6
- data/doc-main.txt +0 -283
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
1.
|
1
|
+
1.2.0
|
@@ -24,6 +24,8 @@
|
|
24
24
|
#ifdef HAVE_RUBY_ENCODING_H
|
25
25
|
#include "ruby/encoding.h"
|
26
26
|
#define FORCE_UTF8(obj) rb_enc_associate((obj), rb_utf8_encoding())
|
27
|
+
static VALUE mEncoding_UTF_8;
|
28
|
+
static ID i_encoding, i_encode;
|
27
29
|
#else
|
28
30
|
#define FORCE_UTF8(obj)
|
29
31
|
#endif
|
@@ -315,14 +317,14 @@ static VALUE mFloat_to_json(int argc, VALUE *argv, VALUE self)
|
|
315
317
|
rb_scan_args(argc, argv, "01*", &Vstate, &rest);
|
316
318
|
if (!NIL_P(Vstate)) Data_Get_Struct(Vstate, JSON_Generator_State, state);
|
317
319
|
if (isinf(value)) {
|
318
|
-
if (
|
320
|
+
if (state && state->allow_nan) {
|
319
321
|
result = rb_funcall(self, i_to_s, 0);
|
320
322
|
} else {
|
321
323
|
tmp = rb_funcall(self, i_to_s, 0);
|
322
324
|
rb_raise(eGeneratorError, "%u: %s not allowed in JSON", __LINE__, StringValueCStr(tmp));
|
323
325
|
}
|
324
326
|
} else if (isnan(value)) {
|
325
|
-
if (
|
327
|
+
if (state && state->allow_nan) {
|
326
328
|
result = rb_funcall(self, i_to_s, 0);
|
327
329
|
} else {
|
328
330
|
tmp = rb_funcall(self, i_to_s, 0);
|
@@ -357,7 +359,16 @@ static VALUE mString_to_json(int argc, VALUE *argv, VALUE self)
|
|
357
359
|
{
|
358
360
|
VALUE result = rb_str_buf_new(RSTRING_LEN(self));
|
359
361
|
rb_str_buf_cat2(result, "\"");
|
362
|
+
#ifdef HAVE_RUBY_ENCODING_H
|
363
|
+
if (rb_funcall(self, i_encoding, 0) == mEncoding_UTF_8) {
|
364
|
+
JSON_convert_UTF8_to_JSON(result, self, strictConversion);
|
365
|
+
} else {
|
366
|
+
VALUE string = rb_funcall(self, i_encode, 1, mEncoding_UTF_8);
|
367
|
+
JSON_convert_UTF8_to_JSON(result, string, strictConversion);
|
368
|
+
}
|
369
|
+
#else
|
360
370
|
JSON_convert_UTF8_to_JSON(result, self, strictConversion);
|
371
|
+
#endif
|
361
372
|
rb_str_buf_cat2(result, "\"");
|
362
373
|
FORCE_UTF8(result);
|
363
374
|
return result;
|
@@ -409,7 +420,7 @@ static VALUE mString_Extend_json_create(VALUE self, VALUE o) {
|
|
409
420
|
}
|
410
421
|
|
411
422
|
/*
|
412
|
-
* call-seq: to_json(
|
423
|
+
* call-seq: to_json(*)
|
413
424
|
*
|
414
425
|
* Returns a JSON string for true: 'true'.
|
415
426
|
*/
|
@@ -421,7 +432,7 @@ static VALUE mTrueClass_to_json(int argc, VALUE *argv, VALUE self)
|
|
421
432
|
}
|
422
433
|
|
423
434
|
/*
|
424
|
-
* call-seq: to_json(
|
435
|
+
* call-seq: to_json(*)
|
425
436
|
*
|
426
437
|
* Returns a JSON string for false: 'false'.
|
427
438
|
*/
|
@@ -433,7 +444,7 @@ static VALUE mFalseClass_to_json(int argc, VALUE *argv, VALUE self)
|
|
433
444
|
}
|
434
445
|
|
435
446
|
/*
|
436
|
-
* call-seq: to_json(
|
447
|
+
* call-seq: to_json(*)
|
437
448
|
*
|
438
449
|
*/
|
439
450
|
static VALUE mNilClass_to_json(int argc, VALUE *argv, VALUE self)
|
@@ -916,4 +927,9 @@ void Init_generator()
|
|
916
927
|
i_unpack = rb_intern("unpack");
|
917
928
|
i_create_id = rb_intern("create_id");
|
918
929
|
i_extend = rb_intern("extend");
|
930
|
+
#ifdef HAVE_RUBY_ENCODING_H
|
931
|
+
mEncoding_UTF_8 = rb_funcall(rb_path2class("Encoding"), rb_intern("find"), 1, rb_str_new2("utf-8"));
|
932
|
+
i_encoding = rb_intern("encoding");
|
933
|
+
i_encode = rb_intern("encode");
|
934
|
+
#endif
|
919
935
|
}
|
@@ -113,7 +113,7 @@ void JSON_convert_UTF8_to_JSON(VALUE buffer, VALUE string, ConversionFlags flags
|
|
113
113
|
}
|
114
114
|
if (!isLegalUTF8(source, extraBytesToRead+1)) {
|
115
115
|
rb_raise(rb_path2class("JSON::GeneratorError"),
|
116
|
-
"source sequence is illegal/malformed");
|
116
|
+
"source sequence is illegal/malformed utf-8");
|
117
117
|
}
|
118
118
|
/*
|
119
119
|
* The cases all fall through. See "Note A" below.
|
@@ -134,7 +134,7 @@ void JSON_convert_UTF8_to_JSON(VALUE buffer, VALUE string, ConversionFlags flags
|
|
134
134
|
if (flags == strictConversion) {
|
135
135
|
source -= (extraBytesToRead+1); /* return to the illegal value itself */
|
136
136
|
rb_raise(rb_path2class("JSON::GeneratorError"),
|
137
|
-
"source sequence is illegal/malformed");
|
137
|
+
"source sequence is illegal/malformed utf-8");
|
138
138
|
} else {
|
139
139
|
unicode_escape(buffer, UNI_REPLACEMENT_CHAR);
|
140
140
|
}
|
@@ -166,7 +166,7 @@ void JSON_convert_UTF8_to_JSON(VALUE buffer, VALUE string, ConversionFlags flags
|
|
166
166
|
if (flags == strictConversion) {
|
167
167
|
source -= (extraBytesToRead+1); /* return to the start */
|
168
168
|
rb_raise(rb_path2class("JSON::GeneratorError"),
|
169
|
-
"source sequence is illegal/malformed");
|
169
|
+
"source sequence is illegal/malformed utf8");
|
170
170
|
} else {
|
171
171
|
unicode_escape(buffer, UNI_REPLACEMENT_CHAR);
|
172
172
|
}
|
@@ -21,15 +21,19 @@
|
|
21
21
|
#ifdef HAVE_RUBY_ENCODING_H
|
22
22
|
#include "ruby/encoding.h"
|
23
23
|
#define FORCE_UTF8(obj) rb_enc_associate((obj), rb_utf8_encoding())
|
24
|
+
static VALUE mEncoding_ASCII_8BIT, mEncoding_UTF_8, mEncoding_UTF_16BE,
|
25
|
+
mEncoding_UTF_16LE, mEncoding_UTF_32BE, mEncoding_UTF_32LE;
|
26
|
+
static ID i_encoding, i_encode, i_encode_bang, i_force_encoding;
|
24
27
|
#else
|
25
28
|
#define FORCE_UTF8(obj)
|
29
|
+
static ID i_iconv;
|
26
30
|
#endif
|
27
31
|
|
28
32
|
static VALUE mJSON, mExt, cParser, eParserError, eNestingError;
|
29
33
|
static VALUE CNaN, CInfinity, CMinusInfinity;
|
30
34
|
|
31
35
|
static ID i_json_creatable_p, i_json_create, i_create_id, i_create_additions,
|
32
|
-
i_chr, i_max_nesting, i_allow_nan, i_object_class, i_array_class;
|
36
|
+
i_chr, i_max_nesting, i_allow_nan, i_object_class, i_array_class;
|
33
37
|
|
34
38
|
#define MinusInfinity "-Infinity"
|
35
39
|
|
@@ -58,11 +62,11 @@ static char *JSON_parse_float(JSON_Parser *json, char *p, char *pe, VALUE *resul
|
|
58
62
|
Data_Get_Struct(self, JSON_Parser, json);
|
59
63
|
|
60
64
|
|
61
|
-
#line
|
65
|
+
#line 88 "parser.rl"
|
62
66
|
|
63
67
|
|
64
68
|
|
65
|
-
#line
|
69
|
+
#line 70 "parser.c"
|
66
70
|
static const int JSON_object_start = 1;
|
67
71
|
static const int JSON_object_first_final = 27;
|
68
72
|
static const int JSON_object_error = 0;
|
@@ -70,7 +74,7 @@ static const int JSON_object_error = 0;
|
|
70
74
|
static const int JSON_object_en_main = 1;
|
71
75
|
|
72
76
|
|
73
|
-
#line
|
77
|
+
#line 121 "parser.rl"
|
74
78
|
|
75
79
|
|
76
80
|
static char *JSON_parse_object(JSON_Parser *json, char *p, char *pe, VALUE *result)
|
@@ -86,14 +90,14 @@ static char *JSON_parse_object(JSON_Parser *json, char *p, char *pe, VALUE *resu
|
|
86
90
|
*result = NIL_P(object_class) ? rb_hash_new() : rb_class_new_instance(0, 0, object_class);
|
87
91
|
|
88
92
|
|
89
|
-
#line
|
93
|
+
#line 94 "parser.c"
|
90
94
|
{
|
91
95
|
cs = JSON_object_start;
|
92
96
|
}
|
93
97
|
|
94
|
-
#line
|
98
|
+
#line 136 "parser.rl"
|
95
99
|
|
96
|
-
#line
|
100
|
+
#line 101 "parser.c"
|
97
101
|
{
|
98
102
|
if ( p == pe )
|
99
103
|
goto _test_eof;
|
@@ -121,7 +125,7 @@ case 2:
|
|
121
125
|
goto st2;
|
122
126
|
goto st0;
|
123
127
|
tr2:
|
124
|
-
#line
|
128
|
+
#line 107 "parser.rl"
|
125
129
|
{
|
126
130
|
char *np = JSON_parse_string(json, p, pe, &last_name);
|
127
131
|
if (np == NULL) { p--; {p++; cs = 3; goto _out;} } else {p = (( np))-1;}
|
@@ -131,7 +135,7 @@ st3:
|
|
131
135
|
if ( ++p == pe )
|
132
136
|
goto _test_eof3;
|
133
137
|
case 3:
|
134
|
-
#line
|
138
|
+
#line 139 "parser.c"
|
135
139
|
switch( (*p) ) {
|
136
140
|
case 13: goto st3;
|
137
141
|
case 32: goto st3;
|
@@ -198,7 +202,7 @@ case 8:
|
|
198
202
|
goto st8;
|
199
203
|
goto st0;
|
200
204
|
tr11:
|
201
|
-
#line
|
205
|
+
#line 96 "parser.rl"
|
202
206
|
{
|
203
207
|
VALUE v = Qnil;
|
204
208
|
char *np = JSON_parse_value(json, p, pe, &v);
|
@@ -214,7 +218,7 @@ st9:
|
|
214
218
|
if ( ++p == pe )
|
215
219
|
goto _test_eof9;
|
216
220
|
case 9:
|
217
|
-
#line
|
221
|
+
#line 222 "parser.c"
|
218
222
|
switch( (*p) ) {
|
219
223
|
case 13: goto st9;
|
220
224
|
case 32: goto st9;
|
@@ -303,14 +307,14 @@ case 18:
|
|
303
307
|
goto st9;
|
304
308
|
goto st18;
|
305
309
|
tr4:
|
306
|
-
#line
|
310
|
+
#line 112 "parser.rl"
|
307
311
|
{ p--; {p++; cs = 27; goto _out;} }
|
308
312
|
goto st27;
|
309
313
|
st27:
|
310
314
|
if ( ++p == pe )
|
311
315
|
goto _test_eof27;
|
312
316
|
case 27:
|
313
|
-
#line
|
317
|
+
#line 318 "parser.c"
|
314
318
|
goto st0;
|
315
319
|
st19:
|
316
320
|
if ( ++p == pe )
|
@@ -408,7 +412,7 @@ case 26:
|
|
408
412
|
_out: {}
|
409
413
|
}
|
410
414
|
|
411
|
-
#line
|
415
|
+
#line 137 "parser.rl"
|
412
416
|
|
413
417
|
if (cs >= JSON_object_first_final) {
|
414
418
|
if (RTEST(json->create_id)) {
|
@@ -427,7 +431,7 @@ case 26:
|
|
427
431
|
}
|
428
432
|
|
429
433
|
|
430
|
-
#line
|
434
|
+
#line 435 "parser.c"
|
431
435
|
static const int JSON_value_start = 1;
|
432
436
|
static const int JSON_value_first_final = 21;
|
433
437
|
static const int JSON_value_error = 0;
|
@@ -435,7 +439,7 @@ static const int JSON_value_error = 0;
|
|
435
439
|
static const int JSON_value_en_main = 1;
|
436
440
|
|
437
441
|
|
438
|
-
#line
|
442
|
+
#line 235 "parser.rl"
|
439
443
|
|
440
444
|
|
441
445
|
static char *JSON_parse_value(JSON_Parser *json, char *p, char *pe, VALUE *result)
|
@@ -443,14 +447,14 @@ static char *JSON_parse_value(JSON_Parser *json, char *p, char *pe, VALUE *resul
|
|
443
447
|
int cs = EVIL;
|
444
448
|
|
445
449
|
|
446
|
-
#line
|
450
|
+
#line 451 "parser.c"
|
447
451
|
{
|
448
452
|
cs = JSON_value_start;
|
449
453
|
}
|
450
454
|
|
451
|
-
#line
|
455
|
+
#line 242 "parser.rl"
|
452
456
|
|
453
|
-
#line
|
457
|
+
#line 458 "parser.c"
|
454
458
|
{
|
455
459
|
if ( p == pe )
|
456
460
|
goto _test_eof;
|
@@ -475,14 +479,14 @@ st0:
|
|
475
479
|
cs = 0;
|
476
480
|
goto _out;
|
477
481
|
tr0:
|
478
|
-
#line
|
482
|
+
#line 183 "parser.rl"
|
479
483
|
{
|
480
484
|
char *np = JSON_parse_string(json, p, pe, result);
|
481
485
|
if (np == NULL) { p--; {p++; cs = 21; goto _out;} } else {p = (( np))-1;}
|
482
486
|
}
|
483
487
|
goto st21;
|
484
488
|
tr2:
|
485
|
-
#line
|
489
|
+
#line 188 "parser.rl"
|
486
490
|
{
|
487
491
|
char *np;
|
488
492
|
if(pe > p + 9 && !strncmp(MinusInfinity, p, 9)) {
|
@@ -502,7 +506,7 @@ tr2:
|
|
502
506
|
}
|
503
507
|
goto st21;
|
504
508
|
tr5:
|
505
|
-
#line
|
509
|
+
#line 206 "parser.rl"
|
506
510
|
{
|
507
511
|
char *np;
|
508
512
|
json->current_nesting++;
|
@@ -512,7 +516,7 @@ tr5:
|
|
512
516
|
}
|
513
517
|
goto st21;
|
514
518
|
tr9:
|
515
|
-
#line
|
519
|
+
#line 214 "parser.rl"
|
516
520
|
{
|
517
521
|
char *np;
|
518
522
|
json->current_nesting++;
|
@@ -522,7 +526,7 @@ tr9:
|
|
522
526
|
}
|
523
527
|
goto st21;
|
524
528
|
tr16:
|
525
|
-
#line
|
529
|
+
#line 176 "parser.rl"
|
526
530
|
{
|
527
531
|
if (json->allow_nan) {
|
528
532
|
*result = CInfinity;
|
@@ -532,7 +536,7 @@ tr16:
|
|
532
536
|
}
|
533
537
|
goto st21;
|
534
538
|
tr18:
|
535
|
-
#line
|
539
|
+
#line 169 "parser.rl"
|
536
540
|
{
|
537
541
|
if (json->allow_nan) {
|
538
542
|
*result = CNaN;
|
@@ -542,19 +546,19 @@ tr18:
|
|
542
546
|
}
|
543
547
|
goto st21;
|
544
548
|
tr22:
|
545
|
-
#line
|
549
|
+
#line 163 "parser.rl"
|
546
550
|
{
|
547
551
|
*result = Qfalse;
|
548
552
|
}
|
549
553
|
goto st21;
|
550
554
|
tr25:
|
551
|
-
#line
|
555
|
+
#line 160 "parser.rl"
|
552
556
|
{
|
553
557
|
*result = Qnil;
|
554
558
|
}
|
555
559
|
goto st21;
|
556
560
|
tr28:
|
557
|
-
#line
|
561
|
+
#line 166 "parser.rl"
|
558
562
|
{
|
559
563
|
*result = Qtrue;
|
560
564
|
}
|
@@ -563,9 +567,9 @@ st21:
|
|
563
567
|
if ( ++p == pe )
|
564
568
|
goto _test_eof21;
|
565
569
|
case 21:
|
566
|
-
#line
|
570
|
+
#line 222 "parser.rl"
|
567
571
|
{ p--; {p++; cs = 21; goto _out;} }
|
568
|
-
#line
|
572
|
+
#line 573 "parser.c"
|
569
573
|
goto st0;
|
570
574
|
st2:
|
571
575
|
if ( ++p == pe )
|
@@ -726,7 +730,7 @@ case 20:
|
|
726
730
|
_out: {}
|
727
731
|
}
|
728
732
|
|
729
|
-
#line
|
733
|
+
#line 243 "parser.rl"
|
730
734
|
|
731
735
|
if (cs >= JSON_value_first_final) {
|
732
736
|
return p;
|
@@ -736,7 +740,7 @@ case 20:
|
|
736
740
|
}
|
737
741
|
|
738
742
|
|
739
|
-
#line
|
743
|
+
#line 744 "parser.c"
|
740
744
|
static const int JSON_integer_start = 1;
|
741
745
|
static const int JSON_integer_first_final = 5;
|
742
746
|
static const int JSON_integer_error = 0;
|
@@ -744,7 +748,7 @@ static const int JSON_integer_error = 0;
|
|
744
748
|
static const int JSON_integer_en_main = 1;
|
745
749
|
|
746
750
|
|
747
|
-
#line
|
751
|
+
#line 259 "parser.rl"
|
748
752
|
|
749
753
|
|
750
754
|
static char *JSON_parse_integer(JSON_Parser *json, char *p, char *pe, VALUE *result)
|
@@ -752,15 +756,15 @@ static char *JSON_parse_integer(JSON_Parser *json, char *p, char *pe, VALUE *res
|
|
752
756
|
int cs = EVIL;
|
753
757
|
|
754
758
|
|
755
|
-
#line
|
759
|
+
#line 760 "parser.c"
|
756
760
|
{
|
757
761
|
cs = JSON_integer_start;
|
758
762
|
}
|
759
763
|
|
760
|
-
#line
|
764
|
+
#line 266 "parser.rl"
|
761
765
|
json->memo = p;
|
762
766
|
|
763
|
-
#line
|
767
|
+
#line 768 "parser.c"
|
764
768
|
{
|
765
769
|
if ( p == pe )
|
766
770
|
goto _test_eof;
|
@@ -794,14 +798,14 @@ case 3:
|
|
794
798
|
goto st0;
|
795
799
|
goto tr4;
|
796
800
|
tr4:
|
797
|
-
#line
|
801
|
+
#line 256 "parser.rl"
|
798
802
|
{ p--; {p++; cs = 5; goto _out;} }
|
799
803
|
goto st5;
|
800
804
|
st5:
|
801
805
|
if ( ++p == pe )
|
802
806
|
goto _test_eof5;
|
803
807
|
case 5:
|
804
|
-
#line
|
808
|
+
#line 809 "parser.c"
|
805
809
|
goto st0;
|
806
810
|
st4:
|
807
811
|
if ( ++p == pe )
|
@@ -820,7 +824,7 @@ case 4:
|
|
820
824
|
_out: {}
|
821
825
|
}
|
822
826
|
|
823
|
-
#line
|
827
|
+
#line 268 "parser.rl"
|
824
828
|
|
825
829
|
if (cs >= JSON_integer_first_final) {
|
826
830
|
long len = p - json->memo;
|
@@ -832,7 +836,7 @@ case 4:
|
|
832
836
|
}
|
833
837
|
|
834
838
|
|
835
|
-
#line
|
839
|
+
#line 840 "parser.c"
|
836
840
|
static const int JSON_float_start = 1;
|
837
841
|
static const int JSON_float_first_final = 10;
|
838
842
|
static const int JSON_float_error = 0;
|
@@ -840,7 +844,7 @@ static const int JSON_float_error = 0;
|
|
840
844
|
static const int JSON_float_en_main = 1;
|
841
845
|
|
842
846
|
|
843
|
-
#line
|
847
|
+
#line 290 "parser.rl"
|
844
848
|
|
845
849
|
|
846
850
|
static char *JSON_parse_float(JSON_Parser *json, char *p, char *pe, VALUE *result)
|
@@ -848,15 +852,15 @@ static char *JSON_parse_float(JSON_Parser *json, char *p, char *pe, VALUE *resul
|
|
848
852
|
int cs = EVIL;
|
849
853
|
|
850
854
|
|
851
|
-
#line
|
855
|
+
#line 856 "parser.c"
|
852
856
|
{
|
853
857
|
cs = JSON_float_start;
|
854
858
|
}
|
855
859
|
|
856
|
-
#line
|
860
|
+
#line 297 "parser.rl"
|
857
861
|
json->memo = p;
|
858
862
|
|
859
|
-
#line
|
863
|
+
#line 864 "parser.c"
|
860
864
|
{
|
861
865
|
if ( p == pe )
|
862
866
|
goto _test_eof;
|
@@ -914,14 +918,14 @@ case 5:
|
|
914
918
|
goto st0;
|
915
919
|
goto tr7;
|
916
920
|
tr7:
|
917
|
-
#line
|
921
|
+
#line 284 "parser.rl"
|
918
922
|
{ p--; {p++; cs = 10; goto _out;} }
|
919
923
|
goto st10;
|
920
924
|
st10:
|
921
925
|
if ( ++p == pe )
|
922
926
|
goto _test_eof10;
|
923
927
|
case 10:
|
924
|
-
#line
|
928
|
+
#line 929 "parser.c"
|
925
929
|
goto st0;
|
926
930
|
st6:
|
927
931
|
if ( ++p == pe )
|
@@ -982,7 +986,7 @@ case 9:
|
|
982
986
|
_out: {}
|
983
987
|
}
|
984
988
|
|
985
|
-
#line
|
989
|
+
#line 299 "parser.rl"
|
986
990
|
|
987
991
|
if (cs >= JSON_float_first_final) {
|
988
992
|
long len = p - json->memo;
|
@@ -995,7 +999,7 @@ case 9:
|
|
995
999
|
|
996
1000
|
|
997
1001
|
|
998
|
-
#line
|
1002
|
+
#line 1003 "parser.c"
|
999
1003
|
static const int JSON_array_start = 1;
|
1000
1004
|
static const int JSON_array_first_final = 17;
|
1001
1005
|
static const int JSON_array_error = 0;
|
@@ -1003,7 +1007,7 @@ static const int JSON_array_error = 0;
|
|
1003
1007
|
static const int JSON_array_en_main = 1;
|
1004
1008
|
|
1005
1009
|
|
1006
|
-
#line
|
1010
|
+
#line 335 "parser.rl"
|
1007
1011
|
|
1008
1012
|
|
1009
1013
|
static char *JSON_parse_array(JSON_Parser *json, char *p, char *pe, VALUE *result)
|
@@ -1017,14 +1021,14 @@ static char *JSON_parse_array(JSON_Parser *json, char *p, char *pe, VALUE *resul
|
|
1017
1021
|
*result = NIL_P(array_class) ? rb_ary_new() : rb_class_new_instance(0, 0, array_class);
|
1018
1022
|
|
1019
1023
|
|
1020
|
-
#line
|
1024
|
+
#line 1025 "parser.c"
|
1021
1025
|
{
|
1022
1026
|
cs = JSON_array_start;
|
1023
1027
|
}
|
1024
1028
|
|
1025
|
-
#line
|
1029
|
+
#line 348 "parser.rl"
|
1026
1030
|
|
1027
|
-
#line
|
1031
|
+
#line 1032 "parser.c"
|
1028
1032
|
{
|
1029
1033
|
if ( p == pe )
|
1030
1034
|
goto _test_eof;
|
@@ -1063,7 +1067,7 @@ case 2:
|
|
1063
1067
|
goto st2;
|
1064
1068
|
goto st0;
|
1065
1069
|
tr2:
|
1066
|
-
#line
|
1070
|
+
#line 316 "parser.rl"
|
1067
1071
|
{
|
1068
1072
|
VALUE v = Qnil;
|
1069
1073
|
char *np = JSON_parse_value(json, p, pe, &v);
|
@@ -1079,7 +1083,7 @@ st3:
|
|
1079
1083
|
if ( ++p == pe )
|
1080
1084
|
goto _test_eof3;
|
1081
1085
|
case 3:
|
1082
|
-
#line
|
1086
|
+
#line 1087 "parser.c"
|
1083
1087
|
switch( (*p) ) {
|
1084
1088
|
case 13: goto st3;
|
1085
1089
|
case 32: goto st3;
|
@@ -1179,14 +1183,14 @@ case 12:
|
|
1179
1183
|
goto st3;
|
1180
1184
|
goto st12;
|
1181
1185
|
tr4:
|
1182
|
-
#line
|
1186
|
+
#line 327 "parser.rl"
|
1183
1187
|
{ p--; {p++; cs = 17; goto _out;} }
|
1184
1188
|
goto st17;
|
1185
1189
|
st17:
|
1186
1190
|
if ( ++p == pe )
|
1187
1191
|
goto _test_eof17;
|
1188
1192
|
case 17:
|
1189
|
-
#line
|
1193
|
+
#line 1194 "parser.c"
|
1190
1194
|
goto st0;
|
1191
1195
|
st13:
|
1192
1196
|
if ( ++p == pe )
|
@@ -1242,7 +1246,7 @@ case 16:
|
|
1242
1246
|
_out: {}
|
1243
1247
|
}
|
1244
1248
|
|
1245
|
-
#line
|
1249
|
+
#line 349 "parser.rl"
|
1246
1250
|
|
1247
1251
|
if(cs >= JSON_array_first_final) {
|
1248
1252
|
return p + 1;
|
@@ -1308,7 +1312,7 @@ static VALUE json_string_unescape(char *p, char *pe)
|
|
1308
1312
|
}
|
1309
1313
|
|
1310
1314
|
|
1311
|
-
#line
|
1315
|
+
#line 1316 "parser.c"
|
1312
1316
|
static const int JSON_string_start = 1;
|
1313
1317
|
static const int JSON_string_first_final = 8;
|
1314
1318
|
static const int JSON_string_error = 0;
|
@@ -1316,7 +1320,7 @@ static const int JSON_string_error = 0;
|
|
1316
1320
|
static const int JSON_string_en_main = 1;
|
1317
1321
|
|
1318
1322
|
|
1319
|
-
#line
|
1323
|
+
#line 433 "parser.rl"
|
1320
1324
|
|
1321
1325
|
|
1322
1326
|
static char *JSON_parse_string(JSON_Parser *json, char *p, char *pe, VALUE *result)
|
@@ -1325,15 +1329,15 @@ static char *JSON_parse_string(JSON_Parser *json, char *p, char *pe, VALUE *resu
|
|
1325
1329
|
|
1326
1330
|
*result = rb_str_new("", 0);
|
1327
1331
|
|
1328
|
-
#line
|
1332
|
+
#line 1333 "parser.c"
|
1329
1333
|
{
|
1330
1334
|
cs = JSON_string_start;
|
1331
1335
|
}
|
1332
1336
|
|
1333
|
-
#line
|
1337
|
+
#line 441 "parser.rl"
|
1334
1338
|
json->memo = p;
|
1335
1339
|
|
1336
|
-
#line
|
1340
|
+
#line 1341 "parser.c"
|
1337
1341
|
{
|
1338
1342
|
if ( p == pe )
|
1339
1343
|
goto _test_eof;
|
@@ -1358,7 +1362,7 @@ case 2:
|
|
1358
1362
|
goto st0;
|
1359
1363
|
goto st2;
|
1360
1364
|
tr2:
|
1361
|
-
#line
|
1365
|
+
#line 419 "parser.rl"
|
1362
1366
|
{
|
1363
1367
|
*result = json_string_unescape(json->memo + 1, p);
|
1364
1368
|
if (NIL_P(*result)) {
|
@@ -1369,14 +1373,14 @@ tr2:
|
|
1369
1373
|
{p = (( p + 1))-1;}
|
1370
1374
|
}
|
1371
1375
|
}
|
1372
|
-
#line
|
1376
|
+
#line 430 "parser.rl"
|
1373
1377
|
{ p--; {p++; cs = 8; goto _out;} }
|
1374
1378
|
goto st8;
|
1375
1379
|
st8:
|
1376
1380
|
if ( ++p == pe )
|
1377
1381
|
goto _test_eof8;
|
1378
1382
|
case 8:
|
1379
|
-
#line
|
1383
|
+
#line 1384 "parser.c"
|
1380
1384
|
goto st0;
|
1381
1385
|
st3:
|
1382
1386
|
if ( ++p == pe )
|
@@ -1452,7 +1456,7 @@ case 7:
|
|
1452
1456
|
_out: {}
|
1453
1457
|
}
|
1454
1458
|
|
1455
|
-
#line
|
1459
|
+
#line 443 "parser.rl"
|
1456
1460
|
|
1457
1461
|
if (cs >= JSON_string_first_final) {
|
1458
1462
|
return p + 1;
|
@@ -1463,7 +1467,7 @@ case 7:
|
|
1463
1467
|
|
1464
1468
|
|
1465
1469
|
|
1466
|
-
#line
|
1470
|
+
#line 1471 "parser.c"
|
1467
1471
|
static const int JSON_start = 1;
|
1468
1472
|
static const int JSON_first_final = 10;
|
1469
1473
|
static const int JSON_error = 0;
|
@@ -1471,7 +1475,7 @@ static const int JSON_error = 0;
|
|
1471
1475
|
static const int JSON_en_main = 1;
|
1472
1476
|
|
1473
1477
|
|
1474
|
-
#line
|
1478
|
+
#line 477 "parser.rl"
|
1475
1479
|
|
1476
1480
|
|
1477
1481
|
/*
|
@@ -1486,6 +1490,54 @@ static const int JSON_en_main = 1;
|
|
1486
1490
|
*
|
1487
1491
|
*/
|
1488
1492
|
|
1493
|
+
inline static VALUE convert_encoding(VALUE source)
|
1494
|
+
{
|
1495
|
+
char *ptr = RSTRING_PTR(source);
|
1496
|
+
long len = RSTRING_LEN(source);
|
1497
|
+
if (len < 2) {
|
1498
|
+
rb_raise(eParserError, "A JSON text must at least contain two octets!");
|
1499
|
+
}
|
1500
|
+
#ifdef HAVE_RUBY_ENCODING_H
|
1501
|
+
{
|
1502
|
+
VALUE encoding = rb_funcall(source, i_encoding, 0);
|
1503
|
+
if (encoding == mEncoding_ASCII_8BIT) {
|
1504
|
+
if (len >= 4 && ptr[0] == 0 && ptr[1] == 0 && ptr[2] == 0) {
|
1505
|
+
source = rb_str_dup(source);
|
1506
|
+
rb_funcall(source, i_force_encoding, 1, mEncoding_UTF_32BE);
|
1507
|
+
source = rb_funcall(source, i_encode_bang, 1, mEncoding_UTF_8);
|
1508
|
+
} else if (len >= 4 && ptr[0] == 0 && ptr[2] == 0) {
|
1509
|
+
source = rb_str_dup(source);
|
1510
|
+
rb_funcall(source, i_force_encoding, 1, mEncoding_UTF_16BE);
|
1511
|
+
source = rb_funcall(source, i_encode_bang, 1, mEncoding_UTF_8);
|
1512
|
+
} else if (len >= 4 && ptr[1] == 0 && ptr[2] == 0 && ptr[3] == 0) {
|
1513
|
+
source = rb_str_dup(source);
|
1514
|
+
rb_funcall(source, i_force_encoding, 1, mEncoding_UTF_32LE);
|
1515
|
+
source = rb_funcall(source, i_encode_bang, 1, mEncoding_UTF_8);
|
1516
|
+
} else if (len >= 4 && ptr[1] == 0 && ptr[3] == 0) {
|
1517
|
+
source = rb_str_dup(source);
|
1518
|
+
rb_funcall(source, i_force_encoding, 1, mEncoding_UTF_16LE);
|
1519
|
+
source = rb_funcall(source, i_encode_bang, 1, mEncoding_UTF_8);
|
1520
|
+
} else {
|
1521
|
+
source = rb_funcall(source, i_force_encoding, 1, mEncoding_UTF_8);
|
1522
|
+
}
|
1523
|
+
} else {
|
1524
|
+
source = rb_funcall(source, i_encode, 1, mEncoding_UTF_8);
|
1525
|
+
}
|
1526
|
+
}
|
1527
|
+
#else
|
1528
|
+
if (len >= 4 && ptr[0] == 0 && ptr[1] == 0 && ptr[2] == 0) {
|
1529
|
+
source = rb_funcall(mJSON, i_iconv, 3, rb_str_new2("utf-8"), rb_str_new2("utf-32be"), source);
|
1530
|
+
} else if (len >= 4 && ptr[0] == 0 && ptr[2] == 0) {
|
1531
|
+
source = rb_funcall(mJSON, i_iconv, 3, rb_str_new2("utf-8"), rb_str_new2("utf-16be"), source);
|
1532
|
+
} else if (len >= 4 && ptr[1] == 0 && ptr[2] == 0 && ptr[3] == 0) {
|
1533
|
+
source = rb_funcall(mJSON, i_iconv, 3, rb_str_new2("utf-8"), rb_str_new2("utf-32le"), source);
|
1534
|
+
} else if (len >= 4 && ptr[1] == 0 && ptr[3] == 0) {
|
1535
|
+
source = rb_funcall(mJSON, i_iconv, 3, rb_str_new2("utf-8"), rb_str_new2("utf-16le"), source);
|
1536
|
+
}
|
1537
|
+
#endif
|
1538
|
+
return source;
|
1539
|
+
}
|
1540
|
+
|
1489
1541
|
/*
|
1490
1542
|
* call-seq: new(source, opts => {})
|
1491
1543
|
*
|
@@ -1516,12 +1568,9 @@ static VALUE cParser_initialize(int argc, VALUE *argv, VALUE self)
|
|
1516
1568
|
VALUE source, opts;
|
1517
1569
|
GET_STRUCT;
|
1518
1570
|
rb_scan_args(argc, argv, "11", &source, &opts);
|
1519
|
-
source = StringValue(source);
|
1571
|
+
source = convert_encoding(StringValue(source));
|
1520
1572
|
ptr = RSTRING_PTR(source);
|
1521
1573
|
len = RSTRING_LEN(source);
|
1522
|
-
if (len < 2) {
|
1523
|
-
rb_raise(eParserError, "A JSON text must at least contain two octets!");
|
1524
|
-
}
|
1525
1574
|
if (!NIL_P(opts)) {
|
1526
1575
|
opts = rb_convert_type(opts, T_HASH, "Hash", "to_hash");
|
1527
1576
|
if (NIL_P(opts)) {
|
@@ -1578,18 +1627,6 @@ static VALUE cParser_initialize(int argc, VALUE *argv, VALUE self)
|
|
1578
1627
|
json->array_class = Qnil;
|
1579
1628
|
}
|
1580
1629
|
json->current_nesting = 0;
|
1581
|
-
/*
|
1582
|
-
Convert these?
|
1583
|
-
if (len >= 4 && ptr[0] == 0 && ptr[1] == 0 && ptr[2] == 0) {
|
1584
|
-
rb_raise(eParserError, "Only UTF8 octet streams are supported atm!");
|
1585
|
-
} else if (len >= 4 && ptr[0] == 0 && ptr[2] == 0) {
|
1586
|
-
rb_raise(eParserError, "Only UTF8 octet streams are supported atm!");
|
1587
|
-
} else if (len >= 4 && ptr[1] == 0 && ptr[2] == 0 && ptr[3] == 0) {
|
1588
|
-
rb_raise(eParserError, "Only UTF8 octet streams are supported atm!");
|
1589
|
-
} else if (len >= 4 && ptr[1] == 0 && ptr[3] == 0) {
|
1590
|
-
rb_raise(eParserError, "Only UTF8 octet streams are supported atm!");
|
1591
|
-
}
|
1592
|
-
*/
|
1593
1630
|
json->len = len;
|
1594
1631
|
json->source = ptr;
|
1595
1632
|
json->Vsource = source;
|
@@ -1610,16 +1647,16 @@ static VALUE cParser_parse(VALUE self)
|
|
1610
1647
|
GET_STRUCT;
|
1611
1648
|
|
1612
1649
|
|
1613
|
-
#line
|
1650
|
+
#line 1651 "parser.c"
|
1614
1651
|
{
|
1615
1652
|
cs = JSON_start;
|
1616
1653
|
}
|
1617
1654
|
|
1618
|
-
#line
|
1655
|
+
#line 648 "parser.rl"
|
1619
1656
|
p = json->source;
|
1620
1657
|
pe = p + json->len;
|
1621
1658
|
|
1622
|
-
#line
|
1659
|
+
#line 1660 "parser.c"
|
1623
1660
|
{
|
1624
1661
|
if ( p == pe )
|
1625
1662
|
goto _test_eof;
|
@@ -1675,7 +1712,7 @@ case 5:
|
|
1675
1712
|
goto st1;
|
1676
1713
|
goto st5;
|
1677
1714
|
tr3:
|
1678
|
-
#line
|
1715
|
+
#line 466 "parser.rl"
|
1679
1716
|
{
|
1680
1717
|
char *np;
|
1681
1718
|
json->current_nesting = 1;
|
@@ -1684,7 +1721,7 @@ tr3:
|
|
1684
1721
|
}
|
1685
1722
|
goto st10;
|
1686
1723
|
tr4:
|
1687
|
-
#line
|
1724
|
+
#line 459 "parser.rl"
|
1688
1725
|
{
|
1689
1726
|
char *np;
|
1690
1727
|
json->current_nesting = 1;
|
@@ -1696,7 +1733,7 @@ st10:
|
|
1696
1733
|
if ( ++p == pe )
|
1697
1734
|
goto _test_eof10;
|
1698
1735
|
case 10:
|
1699
|
-
#line
|
1736
|
+
#line 1737 "parser.c"
|
1700
1737
|
switch( (*p) ) {
|
1701
1738
|
case 13: goto st10;
|
1702
1739
|
case 32: goto st10;
|
@@ -1753,7 +1790,7 @@ case 9:
|
|
1753
1790
|
_out: {}
|
1754
1791
|
}
|
1755
1792
|
|
1756
|
-
#line
|
1793
|
+
#line 651 "parser.rl"
|
1757
1794
|
|
1758
1795
|
if (cs >= JSON_first_final && p == pe) {
|
1759
1796
|
return result;
|
@@ -1826,4 +1863,18 @@ void Init_parser()
|
|
1826
1863
|
i_allow_nan = rb_intern("allow_nan");
|
1827
1864
|
i_object_class = rb_intern("object_class");
|
1828
1865
|
i_array_class = rb_intern("array_class");
|
1866
|
+
#ifdef HAVE_RUBY_ENCODING_H
|
1867
|
+
mEncoding_UTF_8 = rb_funcall(rb_path2class("Encoding"), rb_intern("find"), 1, rb_str_new2("utf-8"));
|
1868
|
+
mEncoding_UTF_16BE = rb_funcall(rb_path2class("Encoding"), rb_intern("find"), 1, rb_str_new2("utf-16be"));
|
1869
|
+
mEncoding_UTF_16LE = rb_funcall(rb_path2class("Encoding"), rb_intern("find"), 1, rb_str_new2("utf-16le"));
|
1870
|
+
mEncoding_UTF_32BE = rb_funcall(rb_path2class("Encoding"), rb_intern("find"), 1, rb_str_new2("utf-32be"));
|
1871
|
+
mEncoding_UTF_32LE = rb_funcall(rb_path2class("Encoding"), rb_intern("find"), 1, rb_str_new2("utf-32le"));
|
1872
|
+
mEncoding_ASCII_8BIT = rb_funcall(rb_path2class("Encoding"), rb_intern("find"), 1, rb_str_new2("ascii-8bit"));
|
1873
|
+
i_encoding = rb_intern("encoding");
|
1874
|
+
i_encode = rb_intern("encode");
|
1875
|
+
i_encode_bang = rb_intern("encode!");
|
1876
|
+
i_force_encoding = rb_intern("force_encoding");
|
1877
|
+
#else
|
1878
|
+
i_iconv = rb_intern("iconv");
|
1879
|
+
#endif
|
1829
1880
|
}
|