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/VERSION CHANGED
@@ -1 +1 @@
1
- 1.1.9
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 (!state || state->allow_nan) {
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 (!state || state->allow_nan) {
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(state = nil, depth = 0)
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(state = nil, depth = 0)
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(state = nil, depth = 0)
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 84 "parser.rl"
65
+ #line 88 "parser.rl"
62
66
 
63
67
 
64
68
 
65
- #line 66 "parser.c"
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 117 "parser.rl"
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 90 "parser.c"
93
+ #line 94 "parser.c"
90
94
  {
91
95
  cs = JSON_object_start;
92
96
  }
93
97
 
94
- #line 132 "parser.rl"
98
+ #line 136 "parser.rl"
95
99
 
96
- #line 97 "parser.c"
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 103 "parser.rl"
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 135 "parser.c"
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 92 "parser.rl"
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 218 "parser.c"
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 108 "parser.rl"
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 314 "parser.c"
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 133 "parser.rl"
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 431 "parser.c"
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 231 "parser.rl"
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 447 "parser.c"
450
+ #line 451 "parser.c"
447
451
  {
448
452
  cs = JSON_value_start;
449
453
  }
450
454
 
451
- #line 238 "parser.rl"
455
+ #line 242 "parser.rl"
452
456
 
453
- #line 454 "parser.c"
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 179 "parser.rl"
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 184 "parser.rl"
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 202 "parser.rl"
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 210 "parser.rl"
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 172 "parser.rl"
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 165 "parser.rl"
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 159 "parser.rl"
549
+ #line 163 "parser.rl"
546
550
  {
547
551
  *result = Qfalse;
548
552
  }
549
553
  goto st21;
550
554
  tr25:
551
- #line 156 "parser.rl"
555
+ #line 160 "parser.rl"
552
556
  {
553
557
  *result = Qnil;
554
558
  }
555
559
  goto st21;
556
560
  tr28:
557
- #line 162 "parser.rl"
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 218 "parser.rl"
570
+ #line 222 "parser.rl"
567
571
  { p--; {p++; cs = 21; goto _out;} }
568
- #line 569 "parser.c"
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 239 "parser.rl"
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 740 "parser.c"
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 255 "parser.rl"
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 756 "parser.c"
759
+ #line 760 "parser.c"
756
760
  {
757
761
  cs = JSON_integer_start;
758
762
  }
759
763
 
760
- #line 262 "parser.rl"
764
+ #line 266 "parser.rl"
761
765
  json->memo = p;
762
766
 
763
- #line 764 "parser.c"
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 252 "parser.rl"
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 805 "parser.c"
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 264 "parser.rl"
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 836 "parser.c"
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 286 "parser.rl"
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 852 "parser.c"
855
+ #line 856 "parser.c"
852
856
  {
853
857
  cs = JSON_float_start;
854
858
  }
855
859
 
856
- #line 293 "parser.rl"
860
+ #line 297 "parser.rl"
857
861
  json->memo = p;
858
862
 
859
- #line 860 "parser.c"
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 280 "parser.rl"
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 925 "parser.c"
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 295 "parser.rl"
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 999 "parser.c"
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 331 "parser.rl"
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 1021 "parser.c"
1024
+ #line 1025 "parser.c"
1021
1025
  {
1022
1026
  cs = JSON_array_start;
1023
1027
  }
1024
1028
 
1025
- #line 344 "parser.rl"
1029
+ #line 348 "parser.rl"
1026
1030
 
1027
- #line 1028 "parser.c"
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 312 "parser.rl"
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 1083 "parser.c"
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 323 "parser.rl"
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 1190 "parser.c"
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 345 "parser.rl"
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 1312 "parser.c"
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 429 "parser.rl"
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 1329 "parser.c"
1332
+ #line 1333 "parser.c"
1329
1333
  {
1330
1334
  cs = JSON_string_start;
1331
1335
  }
1332
1336
 
1333
- #line 437 "parser.rl"
1337
+ #line 441 "parser.rl"
1334
1338
  json->memo = p;
1335
1339
 
1336
- #line 1337 "parser.c"
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 415 "parser.rl"
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 426 "parser.rl"
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 1380 "parser.c"
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 439 "parser.rl"
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 1467 "parser.c"
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 473 "parser.rl"
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 1614 "parser.c"
1650
+ #line 1651 "parser.c"
1614
1651
  {
1615
1652
  cs = JSON_start;
1616
1653
  }
1617
1654
 
1618
- #line 611 "parser.rl"
1655
+ #line 648 "parser.rl"
1619
1656
  p = json->source;
1620
1657
  pe = p + json->len;
1621
1658
 
1622
- #line 1623 "parser.c"
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 462 "parser.rl"
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 455 "parser.rl"
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 1700 "parser.c"
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 614 "parser.rl"
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
  }