json_pure 1.1.9 → 1.2.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
}
|