json_pure 1.8.6 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (65) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +0 -1
  3. data/.travis.yml +5 -3
  4. data/CHANGES +5 -5
  5. data/Gemfile +3 -1
  6. data/README.md +131 -84
  7. data/Rakefile +17 -10
  8. data/VERSION +1 -1
  9. data/ext/json/ext/generator/generator.c +1 -52
  10. data/ext/json/ext/generator/generator.h +0 -5
  11. data/ext/json/ext/parser/extconf.rb +3 -0
  12. data/ext/json/ext/parser/parser.c +304 -458
  13. data/ext/json/ext/parser/parser.h +0 -1
  14. data/ext/json/ext/parser/parser.rl +35 -152
  15. data/ext/json/extconf.rb +0 -1
  16. data/java/src/json/ext/Generator.java +2 -5
  17. data/java/src/json/ext/GeneratorState.java +2 -54
  18. data/java/src/json/ext/OptionsReader.java +1 -1
  19. data/java/src/json/ext/Parser.java +109 -409
  20. data/java/src/json/ext/Parser.rl +24 -117
  21. data/java/src/json/ext/RuntimeInfo.java +0 -4
  22. data/json.gemspec +0 -0
  23. data/json_pure.gemspec +7 -7
  24. data/lib/json.rb +1 -0
  25. data/lib/json/add/bigdecimal.rb +1 -0
  26. data/lib/json/add/complex.rb +2 -1
  27. data/lib/json/add/core.rb +1 -0
  28. data/lib/json/add/date.rb +1 -1
  29. data/lib/json/add/date_time.rb +1 -1
  30. data/lib/json/add/exception.rb +1 -1
  31. data/lib/json/add/ostruct.rb +1 -1
  32. data/lib/json/add/range.rb +1 -1
  33. data/lib/json/add/rational.rb +1 -0
  34. data/lib/json/add/regexp.rb +1 -1
  35. data/lib/json/add/struct.rb +1 -1
  36. data/lib/json/add/symbol.rb +1 -1
  37. data/lib/json/add/time.rb +1 -1
  38. data/lib/json/common.rb +24 -52
  39. data/lib/json/ext.rb +0 -6
  40. data/lib/json/generic_object.rb +5 -4
  41. data/lib/json/pure.rb +2 -8
  42. data/lib/json/pure/generator.rb +51 -123
  43. data/lib/json/pure/parser.rb +28 -80
  44. data/lib/json/version.rb +2 -1
  45. data/references/rfc7159.txt +899 -0
  46. data/tests/fixtures/obsolete_fail1.json +1 -0
  47. data/tests/{test_json_addition.rb → json_addition_test.rb} +22 -25
  48. data/tests/json_common_interface_test.rb +126 -0
  49. data/tests/json_encoding_test.rb +105 -0
  50. data/tests/json_ext_parser_test.rb +15 -0
  51. data/tests/{test_json_fixtures.rb → json_fixtures_test.rb} +5 -8
  52. data/tests/{test_json_generate.rb → json_generator_test.rb} +65 -37
  53. data/tests/{test_json_generic_object.rb → json_generic_object_test.rb} +15 -8
  54. data/tests/json_parser_test.rb +448 -0
  55. data/tests/json_string_matching_test.rb +38 -0
  56. data/tests/test_helper.rb +23 -0
  57. data/tools/fuzz.rb +1 -9
  58. metadata +18 -31
  59. data/TODO +0 -1
  60. data/tests/fixtures/fail1.json +0 -1
  61. data/tests/setup_variant.rb +0 -11
  62. data/tests/test_json.rb +0 -519
  63. data/tests/test_json_encoding.rb +0 -65
  64. data/tests/test_json_string_matching.rb +0 -39
  65. data/tests/test_json_unicode.rb +0 -72
data/Rakefile CHANGED
@@ -88,7 +88,7 @@ if defined?(Gem) and defined?(Gem::PackageTask)
88
88
 
89
89
  s.extra_rdoc_files << 'README.md'
90
90
  s.rdoc_options <<
91
- '--title' << 'JSON implemention for Ruby' << '--main' << 'README.md'
91
+ '--title' << 'JSON implemention for ruby' << '--main' << 'README.md'
92
92
  s.test_files.concat Dir['./tests/test_*.rb']
93
93
 
94
94
  s.author = "Florian Frank"
@@ -132,6 +132,7 @@ if defined?(Gem) and defined?(Gem::PackageTask)
132
132
  s.email = "flori@ping.de"
133
133
  s.homepage = "http://flori.github.com/#{PKG_NAME}"
134
134
  s.license = 'Ruby'
135
+ s.required_ruby_version = '~> 2.0'
135
136
  end
136
137
 
137
138
  desc 'Creates a json.gemspec file'
@@ -156,6 +157,7 @@ task :version do
156
157
  puts m
157
158
  File.open(File.join('lib', 'json', 'version.rb'), 'w') do |v|
158
159
  v.puts <<EOT
160
+ # frozen_string_literal: false
159
161
  module JSON
160
162
  # JSON version
161
163
  VERSION = '#{PKG_VERSION}'
@@ -168,13 +170,17 @@ EOT
168
170
  end
169
171
  end
170
172
 
173
+ task :check_env do
174
+ ENV.key?('JSON') or fail "JSON env var is required"
175
+ end
176
+
171
177
  desc "Testing library (pure ruby)"
172
- task :test_pure => [ :clean, :do_test_pure ]
178
+ task :test_pure => [ :clean, :check_env, :do_test_pure ]
173
179
 
174
180
  UndocumentedTestTask.new do |t|
175
181
  t.name = 'do_test_pure'
176
- t.libs << 'lib'
177
- t.test_files = FileList['tests/test_*.rb']
182
+ t.libs << 'lib' << 'tests'
183
+ t.test_files = FileList['tests/*_test.rb']
178
184
  t.verbose = true
179
185
  t.options = '-v'
180
186
  end
@@ -252,12 +258,12 @@ if defined?(RUBY_ENGINE) and RUBY_ENGINE == 'jruby'
252
258
  end
253
259
 
254
260
  desc "Testing library (jruby)"
255
- task :test_ext => [ :create_jar, :do_test_ext ]
261
+ task :test_ext => [ :create_jar, :check_env, :do_test_ext ]
256
262
 
257
263
  UndocumentedTestTask.new do |t|
258
264
  t.name = 'do_test_ext'
259
- t.libs << 'lib'
260
- t.test_files = FileList['tests/test_*.rb']
265
+ t.libs << 'lib' << 'tests'
266
+ t.test_files = FileList['tests/*_test.rb']
261
267
  t.verbose = true
262
268
  t.options = '-v'
263
269
  end
@@ -326,12 +332,12 @@ else
326
332
  end
327
333
 
328
334
  desc "Testing library (extension)"
329
- task :test_ext => [ :compile, :do_test_ext ]
335
+ task :test_ext => [ :compile, :check_env, :do_test_ext ]
330
336
 
331
337
  UndocumentedTestTask.new do |t|
332
338
  t.name = 'do_test_ext'
333
- t.libs << 'ext' << 'lib'
334
- t.test_files = FileList['tests/test_*.rb']
339
+ t.libs << 'ext' << 'lib' << 'tests'
340
+ t.test_files = FileList['tests/*_test.rb']
335
341
  t.verbose = true
336
342
  t.options = '-v'
337
343
  end
@@ -357,6 +363,7 @@ else
357
363
  sh "ragel -x parser.rl | #{RAGEL_CODEGEN} -G2"
358
364
  end
359
365
  src = File.read("parser.c").gsub(/[ \t]+$/, '')
366
+ src.gsub!(/^static const int (JSON_.*=.*);$/, 'enum {\1};')
360
367
  File.open("parser.c", "w") {|f| f.print src}
361
368
  end
362
369
  end
data/VERSION CHANGED
@@ -1 +1 @@
1
- 1.8.6
1
+ 2.0.0
@@ -20,7 +20,7 @@ static VALUE mJSON, mExt, mGenerator, cState, mGeneratorMethods, mObject,
20
20
 
21
21
  static ID i_to_s, i_to_json, i_new, i_indent, i_space, i_space_before,
22
22
  i_object_nl, i_array_nl, i_max_nesting, i_allow_nan, i_ascii_only,
23
- i_quirks_mode, i_pack, i_unpack, i_create_id, i_extend, i_key_p,
23
+ i_pack, i_unpack, i_create_id, i_extend, i_key_p,
24
24
  i_aref, i_send, i_respond_to_p, i_match, i_keys, i_depth,
25
25
  i_buffer_initial_length, i_dup;
26
26
 
@@ -641,8 +641,6 @@ static VALUE cState_configure(VALUE self, VALUE opts)
641
641
  state->allow_nan = RTEST(tmp);
642
642
  tmp = rb_hash_aref(opts, ID2SYM(i_ascii_only));
643
643
  state->ascii_only = RTEST(tmp);
644
- tmp = rb_hash_aref(opts, ID2SYM(i_quirks_mode));
645
- state->quirks_mode = RTEST(tmp);
646
644
  return self;
647
645
  }
648
646
 
@@ -676,7 +674,6 @@ static VALUE cState_to_h(VALUE self)
676
674
  rb_hash_aset(result, ID2SYM(i_array_nl), rb_str_new(state->array_nl, state->array_nl_len));
677
675
  rb_hash_aset(result, ID2SYM(i_allow_nan), state->allow_nan ? Qtrue : Qfalse);
678
676
  rb_hash_aset(result, ID2SYM(i_ascii_only), state->ascii_only ? Qtrue : Qfalse);
679
- rb_hash_aset(result, ID2SYM(i_quirks_mode), state->quirks_mode ? Qtrue : Qfalse);
680
677
  rb_hash_aset(result, ID2SYM(i_max_nesting), LONG2FIX(state->max_nesting));
681
678
  rb_hash_aset(result, ID2SYM(i_depth), LONG2FIX(state->depth));
682
679
  rb_hash_aset(result, ID2SYM(i_buffer_initial_length), LONG2FIX(state->buffer_initial_length));
@@ -853,7 +850,6 @@ static void generate_json_integer(FBuffer *buffer, VALUE Vstate, JSON_Generator_
853
850
  generate_json_bignum(buffer, Vstate, state, obj);
854
851
  }
855
852
  #endif
856
-
857
853
  static void generate_json_float(FBuffer *buffer, VALUE Vstate, JSON_Generator_State *state, VALUE obj)
858
854
  {
859
855
  double value = RFLOAT_VALUE(obj);
@@ -943,21 +939,6 @@ static VALUE cState_partial_generate(VALUE self, VALUE obj)
943
939
  return fbuffer_to_s(buffer);
944
940
  }
945
941
 
946
- /*
947
- * This function returns true if string is either a JSON array or JSON object.
948
- * It might suffer from false positives, e. g. syntactically incorrect JSON in
949
- * the string or certain UTF-8 characters on the right hand side.
950
- */
951
- static int isArrayOrObject(VALUE string)
952
- {
953
- long string_len = RSTRING_LEN(string);
954
- char *p = RSTRING_PTR(string), *q = p + string_len - 1;
955
- if (string_len < 2) return 0;
956
- for (; p < q && isspace((unsigned char)*p); p++);
957
- for (; q > p && isspace((unsigned char)*q); q--);
958
- return (*p == '[' && *q == ']') || (*p == '{' && *q == '}');
959
- }
960
-
961
942
  /*
962
943
  * call-seq: generate(obj)
963
944
  *
@@ -969,9 +950,6 @@ static VALUE cState_generate(VALUE self, VALUE obj)
969
950
  {
970
951
  VALUE result = cState_partial_generate(self, obj);
971
952
  GET_STATE(self);
972
- if (!state->quirks_mode && !isArrayOrObject(result)) {
973
- rb_raise(eGeneratorError, "only generation of JSON objects or arrays allowed");
974
- }
975
953
  return result;
976
954
  }
977
955
 
@@ -990,8 +968,6 @@ static VALUE cState_generate(VALUE self, VALUE obj)
990
968
  * * *allow_nan*: true if NaN, Infinity, and -Infinity should be
991
969
  * generated, otherwise an exception is thrown, if these values are
992
970
  * encountered. This options defaults to false.
993
- * * *quirks_mode*: Enables quirks_mode for parser, that is for example
994
- * generating single JSON values instead of documents is possible.
995
971
  * * *buffer_initial_length*: sets the initial length of the generator's
996
972
  * internal buffer.
997
973
  */
@@ -1298,29 +1274,6 @@ static VALUE cState_ascii_only_p(VALUE self)
1298
1274
  return state->ascii_only ? Qtrue : Qfalse;
1299
1275
  }
1300
1276
 
1301
- /*
1302
- * call-seq: quirks_mode?
1303
- *
1304
- * Returns true, if quirks mode is enabled. Otherwise returns false.
1305
- */
1306
- static VALUE cState_quirks_mode_p(VALUE self)
1307
- {
1308
- GET_STATE(self);
1309
- return state->quirks_mode ? Qtrue : Qfalse;
1310
- }
1311
-
1312
- /*
1313
- * call-seq: quirks_mode=(enable)
1314
- *
1315
- * If set to true, enables the quirks_mode mode.
1316
- */
1317
- static VALUE cState_quirks_mode_set(VALUE self, VALUE enable)
1318
- {
1319
- GET_STATE(self);
1320
- state->quirks_mode = RTEST(enable);
1321
- return Qnil;
1322
- }
1323
-
1324
1277
  /*
1325
1278
  * call-seq: depth
1326
1279
  *
@@ -1409,9 +1362,6 @@ void Init_generator(void)
1409
1362
  rb_define_method(cState, "check_circular?", cState_check_circular_p, 0);
1410
1363
  rb_define_method(cState, "allow_nan?", cState_allow_nan_p, 0);
1411
1364
  rb_define_method(cState, "ascii_only?", cState_ascii_only_p, 0);
1412
- rb_define_method(cState, "quirks_mode?", cState_quirks_mode_p, 0);
1413
- rb_define_method(cState, "quirks_mode", cState_quirks_mode_p, 0);
1414
- rb_define_method(cState, "quirks_mode=", cState_quirks_mode_set, 1);
1415
1365
  rb_define_method(cState, "depth", cState_depth, 0);
1416
1366
  rb_define_method(cState, "depth=", cState_depth_set, 1);
1417
1367
  rb_define_method(cState, "buffer_initial_length", cState_buffer_initial_length, 0);
@@ -1468,7 +1418,6 @@ void Init_generator(void)
1468
1418
  i_max_nesting = rb_intern("max_nesting");
1469
1419
  i_allow_nan = rb_intern("allow_nan");
1470
1420
  i_ascii_only = rb_intern("ascii_only");
1471
- i_quirks_mode = rb_intern("quirks_mode");
1472
1421
  i_depth = rb_intern("depth");
1473
1422
  i_buffer_initial_length = rb_intern("buffer_initial_length");
1474
1423
  i_pack = rb_intern("pack");
@@ -21,10 +21,6 @@
21
21
  #define rb_obj_instance_variables(object) rb_funcall(object, rb_intern("instance_variables"), 0)
22
22
  #endif
23
23
 
24
- #ifndef RB_TYPE_P
25
- #define RB_TYPE_P(obj, type) (rb_type(obj) == type)
26
- #endif
27
-
28
24
  #define option_given_p(opts, key) RTEST(rb_funcall(opts, i_key_p, 1, key))
29
25
 
30
26
  /* unicode definitions */
@@ -77,7 +73,6 @@ typedef struct JSON_Generator_StateStruct {
77
73
  long max_nesting;
78
74
  char allow_nan;
79
75
  char ascii_only;
80
- char quirks_mode;
81
76
  long depth;
82
77
  long buffer_initial_length;
83
78
  } JSON_Generator_State;
@@ -1,3 +1,6 @@
1
+ # frozen_string_literal: false
1
2
  require 'mkmf'
2
3
 
4
+ have_func("rb_enc_raise", "ruby.h")
5
+
3
6
  create_makefile 'json/ext/parser'
@@ -4,7 +4,7 @@
4
4
  #include "parser.h"
5
5
 
6
6
  #if defined HAVE_RUBY_ENCODING_H
7
- # define EXC_ENCODING UTF_8,
7
+ # define EXC_ENCODING rb_utf8_encoding(),
8
8
  # ifndef HAVE_RB_ENC_RAISE
9
9
  static void
10
10
  enc_raise(rb_encoding *enc, VALUE exc, const char *fmt, ...)
@@ -89,34 +89,28 @@ static int convert_UTF32_to_UTF8(char *buf, UTF32 ch)
89
89
  return len;
90
90
  }
91
91
 
92
- #ifdef HAVE_RUBY_ENCODING_H
93
- static rb_encoding *UTF_8, *UTF_16BE, *UTF_16LE, *UTF_32BE, *UTF_32LE;
94
- #else
95
- static ID i_iconv;
96
- #endif
97
-
98
92
  static VALUE mJSON, mExt, cParser, eParserError, eNestingError;
99
93
  static VALUE CNaN, CInfinity, CMinusInfinity;
100
94
 
101
95
  static ID i_json_creatable_p, i_json_create, i_create_id, i_create_additions,
102
- i_chr, i_max_nesting, i_allow_nan, i_symbolize_names, i_quirks_mode,
96
+ i_chr, i_max_nesting, i_allow_nan, i_symbolize_names,
103
97
  i_object_class, i_array_class, i_key_p, i_deep_const_get, i_match,
104
98
  i_match_string, i_aset, i_aref, i_leftshift;
105
99
 
106
100
 
107
- #line 130 "parser.rl"
101
+ #line 124 "parser.rl"
108
102
 
109
103
 
110
104
 
111
- #line 112 "parser.c"
112
- static const int JSON_object_start = 1;
113
- static const int JSON_object_first_final = 27;
114
- static const int JSON_object_error = 0;
105
+ #line 106 "parser.c"
106
+ enum {JSON_object_start = 1};
107
+ enum {JSON_object_first_final = 27};
108
+ enum {JSON_object_error = 0};
115
109
 
116
- static const int JSON_object_en_main = 1;
110
+ enum {JSON_object_en_main = 1};
117
111
 
118
112
 
119
- #line 171 "parser.rl"
113
+ #line 165 "parser.rl"
120
114
 
121
115
 
122
116
  static char *JSON_parse_object(JSON_Parser *json, char *p, char *pe, VALUE *result)
@@ -132,14 +126,14 @@ static char *JSON_parse_object(JSON_Parser *json, char *p, char *pe, VALUE *resu
132
126
  *result = NIL_P(object_class) ? rb_hash_new() : rb_class_new_instance(0, 0, object_class);
133
127
 
134
128
 
135
- #line 136 "parser.c"
129
+ #line 130 "parser.c"
136
130
  {
137
131
  cs = JSON_object_start;
138
132
  }
139
133
 
140
- #line 186 "parser.rl"
134
+ #line 180 "parser.rl"
141
135
 
142
- #line 143 "parser.c"
136
+ #line 137 "parser.c"
143
137
  {
144
138
  if ( p == pe )
145
139
  goto _test_eof;
@@ -167,7 +161,7 @@ case 2:
167
161
  goto st2;
168
162
  goto st0;
169
163
  tr2:
170
- #line 153 "parser.rl"
164
+ #line 147 "parser.rl"
171
165
  {
172
166
  char *np;
173
167
  json->parsing_name = 1;
@@ -180,7 +174,7 @@ st3:
180
174
  if ( ++p == pe )
181
175
  goto _test_eof3;
182
176
  case 3:
183
- #line 184 "parser.c"
177
+ #line 178 "parser.c"
184
178
  switch( (*p) ) {
185
179
  case 13: goto st3;
186
180
  case 32: goto st3;
@@ -247,7 +241,7 @@ case 8:
247
241
  goto st8;
248
242
  goto st0;
249
243
  tr11:
250
- #line 138 "parser.rl"
244
+ #line 132 "parser.rl"
251
245
  {
252
246
  VALUE v = Qnil;
253
247
  char *np = JSON_parse_value(json, p, pe, &v);
@@ -267,7 +261,7 @@ st9:
267
261
  if ( ++p == pe )
268
262
  goto _test_eof9;
269
263
  case 9:
270
- #line 271 "parser.c"
264
+ #line 265 "parser.c"
271
265
  switch( (*p) ) {
272
266
  case 13: goto st9;
273
267
  case 32: goto st9;
@@ -356,14 +350,14 @@ case 18:
356
350
  goto st9;
357
351
  goto st18;
358
352
  tr4:
359
- #line 161 "parser.rl"
353
+ #line 155 "parser.rl"
360
354
  { p--; {p++; cs = 27; goto _out;} }
361
355
  goto st27;
362
356
  st27:
363
357
  if ( ++p == pe )
364
358
  goto _test_eof27;
365
359
  case 27:
366
- #line 367 "parser.c"
360
+ #line 361 "parser.c"
367
361
  goto st0;
368
362
  st19:
369
363
  if ( ++p == pe )
@@ -461,7 +455,7 @@ case 26:
461
455
  _out: {}
462
456
  }
463
457
 
464
- #line 187 "parser.rl"
458
+ #line 181 "parser.rl"
465
459
 
466
460
  if (cs >= JSON_object_first_final) {
467
461
  if (json->create_additions) {
@@ -486,15 +480,15 @@ case 26:
486
480
 
487
481
 
488
482
 
489
- #line 490 "parser.c"
490
- static const int JSON_value_start = 1;
491
- static const int JSON_value_first_final = 21;
492
- static const int JSON_value_error = 0;
483
+ #line 484 "parser.c"
484
+ enum {JSON_value_start = 1};
485
+ enum {JSON_value_first_final = 29};
486
+ enum {JSON_value_error = 0};
493
487
 
494
- static const int JSON_value_en_main = 1;
488
+ enum {JSON_value_en_main = 1};
495
489
 
496
490
 
497
- #line 291 "parser.rl"
491
+ #line 285 "parser.rl"
498
492
 
499
493
 
500
494
  static char *JSON_parse_value(JSON_Parser *json, char *p, char *pe, VALUE *result)
@@ -502,53 +496,62 @@ static char *JSON_parse_value(JSON_Parser *json, char *p, char *pe, VALUE *resul
502
496
  int cs = EVIL;
503
497
 
504
498
 
505
- #line 506 "parser.c"
499
+ #line 500 "parser.c"
506
500
  {
507
501
  cs = JSON_value_start;
508
502
  }
509
503
 
510
- #line 298 "parser.rl"
504
+ #line 292 "parser.rl"
511
505
 
512
- #line 513 "parser.c"
506
+ #line 507 "parser.c"
513
507
  {
514
508
  if ( p == pe )
515
509
  goto _test_eof;
516
510
  switch ( cs )
517
511
  {
512
+ st1:
513
+ if ( ++p == pe )
514
+ goto _test_eof1;
518
515
  case 1:
519
516
  switch( (*p) ) {
520
- case 34: goto tr0;
521
- case 45: goto tr2;
522
- case 73: goto st2;
523
- case 78: goto st9;
524
- case 91: goto tr5;
525
- case 102: goto st11;
526
- case 110: goto st15;
527
- case 116: goto st18;
528
- case 123: goto tr9;
517
+ case 13: goto st1;
518
+ case 32: goto st1;
519
+ case 34: goto tr2;
520
+ case 45: goto tr3;
521
+ case 47: goto st6;
522
+ case 73: goto st10;
523
+ case 78: goto st17;
524
+ case 91: goto tr7;
525
+ case 102: goto st19;
526
+ case 110: goto st23;
527
+ case 116: goto st26;
528
+ case 123: goto tr11;
529
529
  }
530
- if ( 48 <= (*p) && (*p) <= 57 )
531
- goto tr2;
530
+ if ( (*p) > 10 ) {
531
+ if ( 48 <= (*p) && (*p) <= 57 )
532
+ goto tr3;
533
+ } else if ( (*p) >= 9 )
534
+ goto st1;
532
535
  goto st0;
533
536
  st0:
534
537
  cs = 0;
535
538
  goto _out;
536
- tr0:
537
- #line 239 "parser.rl"
539
+ tr2:
540
+ #line 233 "parser.rl"
538
541
  {
539
542
  char *np = JSON_parse_string(json, p, pe, result);
540
- if (np == NULL) { p--; {p++; cs = 21; goto _out;} } else {p = (( np))-1;}
543
+ if (np == NULL) { p--; {p++; cs = 29; goto _out;} } else {p = (( np))-1;}
541
544
  }
542
- goto st21;
543
- tr2:
544
- #line 244 "parser.rl"
545
+ goto st29;
546
+ tr3:
547
+ #line 238 "parser.rl"
545
548
  {
546
549
  char *np;
547
- if(pe > p + 9 - json->quirks_mode && !strncmp(MinusInfinity, p, 9)) {
550
+ if(pe > p + 8 && !strncmp(MinusInfinity, p, 9)) {
548
551
  if (json->allow_nan) {
549
552
  *result = CMinusInfinity;
550
553
  {p = (( p + 10))-1;}
551
- p--; {p++; cs = 21; goto _out;}
554
+ p--; {p++; cs = 29; goto _out;}
552
555
  } else {
553
556
  rb_enc_raise(EXC_ENCODING eParserError, "%u: unexpected token at '%s'", __LINE__, p);
554
557
  }
@@ -557,31 +560,31 @@ tr2:
557
560
  if (np != NULL) {p = (( np))-1;}
558
561
  np = JSON_parse_integer(json, p, pe, result);
559
562
  if (np != NULL) {p = (( np))-1;}
560
- p--; {p++; cs = 21; goto _out;}
563
+ p--; {p++; cs = 29; goto _out;}
561
564
  }
562
- goto st21;
563
- tr5:
564
- #line 262 "parser.rl"
565
+ goto st29;
566
+ tr7:
567
+ #line 256 "parser.rl"
565
568
  {
566
569
  char *np;
567
570
  json->current_nesting++;
568
571
  np = JSON_parse_array(json, p, pe, result);
569
572
  json->current_nesting--;
570
- if (np == NULL) { p--; {p++; cs = 21; goto _out;} } else {p = (( np))-1;}
573
+ if (np == NULL) { p--; {p++; cs = 29; goto _out;} } else {p = (( np))-1;}
571
574
  }
572
- goto st21;
573
- tr9:
574
- #line 270 "parser.rl"
575
+ goto st29;
576
+ tr11:
577
+ #line 264 "parser.rl"
575
578
  {
576
579
  char *np;
577
580
  json->current_nesting++;
578
581
  np = JSON_parse_object(json, p, pe, result);
579
582
  json->current_nesting--;
580
- if (np == NULL) { p--; {p++; cs = 21; goto _out;} } else {p = (( np))-1;}
583
+ if (np == NULL) { p--; {p++; cs = 29; goto _out;} } else {p = (( np))-1;}
581
584
  }
582
- goto st21;
583
- tr16:
584
- #line 232 "parser.rl"
585
+ goto st29;
586
+ tr25:
587
+ #line 226 "parser.rl"
585
588
  {
586
589
  if (json->allow_nan) {
587
590
  *result = CInfinity;
@@ -589,9 +592,9 @@ tr16:
589
592
  rb_enc_raise(EXC_ENCODING eParserError, "%u: unexpected token at '%s'", __LINE__, p - 8);
590
593
  }
591
594
  }
592
- goto st21;
593
- tr18:
594
- #line 225 "parser.rl"
595
+ goto st29;
596
+ tr27:
597
+ #line 219 "parser.rl"
595
598
  {
596
599
  if (json->allow_nan) {
597
600
  *result = CNaN;
@@ -599,168 +602,240 @@ tr18:
599
602
  rb_enc_raise(EXC_ENCODING eParserError, "%u: unexpected token at '%s'", __LINE__, p - 2);
600
603
  }
601
604
  }
602
- goto st21;
603
- tr22:
604
- #line 219 "parser.rl"
605
+ goto st29;
606
+ tr31:
607
+ #line 213 "parser.rl"
605
608
  {
606
609
  *result = Qfalse;
607
610
  }
608
- goto st21;
609
- tr25:
610
- #line 216 "parser.rl"
611
+ goto st29;
612
+ tr34:
613
+ #line 210 "parser.rl"
611
614
  {
612
615
  *result = Qnil;
613
616
  }
614
- goto st21;
615
- tr28:
616
- #line 222 "parser.rl"
617
+ goto st29;
618
+ tr37:
619
+ #line 216 "parser.rl"
617
620
  {
618
621
  *result = Qtrue;
619
622
  }
620
- goto st21;
621
- st21:
622
- if ( ++p == pe )
623
- goto _test_eof21;
624
- case 21:
625
- #line 278 "parser.rl"
626
- { p--; {p++; cs = 21; goto _out;} }
627
- #line 628 "parser.c"
623
+ goto st29;
624
+ st29:
625
+ if ( ++p == pe )
626
+ goto _test_eof29;
627
+ case 29:
628
+ #line 272 "parser.rl"
629
+ { p--; {p++; cs = 29; goto _out;} }
630
+ #line 631 "parser.c"
631
+ switch( (*p) ) {
632
+ case 13: goto st29;
633
+ case 32: goto st29;
634
+ case 47: goto st2;
635
+ }
636
+ if ( 9 <= (*p) && (*p) <= 10 )
637
+ goto st29;
628
638
  goto st0;
629
639
  st2:
630
640
  if ( ++p == pe )
631
641
  goto _test_eof2;
632
642
  case 2:
633
- if ( (*p) == 110 )
634
- goto st3;
643
+ switch( (*p) ) {
644
+ case 42: goto st3;
645
+ case 47: goto st5;
646
+ }
635
647
  goto st0;
636
648
  st3:
637
649
  if ( ++p == pe )
638
650
  goto _test_eof3;
639
651
  case 3:
640
- if ( (*p) == 102 )
652
+ if ( (*p) == 42 )
641
653
  goto st4;
642
- goto st0;
654
+ goto st3;
643
655
  st4:
644
656
  if ( ++p == pe )
645
657
  goto _test_eof4;
646
658
  case 4:
647
- if ( (*p) == 105 )
648
- goto st5;
649
- goto st0;
659
+ switch( (*p) ) {
660
+ case 42: goto st4;
661
+ case 47: goto st29;
662
+ }
663
+ goto st3;
650
664
  st5:
651
665
  if ( ++p == pe )
652
666
  goto _test_eof5;
653
667
  case 5:
654
- if ( (*p) == 110 )
655
- goto st6;
656
- goto st0;
668
+ if ( (*p) == 10 )
669
+ goto st29;
670
+ goto st5;
657
671
  st6:
658
672
  if ( ++p == pe )
659
673
  goto _test_eof6;
660
674
  case 6:
661
- if ( (*p) == 105 )
662
- goto st7;
675
+ switch( (*p) ) {
676
+ case 42: goto st7;
677
+ case 47: goto st9;
678
+ }
663
679
  goto st0;
664
680
  st7:
665
681
  if ( ++p == pe )
666
682
  goto _test_eof7;
667
683
  case 7:
668
- if ( (*p) == 116 )
684
+ if ( (*p) == 42 )
669
685
  goto st8;
670
- goto st0;
686
+ goto st7;
671
687
  st8:
672
688
  if ( ++p == pe )
673
689
  goto _test_eof8;
674
690
  case 8:
675
- if ( (*p) == 121 )
676
- goto tr16;
677
- goto st0;
691
+ switch( (*p) ) {
692
+ case 42: goto st8;
693
+ case 47: goto st1;
694
+ }
695
+ goto st7;
678
696
  st9:
679
697
  if ( ++p == pe )
680
698
  goto _test_eof9;
681
699
  case 9:
682
- if ( (*p) == 97 )
683
- goto st10;
684
- goto st0;
700
+ if ( (*p) == 10 )
701
+ goto st1;
702
+ goto st9;
685
703
  st10:
686
704
  if ( ++p == pe )
687
705
  goto _test_eof10;
688
706
  case 10:
689
- if ( (*p) == 78 )
690
- goto tr18;
707
+ if ( (*p) == 110 )
708
+ goto st11;
691
709
  goto st0;
692
710
  st11:
693
711
  if ( ++p == pe )
694
712
  goto _test_eof11;
695
713
  case 11:
696
- if ( (*p) == 97 )
714
+ if ( (*p) == 102 )
697
715
  goto st12;
698
716
  goto st0;
699
717
  st12:
700
718
  if ( ++p == pe )
701
719
  goto _test_eof12;
702
720
  case 12:
703
- if ( (*p) == 108 )
721
+ if ( (*p) == 105 )
704
722
  goto st13;
705
723
  goto st0;
706
724
  st13:
707
725
  if ( ++p == pe )
708
726
  goto _test_eof13;
709
727
  case 13:
710
- if ( (*p) == 115 )
728
+ if ( (*p) == 110 )
711
729
  goto st14;
712
730
  goto st0;
713
731
  st14:
714
732
  if ( ++p == pe )
715
733
  goto _test_eof14;
716
734
  case 14:
717
- if ( (*p) == 101 )
718
- goto tr22;
735
+ if ( (*p) == 105 )
736
+ goto st15;
719
737
  goto st0;
720
738
  st15:
721
739
  if ( ++p == pe )
722
740
  goto _test_eof15;
723
741
  case 15:
724
- if ( (*p) == 117 )
742
+ if ( (*p) == 116 )
725
743
  goto st16;
726
744
  goto st0;
727
745
  st16:
728
746
  if ( ++p == pe )
729
747
  goto _test_eof16;
730
748
  case 16:
731
- if ( (*p) == 108 )
732
- goto st17;
749
+ if ( (*p) == 121 )
750
+ goto tr25;
733
751
  goto st0;
734
752
  st17:
735
753
  if ( ++p == pe )
736
754
  goto _test_eof17;
737
755
  case 17:
738
- if ( (*p) == 108 )
739
- goto tr25;
756
+ if ( (*p) == 97 )
757
+ goto st18;
740
758
  goto st0;
741
759
  st18:
742
760
  if ( ++p == pe )
743
761
  goto _test_eof18;
744
762
  case 18:
745
- if ( (*p) == 114 )
746
- goto st19;
763
+ if ( (*p) == 78 )
764
+ goto tr27;
747
765
  goto st0;
748
766
  st19:
749
767
  if ( ++p == pe )
750
768
  goto _test_eof19;
751
769
  case 19:
752
- if ( (*p) == 117 )
770
+ if ( (*p) == 97 )
753
771
  goto st20;
754
772
  goto st0;
755
773
  st20:
756
774
  if ( ++p == pe )
757
775
  goto _test_eof20;
758
776
  case 20:
777
+ if ( (*p) == 108 )
778
+ goto st21;
779
+ goto st0;
780
+ st21:
781
+ if ( ++p == pe )
782
+ goto _test_eof21;
783
+ case 21:
784
+ if ( (*p) == 115 )
785
+ goto st22;
786
+ goto st0;
787
+ st22:
788
+ if ( ++p == pe )
789
+ goto _test_eof22;
790
+ case 22:
791
+ if ( (*p) == 101 )
792
+ goto tr31;
793
+ goto st0;
794
+ st23:
795
+ if ( ++p == pe )
796
+ goto _test_eof23;
797
+ case 23:
798
+ if ( (*p) == 117 )
799
+ goto st24;
800
+ goto st0;
801
+ st24:
802
+ if ( ++p == pe )
803
+ goto _test_eof24;
804
+ case 24:
805
+ if ( (*p) == 108 )
806
+ goto st25;
807
+ goto st0;
808
+ st25:
809
+ if ( ++p == pe )
810
+ goto _test_eof25;
811
+ case 25:
812
+ if ( (*p) == 108 )
813
+ goto tr34;
814
+ goto st0;
815
+ st26:
816
+ if ( ++p == pe )
817
+ goto _test_eof26;
818
+ case 26:
819
+ if ( (*p) == 114 )
820
+ goto st27;
821
+ goto st0;
822
+ st27:
823
+ if ( ++p == pe )
824
+ goto _test_eof27;
825
+ case 27:
826
+ if ( (*p) == 117 )
827
+ goto st28;
828
+ goto st0;
829
+ st28:
830
+ if ( ++p == pe )
831
+ goto _test_eof28;
832
+ case 28:
759
833
  if ( (*p) == 101 )
760
- goto tr28;
834
+ goto tr37;
761
835
  goto st0;
762
836
  }
763
- _test_eof21: cs = 21; goto _test_eof;
837
+ _test_eof1: cs = 1; goto _test_eof;
838
+ _test_eof29: cs = 29; goto _test_eof;
764
839
  _test_eof2: cs = 2; goto _test_eof;
765
840
  _test_eof3: cs = 3; goto _test_eof;
766
841
  _test_eof4: cs = 4; goto _test_eof;
@@ -780,12 +855,20 @@ case 20:
780
855
  _test_eof18: cs = 18; goto _test_eof;
781
856
  _test_eof19: cs = 19; goto _test_eof;
782
857
  _test_eof20: cs = 20; goto _test_eof;
858
+ _test_eof21: cs = 21; goto _test_eof;
859
+ _test_eof22: cs = 22; goto _test_eof;
860
+ _test_eof23: cs = 23; goto _test_eof;
861
+ _test_eof24: cs = 24; goto _test_eof;
862
+ _test_eof25: cs = 25; goto _test_eof;
863
+ _test_eof26: cs = 26; goto _test_eof;
864
+ _test_eof27: cs = 27; goto _test_eof;
865
+ _test_eof28: cs = 28; goto _test_eof;
783
866
 
784
867
  _test_eof: {}
785
868
  _out: {}
786
869
  }
787
870
 
788
- #line 299 "parser.rl"
871
+ #line 293 "parser.rl"
789
872
 
790
873
  if (cs >= JSON_value_first_final) {
791
874
  return p;
@@ -795,15 +878,15 @@ case 20:
795
878
  }
796
879
 
797
880
 
798
- #line 799 "parser.c"
799
- static const int JSON_integer_start = 1;
800
- static const int JSON_integer_first_final = 3;
801
- static const int JSON_integer_error = 0;
881
+ #line 882 "parser.c"
882
+ enum {JSON_integer_start = 1};
883
+ enum {JSON_integer_first_final = 3};
884
+ enum {JSON_integer_error = 0};
802
885
 
803
- static const int JSON_integer_en_main = 1;
886
+ enum {JSON_integer_en_main = 1};
804
887
 
805
888
 
806
- #line 315 "parser.rl"
889
+ #line 309 "parser.rl"
807
890
 
808
891
 
809
892
  static char *JSON_parse_integer(JSON_Parser *json, char *p, char *pe, VALUE *result)
@@ -811,15 +894,15 @@ static char *JSON_parse_integer(JSON_Parser *json, char *p, char *pe, VALUE *res
811
894
  int cs = EVIL;
812
895
 
813
896
 
814
- #line 815 "parser.c"
897
+ #line 898 "parser.c"
815
898
  {
816
899
  cs = JSON_integer_start;
817
900
  }
818
901
 
819
- #line 322 "parser.rl"
902
+ #line 316 "parser.rl"
820
903
  json->memo = p;
821
904
 
822
- #line 823 "parser.c"
905
+ #line 906 "parser.c"
823
906
  {
824
907
  if ( p == pe )
825
908
  goto _test_eof;
@@ -853,14 +936,14 @@ case 3:
853
936
  goto st0;
854
937
  goto tr4;
855
938
  tr4:
856
- #line 312 "parser.rl"
939
+ #line 306 "parser.rl"
857
940
  { p--; {p++; cs = 4; goto _out;} }
858
941
  goto st4;
859
942
  st4:
860
943
  if ( ++p == pe )
861
944
  goto _test_eof4;
862
945
  case 4:
863
- #line 864 "parser.c"
946
+ #line 947 "parser.c"
864
947
  goto st0;
865
948
  st5:
866
949
  if ( ++p == pe )
@@ -879,7 +962,7 @@ case 5:
879
962
  _out: {}
880
963
  }
881
964
 
882
- #line 324 "parser.rl"
965
+ #line 318 "parser.rl"
883
966
 
884
967
  if (cs >= JSON_integer_first_final) {
885
968
  long len = p - json->memo;
@@ -894,15 +977,15 @@ case 5:
894
977
  }
895
978
 
896
979
 
897
- #line 898 "parser.c"
898
- static const int JSON_float_start = 1;
899
- static const int JSON_float_first_final = 8;
900
- static const int JSON_float_error = 0;
980
+ #line 981 "parser.c"
981
+ enum {JSON_float_start = 1};
982
+ enum {JSON_float_first_final = 8};
983
+ enum {JSON_float_error = 0};
901
984
 
902
- static const int JSON_float_en_main = 1;
985
+ enum {JSON_float_en_main = 1};
903
986
 
904
987
 
905
- #line 349 "parser.rl"
988
+ #line 343 "parser.rl"
906
989
 
907
990
 
908
991
  static char *JSON_parse_float(JSON_Parser *json, char *p, char *pe, VALUE *result)
@@ -910,15 +993,15 @@ static char *JSON_parse_float(JSON_Parser *json, char *p, char *pe, VALUE *resul
910
993
  int cs = EVIL;
911
994
 
912
995
 
913
- #line 914 "parser.c"
996
+ #line 997 "parser.c"
914
997
  {
915
998
  cs = JSON_float_start;
916
999
  }
917
1000
 
918
- #line 356 "parser.rl"
1001
+ #line 350 "parser.rl"
919
1002
  json->memo = p;
920
1003
 
921
- #line 922 "parser.c"
1004
+ #line 1005 "parser.c"
922
1005
  {
923
1006
  if ( p == pe )
924
1007
  goto _test_eof;
@@ -976,14 +1059,14 @@ case 8:
976
1059
  goto st0;
977
1060
  goto tr9;
978
1061
  tr9:
979
- #line 343 "parser.rl"
1062
+ #line 337 "parser.rl"
980
1063
  { p--; {p++; cs = 9; goto _out;} }
981
1064
  goto st9;
982
1065
  st9:
983
1066
  if ( ++p == pe )
984
1067
  goto _test_eof9;
985
1068
  case 9:
986
- #line 987 "parser.c"
1069
+ #line 1070 "parser.c"
987
1070
  goto st0;
988
1071
  st5:
989
1072
  if ( ++p == pe )
@@ -1044,7 +1127,7 @@ case 7:
1044
1127
  _out: {}
1045
1128
  }
1046
1129
 
1047
- #line 358 "parser.rl"
1130
+ #line 352 "parser.rl"
1048
1131
 
1049
1132
  if (cs >= JSON_float_first_final) {
1050
1133
  long len = p - json->memo;
@@ -1060,15 +1143,15 @@ case 7:
1060
1143
 
1061
1144
 
1062
1145
 
1063
- #line 1064 "parser.c"
1064
- static const int JSON_array_start = 1;
1065
- static const int JSON_array_first_final = 17;
1066
- static const int JSON_array_error = 0;
1146
+ #line 1147 "parser.c"
1147
+ enum {JSON_array_start = 1};
1148
+ enum {JSON_array_first_final = 17};
1149
+ enum {JSON_array_error = 0};
1067
1150
 
1068
- static const int JSON_array_en_main = 1;
1151
+ enum {JSON_array_en_main = 1};
1069
1152
 
1070
1153
 
1071
- #line 401 "parser.rl"
1154
+ #line 395 "parser.rl"
1072
1155
 
1073
1156
 
1074
1157
  static char *JSON_parse_array(JSON_Parser *json, char *p, char *pe, VALUE *result)
@@ -1082,14 +1165,14 @@ static char *JSON_parse_array(JSON_Parser *json, char *p, char *pe, VALUE *resul
1082
1165
  *result = NIL_P(array_class) ? rb_ary_new() : rb_class_new_instance(0, 0, array_class);
1083
1166
 
1084
1167
 
1085
- #line 1086 "parser.c"
1168
+ #line 1169 "parser.c"
1086
1169
  {
1087
1170
  cs = JSON_array_start;
1088
1171
  }
1089
1172
 
1090
- #line 414 "parser.rl"
1173
+ #line 408 "parser.rl"
1091
1174
 
1092
- #line 1093 "parser.c"
1175
+ #line 1176 "parser.c"
1093
1176
  {
1094
1177
  if ( p == pe )
1095
1178
  goto _test_eof;
@@ -1128,7 +1211,7 @@ case 2:
1128
1211
  goto st2;
1129
1212
  goto st0;
1130
1213
  tr2:
1131
- #line 378 "parser.rl"
1214
+ #line 372 "parser.rl"
1132
1215
  {
1133
1216
  VALUE v = Qnil;
1134
1217
  char *np = JSON_parse_value(json, p, pe, &v);
@@ -1148,7 +1231,7 @@ st3:
1148
1231
  if ( ++p == pe )
1149
1232
  goto _test_eof3;
1150
1233
  case 3:
1151
- #line 1152 "parser.c"
1234
+ #line 1235 "parser.c"
1152
1235
  switch( (*p) ) {
1153
1236
  case 13: goto st3;
1154
1237
  case 32: goto st3;
@@ -1248,14 +1331,14 @@ case 12:
1248
1331
  goto st3;
1249
1332
  goto st12;
1250
1333
  tr4:
1251
- #line 393 "parser.rl"
1334
+ #line 387 "parser.rl"
1252
1335
  { p--; {p++; cs = 17; goto _out;} }
1253
1336
  goto st17;
1254
1337
  st17:
1255
1338
  if ( ++p == pe )
1256
1339
  goto _test_eof17;
1257
1340
  case 17:
1258
- #line 1259 "parser.c"
1341
+ #line 1342 "parser.c"
1259
1342
  goto st0;
1260
1343
  st13:
1261
1344
  if ( ++p == pe )
@@ -1311,7 +1394,7 @@ case 16:
1311
1394
  _out: {}
1312
1395
  }
1313
1396
 
1314
- #line 415 "parser.rl"
1397
+ #line 409 "parser.rl"
1315
1398
 
1316
1399
  if(cs >= JSON_array_first_final) {
1317
1400
  return p + 1;
@@ -1392,15 +1475,15 @@ static VALUE json_string_unescape(VALUE result, char *string, char *stringEnd)
1392
1475
  }
1393
1476
 
1394
1477
 
1395
- #line 1396 "parser.c"
1396
- static const int JSON_string_start = 1;
1397
- static const int JSON_string_first_final = 8;
1398
- static const int JSON_string_error = 0;
1478
+ #line 1479 "parser.c"
1479
+ enum {JSON_string_start = 1};
1480
+ enum {JSON_string_first_final = 8};
1481
+ enum {JSON_string_error = 0};
1399
1482
 
1400
- static const int JSON_string_en_main = 1;
1483
+ enum {JSON_string_en_main = 1};
1401
1484
 
1402
1485
 
1403
- #line 514 "parser.rl"
1486
+ #line 508 "parser.rl"
1404
1487
 
1405
1488
 
1406
1489
  static int
@@ -1422,15 +1505,15 @@ static char *JSON_parse_string(JSON_Parser *json, char *p, char *pe, VALUE *resu
1422
1505
 
1423
1506
  *result = rb_str_buf_new(0);
1424
1507
 
1425
- #line 1426 "parser.c"
1508
+ #line 1509 "parser.c"
1426
1509
  {
1427
1510
  cs = JSON_string_start;
1428
1511
  }
1429
1512
 
1430
- #line 535 "parser.rl"
1513
+ #line 529 "parser.rl"
1431
1514
  json->memo = p;
1432
1515
 
1433
- #line 1434 "parser.c"
1516
+ #line 1517 "parser.c"
1434
1517
  {
1435
1518
  if ( p == pe )
1436
1519
  goto _test_eof;
@@ -1455,7 +1538,7 @@ case 2:
1455
1538
  goto st0;
1456
1539
  goto st2;
1457
1540
  tr2:
1458
- #line 500 "parser.rl"
1541
+ #line 494 "parser.rl"
1459
1542
  {
1460
1543
  *result = json_string_unescape(*result, json->memo + 1, p);
1461
1544
  if (NIL_P(*result)) {
@@ -1466,14 +1549,14 @@ tr2:
1466
1549
  {p = (( p + 1))-1;}
1467
1550
  }
1468
1551
  }
1469
- #line 511 "parser.rl"
1552
+ #line 505 "parser.rl"
1470
1553
  { p--; {p++; cs = 8; goto _out;} }
1471
1554
  goto st8;
1472
1555
  st8:
1473
1556
  if ( ++p == pe )
1474
1557
  goto _test_eof8;
1475
1558
  case 8:
1476
- #line 1477 "parser.c"
1559
+ #line 1560 "parser.c"
1477
1560
  goto st0;
1478
1561
  st3:
1479
1562
  if ( ++p == pe )
@@ -1549,7 +1632,7 @@ case 7:
1549
1632
  _out: {}
1550
1633
  }
1551
1634
 
1552
- #line 537 "parser.rl"
1635
+ #line 531 "parser.rl"
1553
1636
 
1554
1637
  if (json->create_additions && RTEST(match_string = json->match_string)) {
1555
1638
  VALUE klass;
@@ -1564,6 +1647,8 @@ case 7:
1564
1647
 
1565
1648
  if (json->symbolize_names && json->parsing_name) {
1566
1649
  *result = rb_str_intern(*result);
1650
+ } else {
1651
+ rb_str_resize(*result, RSTRING_LEN(*result));
1567
1652
  }
1568
1653
  if (cs >= JSON_string_first_final) {
1569
1654
  return p + 1;
@@ -1586,41 +1671,13 @@ case 7:
1586
1671
 
1587
1672
  static VALUE convert_encoding(VALUE source)
1588
1673
  {
1589
- const char *ptr = RSTRING_PTR(source);
1590
- long len = RSTRING_LEN(source);
1591
- if (len < 2) {
1592
- rb_raise(eParserError, "A JSON text must at least contain two octets!");
1593
- }
1594
1674
  #ifdef HAVE_RUBY_ENCODING_H
1595
- {
1596
- rb_encoding *enc = rb_enc_get(source);
1597
- if (enc == rb_ascii8bit_encoding()) {
1598
- if (len >= 4 && ptr[0] == 0 && ptr[1] == 0 && ptr[2] == 0) {
1599
- source = rb_str_conv_enc(source, UTF_32BE, rb_utf8_encoding());
1600
- } else if (len >= 4 && ptr[0] == 0 && ptr[2] == 0) {
1601
- source = rb_str_conv_enc(source, UTF_16BE, rb_utf8_encoding());
1602
- } else if (len >= 4 && ptr[1] == 0 && ptr[2] == 0 && ptr[3] == 0) {
1603
- source = rb_str_conv_enc(source, UTF_32LE, rb_utf8_encoding());
1604
- } else if (len >= 4 && ptr[1] == 0 && ptr[3] == 0) {
1605
- source = rb_str_conv_enc(source, UTF_16LE, rb_utf8_encoding());
1606
- } else {
1607
- source = rb_str_dup(source);
1608
- FORCE_UTF8(source);
1609
- }
1610
- } else {
1611
- source = rb_str_conv_enc(source, rb_enc_get(source), rb_utf8_encoding());
1612
- }
1613
- }
1614
- #else
1615
- if (len >= 4 && ptr[0] == 0 && ptr[1] == 0 && ptr[2] == 0) {
1616
- source = rb_funcall(mJSON, i_iconv, 3, rb_str_new2("utf-8"), rb_str_new2("utf-32be"), source);
1617
- } else if (len >= 4 && ptr[0] == 0 && ptr[2] == 0) {
1618
- source = rb_funcall(mJSON, i_iconv, 3, rb_str_new2("utf-8"), rb_str_new2("utf-16be"), source);
1619
- } else if (len >= 4 && ptr[1] == 0 && ptr[2] == 0 && ptr[3] == 0) {
1620
- source = rb_funcall(mJSON, i_iconv, 3, rb_str_new2("utf-8"), rb_str_new2("utf-32le"), source);
1621
- } else if (len >= 4 && ptr[1] == 0 && ptr[3] == 0) {
1622
- source = rb_funcall(mJSON, i_iconv, 3, rb_str_new2("utf-8"), rb_str_new2("utf-16le"), source);
1623
- }
1675
+ rb_encoding *enc = rb_enc_get(source);
1676
+ if (enc == rb_ascii8bit_encoding()) {
1677
+ FORCE_UTF8(source);
1678
+ } else {
1679
+ source = rb_str_conv_enc(source, NULL, rb_utf8_encoding());
1680
+ }
1624
1681
  #endif
1625
1682
  return source;
1626
1683
  }
@@ -1643,8 +1700,9 @@ static VALUE convert_encoding(VALUE source)
1643
1700
  * defiance of RFC 4627 to be parsed by the Parser. This option defaults to
1644
1701
  * false.
1645
1702
  * * *symbolize_names*: If set to true, returns symbols for the names
1646
- * (keys) in a JSON object. Otherwise strings are returned, which is also
1647
- * the default.
1703
+ * (keys) in a JSON object. Otherwise strings are returned, which is
1704
+ * also the default. It's not possible to use this option in
1705
+ * conjunction with the *create_additions* option.
1648
1706
  * * *create_additions*: If set to false, the Parser doesn't create
1649
1707
  * additions even if a matching class and create_id was found. This option
1650
1708
  * defaults to false.
@@ -1695,19 +1753,17 @@ static VALUE cParser_initialize(int argc, VALUE *argv, VALUE self)
1695
1753
  } else {
1696
1754
  json->symbolize_names = 0;
1697
1755
  }
1698
- tmp = ID2SYM(i_quirks_mode);
1699
- if (option_given_p(opts, tmp)) {
1700
- VALUE quirks_mode = rb_hash_aref(opts, tmp);
1701
- json->quirks_mode = RTEST(quirks_mode) ? 1 : 0;
1702
- } else {
1703
- json->quirks_mode = 0;
1704
- }
1705
1756
  tmp = ID2SYM(i_create_additions);
1706
1757
  if (option_given_p(opts, tmp)) {
1707
1758
  json->create_additions = RTEST(rb_hash_aref(opts, tmp));
1708
1759
  } else {
1709
1760
  json->create_additions = 0;
1710
1761
  }
1762
+ if (json->symbolize_names && json->create_additions) {
1763
+ rb_raise(rb_eArgError,
1764
+ "options :symbolize_names and :create_additions cannot be "
1765
+ " used in conjunction");
1766
+ }
1711
1767
  tmp = ID2SYM(i_create_id);
1712
1768
  if (option_given_p(opts, tmp)) {
1713
1769
  json->create_id = rb_hash_aref(opts, tmp);
@@ -1744,11 +1800,9 @@ static VALUE cParser_initialize(int argc, VALUE *argv, VALUE self)
1744
1800
  json->object_class = Qnil;
1745
1801
  json->array_class = Qnil;
1746
1802
  }
1747
- StringValue(source);
1748
- if (!json->quirks_mode) {
1749
- source = convert_encoding(source);
1750
- }
1803
+ source = convert_encoding(StringValue(source));
1751
1804
  json->current_nesting = 0;
1805
+ StringValue(source);
1752
1806
  json->len = RSTRING_LEN(source);
1753
1807
  json->source = RSTRING_PTR(source);;
1754
1808
  json->Vsource = source;
@@ -1756,209 +1810,41 @@ static VALUE cParser_initialize(int argc, VALUE *argv, VALUE self)
1756
1810
  }
1757
1811
 
1758
1812
 
1759
- #line 1760 "parser.c"
1760
- static const int JSON_start = 1;
1761
- static const int JSON_first_final = 10;
1762
- static const int JSON_error = 0;
1813
+ #line 1814 "parser.c"
1814
+ enum {JSON_start = 1};
1815
+ enum {JSON_first_final = 10};
1816
+ enum {JSON_error = 0};
1763
1817
 
1764
- static const int JSON_en_main = 1;
1818
+ enum {JSON_en_main = 1};
1765
1819
 
1766
1820
 
1767
- #line 767 "parser.rl"
1821
+ #line 722 "parser.rl"
1768
1822
 
1769
1823
 
1770
- static VALUE cParser_parse_strict(VALUE self)
1824
+ /*
1825
+ * call-seq: parse()
1826
+ *
1827
+ * Parses the current JSON text _source_ and returns the complete data
1828
+ * structure as a result.
1829
+ */
1830
+ static VALUE cParser_parse(VALUE self)
1771
1831
  {
1772
- char *p, *pe;
1773
- int cs = EVIL;
1774
- VALUE result = Qnil;
1775
- GET_PARSER;
1832
+ char *p, *pe;
1833
+ int cs = EVIL;
1834
+ VALUE result = Qnil;
1835
+ GET_PARSER;
1776
1836
 
1777
1837
 
1778
- #line 1779 "parser.c"
1838
+ #line 1839 "parser.c"
1779
1839
  {
1780
1840
  cs = JSON_start;
1781
1841
  }
1782
1842
 
1783
- #line 777 "parser.rl"
1784
- p = json->source;
1785
- pe = p + json->len;
1786
-
1787
- #line 1788 "parser.c"
1788
- {
1789
- if ( p == pe )
1790
- goto _test_eof;
1791
- switch ( cs )
1792
- {
1793
- st1:
1794
- if ( ++p == pe )
1795
- goto _test_eof1;
1796
- case 1:
1797
- switch( (*p) ) {
1798
- case 13: goto st1;
1799
- case 32: goto st1;
1800
- case 47: goto st2;
1801
- case 91: goto tr3;
1802
- case 123: goto tr4;
1803
- }
1804
- if ( 9 <= (*p) && (*p) <= 10 )
1805
- goto st1;
1806
- goto st0;
1807
- st0:
1808
- cs = 0;
1809
- goto _out;
1810
- st2:
1811
- if ( ++p == pe )
1812
- goto _test_eof2;
1813
- case 2:
1814
- switch( (*p) ) {
1815
- case 42: goto st3;
1816
- case 47: goto st5;
1817
- }
1818
- goto st0;
1819
- st3:
1820
- if ( ++p == pe )
1821
- goto _test_eof3;
1822
- case 3:
1823
- if ( (*p) == 42 )
1824
- goto st4;
1825
- goto st3;
1826
- st4:
1827
- if ( ++p == pe )
1828
- goto _test_eof4;
1829
- case 4:
1830
- switch( (*p) ) {
1831
- case 42: goto st4;
1832
- case 47: goto st1;
1833
- }
1834
- goto st3;
1835
- st5:
1836
- if ( ++p == pe )
1837
- goto _test_eof5;
1838
- case 5:
1839
- if ( (*p) == 10 )
1840
- goto st1;
1841
- goto st5;
1842
- tr3:
1843
- #line 756 "parser.rl"
1844
- {
1845
- char *np;
1846
- json->current_nesting = 1;
1847
- np = JSON_parse_array(json, p, pe, &result);
1848
- if (np == NULL) { p--; {p++; cs = 10; goto _out;} } else {p = (( np))-1;}
1849
- }
1850
- goto st10;
1851
- tr4:
1852
- #line 749 "parser.rl"
1853
- {
1854
- char *np;
1855
- json->current_nesting = 1;
1856
- np = JSON_parse_object(json, p, pe, &result);
1857
- if (np == NULL) { p--; {p++; cs = 10; goto _out;} } else {p = (( np))-1;}
1858
- }
1859
- goto st10;
1860
- st10:
1861
- if ( ++p == pe )
1862
- goto _test_eof10;
1863
- case 10:
1864
- #line 1865 "parser.c"
1865
- switch( (*p) ) {
1866
- case 13: goto st10;
1867
- case 32: goto st10;
1868
- case 47: goto st6;
1869
- }
1870
- if ( 9 <= (*p) && (*p) <= 10 )
1871
- goto st10;
1872
- goto st0;
1873
- st6:
1874
- if ( ++p == pe )
1875
- goto _test_eof6;
1876
- case 6:
1877
- switch( (*p) ) {
1878
- case 42: goto st7;
1879
- case 47: goto st9;
1880
- }
1881
- goto st0;
1882
- st7:
1883
- if ( ++p == pe )
1884
- goto _test_eof7;
1885
- case 7:
1886
- if ( (*p) == 42 )
1887
- goto st8;
1888
- goto st7;
1889
- st8:
1890
- if ( ++p == pe )
1891
- goto _test_eof8;
1892
- case 8:
1893
- switch( (*p) ) {
1894
- case 42: goto st8;
1895
- case 47: goto st10;
1896
- }
1897
- goto st7;
1898
- st9:
1899
- if ( ++p == pe )
1900
- goto _test_eof9;
1901
- case 9:
1902
- if ( (*p) == 10 )
1903
- goto st10;
1904
- goto st9;
1905
- }
1906
- _test_eof1: cs = 1; goto _test_eof;
1907
- _test_eof2: cs = 2; goto _test_eof;
1908
- _test_eof3: cs = 3; goto _test_eof;
1909
- _test_eof4: cs = 4; goto _test_eof;
1910
- _test_eof5: cs = 5; goto _test_eof;
1911
- _test_eof10: cs = 10; goto _test_eof;
1912
- _test_eof6: cs = 6; goto _test_eof;
1913
- _test_eof7: cs = 7; goto _test_eof;
1914
- _test_eof8: cs = 8; goto _test_eof;
1915
- _test_eof9: cs = 9; goto _test_eof;
1916
-
1917
- _test_eof: {}
1918
- _out: {}
1919
- }
1920
-
1921
- #line 780 "parser.rl"
1922
-
1923
- if (cs >= JSON_first_final && p == pe) {
1924
- return result;
1925
- } else {
1926
- rb_enc_raise(EXC_ENCODING eParserError, "%u: unexpected token at '%s'", __LINE__, p);
1927
- return Qnil;
1928
- }
1929
- }
1930
-
1931
-
1932
-
1933
- #line 1934 "parser.c"
1934
- static const int JSON_quirks_mode_start = 1;
1935
- static const int JSON_quirks_mode_first_final = 10;
1936
- static const int JSON_quirks_mode_error = 0;
1937
-
1938
- static const int JSON_quirks_mode_en_main = 1;
1939
-
1940
-
1941
- #line 805 "parser.rl"
1942
-
1943
-
1944
- static VALUE cParser_parse_quirks_mode(VALUE self)
1945
- {
1946
- char *p, *pe;
1947
- int cs = EVIL;
1948
- VALUE result = Qnil;
1949
- GET_PARSER;
1950
-
1951
-
1952
- #line 1953 "parser.c"
1953
- {
1954
- cs = JSON_quirks_mode_start;
1955
- }
1956
-
1957
- #line 815 "parser.rl"
1958
- p = json->source;
1959
- pe = p + json->len;
1843
+ #line 738 "parser.rl"
1844
+ p = json->source;
1845
+ pe = p + json->len;
1960
1846
 
1961
- #line 1962 "parser.c"
1847
+ #line 1848 "parser.c"
1962
1848
  {
1963
1849
  if ( p == pe )
1964
1850
  goto _test_eof;
@@ -1992,7 +1878,7 @@ st0:
1992
1878
  cs = 0;
1993
1879
  goto _out;
1994
1880
  tr2:
1995
- #line 797 "parser.rl"
1881
+ #line 714 "parser.rl"
1996
1882
  {
1997
1883
  char *np = JSON_parse_value(json, p, pe, &result);
1998
1884
  if (np == NULL) { p--; {p++; cs = 10; goto _out;} } else {p = (( np))-1;}
@@ -2002,7 +1888,7 @@ st10:
2002
1888
  if ( ++p == pe )
2003
1889
  goto _test_eof10;
2004
1890
  case 10:
2005
- #line 2006 "parser.c"
1891
+ #line 1892 "parser.c"
2006
1892
  switch( (*p) ) {
2007
1893
  case 13: goto st10;
2008
1894
  case 32: goto st10;
@@ -2091,30 +1977,13 @@ case 9:
2091
1977
  _out: {}
2092
1978
  }
2093
1979
 
2094
- #line 818 "parser.rl"
2095
-
2096
- if (cs >= JSON_quirks_mode_first_final && p == pe) {
2097
- return result;
2098
- } else {
2099
- rb_enc_raise(EXC_ENCODING eParserError, "%u: unexpected token at '%s'", __LINE__, p);
2100
- return Qnil;
2101
- }
2102
- }
2103
-
2104
- /*
2105
- * call-seq: parse()
2106
- *
2107
- * Parses the current JSON text _source_ and returns the complete data
2108
- * structure as a result.
2109
- */
2110
- static VALUE cParser_parse(VALUE self)
2111
- {
2112
- GET_PARSER;
1980
+ #line 741 "parser.rl"
2113
1981
 
2114
- if (json->quirks_mode) {
2115
- return cParser_parse_quirks_mode(self);
1982
+ if (cs >= JSON_first_final && p == pe) {
1983
+ return result;
2116
1984
  } else {
2117
- return cParser_parse_strict(self);
1985
+ rb_enc_raise(EXC_ENCODING eParserError, "%u: unexpected token at '%s'", __LINE__, p);
1986
+ return Qnil;
2118
1987
  }
2119
1988
  }
2120
1989
 
@@ -2172,18 +2041,6 @@ static VALUE cParser_source(VALUE self)
2172
2041
  return rb_str_dup(json->Vsource);
2173
2042
  }
2174
2043
 
2175
- /*
2176
- * call-seq: quirks_mode?()
2177
- *
2178
- * Returns a true, if this parser is in quirks_mode, false otherwise.
2179
- */
2180
- static VALUE cParser_quirks_mode_p(VALUE self)
2181
- {
2182
- GET_PARSER;
2183
- return json->quirks_mode ? Qtrue : Qfalse;
2184
- }
2185
-
2186
-
2187
2044
  void Init_parser(void)
2188
2045
  {
2189
2046
  rb_require("json/common");
@@ -2196,7 +2053,6 @@ void Init_parser(void)
2196
2053
  rb_define_method(cParser, "initialize", cParser_initialize, -1);
2197
2054
  rb_define_method(cParser, "parse", cParser_parse, 0);
2198
2055
  rb_define_method(cParser, "source", cParser_source, 0);
2199
- rb_define_method(cParser, "quirks_mode?", cParser_quirks_mode_p, 0);
2200
2056
 
2201
2057
  CNaN = rb_const_get(mJSON, rb_intern("NaN"));
2202
2058
  CInfinity = rb_const_get(mJSON, rb_intern("Infinity"));
@@ -2210,7 +2066,6 @@ void Init_parser(void)
2210
2066
  i_max_nesting = rb_intern("max_nesting");
2211
2067
  i_allow_nan = rb_intern("allow_nan");
2212
2068
  i_symbolize_names = rb_intern("symbolize_names");
2213
- i_quirks_mode = rb_intern("quirks_mode");
2214
2069
  i_object_class = rb_intern("object_class");
2215
2070
  i_array_class = rb_intern("array_class");
2216
2071
  i_match = rb_intern("match");
@@ -2220,15 +2075,6 @@ void Init_parser(void)
2220
2075
  i_aset = rb_intern("[]=");
2221
2076
  i_aref = rb_intern("[]");
2222
2077
  i_leftshift = rb_intern("<<");
2223
- #ifdef HAVE_RUBY_ENCODING_H
2224
- UTF_8 = rb_utf8_encoding();
2225
- UTF_16BE = rb_enc_find("utf-16be");
2226
- UTF_16LE = rb_enc_find("utf-16le");
2227
- UTF_32BE = rb_enc_find("utf-32be");
2228
- UTF_32LE = rb_enc_find("utf-32le");
2229
- #else
2230
- i_iconv = rb_intern("iconv");
2231
- #endif
2232
2078
  }
2233
2079
 
2234
2080
  /*