json-maglev- 1.5.4 → 1.6.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (57) hide show
  1. data/CHANGES +11 -1
  2. data/Rakefile +14 -12
  3. data/VERSION +1 -1
  4. data/ext/json/ext/generator/extconf.rb +0 -7
  5. data/ext/json/ext/generator/generator.c +55 -10
  6. data/ext/json/ext/generator/generator.h +7 -5
  7. data/ext/json/ext/parser/extconf.rb +0 -3
  8. data/ext/json/ext/parser/parser.c +418 -207
  9. data/ext/json/ext/parser/parser.h +11 -10
  10. data/ext/json/ext/parser/parser.rl +178 -104
  11. data/install.rb +1 -8
  12. data/java/src/json/ext/Generator.java +3 -3
  13. data/java/src/json/ext/GeneratorMethods.java +2 -2
  14. data/java/src/json/ext/GeneratorService.java +1 -1
  15. data/java/src/json/ext/GeneratorState.java +41 -13
  16. data/java/src/json/ext/OptionsReader.java +1 -1
  17. data/java/src/json/ext/Parser.java +382 -107
  18. data/java/src/json/ext/Parser.rl +97 -28
  19. data/java/src/json/ext/ParserService.java +1 -1
  20. data/java/src/json/ext/Utils.java +1 -1
  21. data/json.gemspec +5 -6
  22. data/json_pure.gemspec +5 -9
  23. data/lib/json.rb +4 -4
  24. data/lib/json/add/complex.rb +22 -0
  25. data/lib/json/add/core.rb +9 -241
  26. data/lib/json/add/date.rb +34 -0
  27. data/lib/json/add/date_time.rb +50 -0
  28. data/lib/json/add/exception.rb +31 -0
  29. data/lib/json/add/range.rb +29 -0
  30. data/lib/json/add/rational.rb +22 -0
  31. data/lib/json/add/regexp.rb +30 -0
  32. data/lib/json/add/struct.rb +30 -0
  33. data/lib/json/add/symbol.rb +25 -0
  34. data/lib/json/add/time.rb +35 -0
  35. data/lib/json/common.rb +47 -35
  36. data/lib/json/ext.rb +2 -15
  37. data/lib/json/pure/generator.rb +17 -2
  38. data/lib/json/pure/parser.rb +89 -55
  39. data/lib/json/version.rb +1 -1
  40. data/tests/test_json.rb +36 -0
  41. data/tests/test_json_addition.rb +8 -1
  42. data/tests/test_json_generate.rb +34 -1
  43. data/tools/server.rb +1 -0
  44. metadata +20 -24
  45. data/bin/edit_json.rb +0 -9
  46. data/bin/prettify_json.rb +0 -48
  47. data/lib/json/Array.xpm +0 -21
  48. data/lib/json/FalseClass.xpm +0 -21
  49. data/lib/json/Hash.xpm +0 -21
  50. data/lib/json/Key.xpm +0 -73
  51. data/lib/json/NilClass.xpm +0 -21
  52. data/lib/json/Numeric.xpm +0 -28
  53. data/lib/json/String.xpm +0 -96
  54. data/lib/json/TrueClass.xpm +0 -21
  55. data/lib/json/add/rails.rb +0 -8
  56. data/lib/json/editor.rb +0 -1369
  57. data/lib/json/json.xpm +0 -1499
data/CHANGES CHANGED
@@ -1,6 +1,16 @@
1
- 2011-07-04 (1.5.4)
1
+ 2011-09-18 (1.6.1)
2
+ * Using -target 1.5 to force Java bits to compile with 1.5.
3
+ 2011-09-12 (1.6.0)
4
+ * Extract utilities (prettifier and GUI-editor) in its own gem json-utils.
5
+ * Split json/add/core into different files for classes to be serialised.
6
+ 2011-08-31 (1.5.4)
2
7
  * Fix memory leak when used from multiple JRuby. (Patch by
3
8
  jfirebaugh@github).
9
+ * Apply patch by Eric Wong <nocode@yhbt.net> that fixes garbage collection problem
10
+ reported in https://github.com/flori/json/issues/46.
11
+ * Add :quirks_mode option to parser and generator.
12
+ * Add support for Rational and Complex number additions via json/add/complex
13
+ and json/add/rational requires.
4
14
  2011-06-20 (1.5.3)
5
15
  * Alias State#configure method as State#merge to increase duck type synonymy with Hash.
6
16
  * Add as_json methods in json/add/core, so rails can create its json objects
data/Rakefile CHANGED
@@ -4,7 +4,12 @@ rescue LoadError
4
4
  end
5
5
 
6
6
  require 'rbconfig'
7
- include Config
7
+ begin
8
+ include RbConfig
9
+ rescue NameError
10
+ include Config
11
+ end
12
+
8
13
 
9
14
  require 'rake/clean'
10
15
  CLOBBER.include Dir['benchmarks/data/*.{dat,log}'], 'doc', 'Gemfile.lock'
@@ -91,10 +96,6 @@ if defined?(Gem) and defined?(Gem::PackageTask)
91
96
  s.add_development_dependency 'bullshit'
92
97
  s.add_development_dependency 'sdoc'
93
98
  s.add_development_dependency 'rake', '~>0.9.2'
94
- s.add_dependency 'spruz', '~>0.2.8'
95
-
96
- s.bindir = "bin"
97
- s.executables = [ "edit_json.rb", "prettify_json.rb" ]
98
99
 
99
100
  s.extra_rdoc_files << 'README.rdoc'
100
101
  s.rdoc_options <<
@@ -136,9 +137,6 @@ if defined?(Gem) and defined?(Gem::PackageTask)
136
137
  s.add_development_dependency 'bullshit'
137
138
  s.add_development_dependency 'sdoc'
138
139
 
139
- s.bindir = "bin"
140
- s.executables = [ "edit_json.rb", "prettify_json.rb" ]
141
-
142
140
  s.extra_rdoc_files << 'README.rdoc'
143
141
  s.rdoc_options <<
144
142
  '--title' << 'JSON implemention for Ruby' << '--main' << 'README.rdoc'
@@ -228,13 +226,13 @@ if defined?(RUBY_ENGINE) and RUBY_ENGINE == 'jruby'
228
226
  rm_rf JAVA_PARSER_SRC
229
227
  end
230
228
 
231
- JRUBY_JAR = File.join(Config::CONFIG["libdir"], "jruby.jar")
229
+ JRUBY_JAR = File.join(CONFIG["libdir"], "jruby.jar")
232
230
  if File.exist?(JRUBY_JAR)
233
231
  JAVA_SOURCES.each do |src|
234
232
  classpath = (Dir['java/lib/*.jar'] << 'java/src' << JRUBY_JAR) * ':'
235
233
  obj = src.sub(/\.java\Z/, '.class')
236
234
  file obj => src do
237
- sh 'javac', '-classpath', classpath, '-source', '1.5', src
235
+ sh 'javac', '-classpath', classpath, '-source', '1.5', '-target', '1.5', src
238
236
  end
239
237
  JAVA_CLASSES << obj
240
238
  end
@@ -298,7 +296,9 @@ if defined?(RUBY_ENGINE) and RUBY_ENGINE == 'jruby'
298
296
  task :create_jar => [ :create_parser_jar, :create_generator_jar ]
299
297
 
300
298
  desc "Build all gems and archives for a new release of the jruby extension."
301
- task :release => [ :clean, :version, :jruby_gem ]
299
+ task :build => [ :clean, :version, :jruby_gem ]
300
+
301
+ task :release => :build
302
302
  else
303
303
  desc "Compiling extension"
304
304
  task :compile => [ EXT_PARSER_DL, EXT_GENERATOR_DL ]
@@ -400,7 +400,9 @@ else
400
400
  task :ragel_dot => [ :ragel_dot_png, :ragel_dot_ps ]
401
401
 
402
402
  desc "Build all gems and archives for a new release of json and json_pure."
403
- task :release => [ :clean, :gemspec, :package ]
403
+ task :build => [ :clean, :gemspec, :package ]
404
+
405
+ task :release => :build
404
406
  end
405
407
 
406
408
  desc "Compile in the the source directory"
data/VERSION CHANGED
@@ -1 +1 @@
1
- 1.5.4
1
+ 1.6.1
@@ -1,5 +1,4 @@
1
1
  require 'mkmf'
2
- require 'rbconfig'
3
2
 
4
3
  unless $CFLAGS.gsub!(/ -O[\dsz]?/, ' -O3')
5
4
  $CFLAGS << ' -O3'
@@ -11,10 +10,4 @@ if CONFIG['CC'] =~ /gcc/
11
10
  #end
12
11
  end
13
12
 
14
- if RUBY_VERSION < "1.9"
15
- have_header("re.h")
16
- else
17
- have_header("ruby/re.h")
18
- have_header("ruby/encoding.h")
19
- end
20
13
  create_makefile 'json/ext/generator'
@@ -13,8 +13,8 @@ static VALUE mJSON, mExt, mGenerator, cState, mGeneratorMethods, mObject,
13
13
 
14
14
  static ID i_to_s, i_to_json, i_new, i_indent, i_space, i_space_before,
15
15
  i_object_nl, i_array_nl, i_max_nesting, i_allow_nan, i_ascii_only,
16
- i_pack, i_unpack, i_create_id, i_extend, i_key_p, i_aref, i_send,
17
- i_respond_to_p, i_match, i_keys, i_depth, i_dup;
16
+ i_quirks_mode, i_pack, i_unpack, i_create_id, i_extend, i_key_p,
17
+ i_aref, i_send, i_respond_to_p, i_match, i_keys, i_depth, i_dup;
18
18
 
19
19
  /*
20
20
  * Copyright 2001-2004 Unicode, Inc.
@@ -349,6 +349,16 @@ static void fbuffer_append(FBuffer *fb, const char *newstr, unsigned long len)
349
349
  }
350
350
  }
351
351
 
352
+ static void fbuffer_append_str(FBuffer *fb, VALUE str)
353
+ {
354
+ const char *newstr = StringValuePtr(str);
355
+ unsigned long len = RSTRING_LEN(str);
356
+
357
+ RB_GC_GUARD(str);
358
+
359
+ fbuffer_append(fb, newstr, len);
360
+ }
361
+
352
362
  static void fbuffer_append_char(FBuffer *fb, char newchr)
353
363
  {
354
364
  fbuffer_inc_capa(fb, 1);
@@ -688,6 +698,8 @@ static VALUE cState_configure(VALUE self, VALUE opts)
688
698
  state->allow_nan = RTEST(tmp);
689
699
  tmp = rb_hash_aref(opts, ID2SYM(i_ascii_only));
690
700
  state->ascii_only = RTEST(tmp);
701
+ tmp = rb_hash_aref(opts, ID2SYM(i_quirks_mode));
702
+ state->quirks_mode = RTEST(tmp);
691
703
  return self;
692
704
  }
693
705
 
@@ -708,6 +720,7 @@ static VALUE cState_to_h(VALUE self)
708
720
  rb_hash_aset(result, ID2SYM(i_array_nl), rb_str_new(state->array_nl, state->array_nl_len));
709
721
  rb_hash_aset(result, ID2SYM(i_allow_nan), state->allow_nan ? Qtrue : Qfalse);
710
722
  rb_hash_aset(result, ID2SYM(i_ascii_only), state->ascii_only ? Qtrue : Qfalse);
723
+ rb_hash_aset(result, ID2SYM(i_quirks_mode), state->quirks_mode ? Qtrue : Qfalse);
711
724
  rb_hash_aset(result, ID2SYM(i_max_nesting), LONG2FIX(state->max_nesting));
712
725
  rb_hash_aset(result, ID2SYM(i_depth), LONG2FIX(state->depth));
713
726
  return result;
@@ -852,7 +865,7 @@ static void generate_json_fixnum(FBuffer *buffer, VALUE Vstate, JSON_Generator_S
852
865
  static void generate_json_bignum(FBuffer *buffer, VALUE Vstate, JSON_Generator_State *state, VALUE obj)
853
866
  {
854
867
  VALUE tmp = rb_funcall(obj, i_to_s, 0);
855
- fbuffer_append(buffer, RSTRING_PAIR(tmp));
868
+ fbuffer_append_str(buffer, tmp);
856
869
  }
857
870
 
858
871
  static void generate_json_float(FBuffer *buffer, VALUE Vstate, JSON_Generator_State *state, VALUE obj)
@@ -869,7 +882,7 @@ static void generate_json_float(FBuffer *buffer, VALUE Vstate, JSON_Generator_St
869
882
  rb_raise(eGeneratorError, "%u: %s not allowed in JSON", __LINE__, StringValueCStr(tmp));
870
883
  }
871
884
  }
872
- fbuffer_append(buffer, RSTRING_PAIR(tmp));
885
+ fbuffer_append_str(buffer, tmp);
873
886
  }
874
887
 
875
888
  static void generate_json(FBuffer *buffer, VALUE Vstate, JSON_Generator_State *state, VALUE obj)
@@ -897,7 +910,7 @@ static void generate_json(FBuffer *buffer, VALUE Vstate, JSON_Generator_State *s
897
910
  } else if (rb_respond_to(obj, i_to_json)) {
898
911
  tmp = rb_funcall(obj, i_to_json, 1, Vstate);
899
912
  Check_Type(tmp, T_STRING);
900
- fbuffer_append(buffer, RSTRING_PAIR(tmp));
913
+ fbuffer_append_str(buffer, tmp);
901
914
  } else {
902
915
  tmp = rb_funcall(obj, i_to_s, 0);
903
916
  Check_Type(tmp, T_STRING);
@@ -961,11 +974,14 @@ static VALUE cState_generate(VALUE self, VALUE obj)
961
974
  {
962
975
  VALUE result = cState_partial_generate(self, obj);
963
976
  VALUE re, args[2];
964
- args[0] = rb_str_new2("\\A\\s*(?:\\[.*\\]|\\{.*\\})\\s*\\Z");
965
- args[1] = CRegexp_MULTILINE;
966
- re = rb_class_new_instance(2, args, rb_cRegexp);
967
- if (NIL_P(rb_funcall(re, i_match, 1, result))) {
968
- rb_raise(eGeneratorError, "only generation of JSON objects or arrays allowed");
977
+ GET_STATE(self);
978
+ if (!state->quirks_mode) {
979
+ args[0] = rb_str_new2("\\A\\s*(?:\\[.*\\]|\\{.*\\})\\s*\\Z");
980
+ args[1] = CRegexp_MULTILINE;
981
+ re = rb_class_new_instance(2, args, rb_cRegexp);
982
+ if (NIL_P(rb_funcall(re, i_match, 1, result))) {
983
+ rb_raise(eGeneratorError, "only generation of JSON objects or arrays allowed");
984
+ }
969
985
  }
970
986
  return result;
971
987
  }
@@ -985,6 +1001,8 @@ static VALUE cState_generate(VALUE self, VALUE obj)
985
1001
  * * *allow_nan*: true if NaN, Infinity, and -Infinity should be
986
1002
  * generated, otherwise an exception is thrown, if these values are
987
1003
  * encountered. This options defaults to false.
1004
+ * * *quirks_mode*: Enables quirks_mode for parser, that is for example
1005
+ * generating single JSON values instead of documents is possible.
988
1006
  */
989
1007
  static VALUE cState_initialize(int argc, VALUE *argv, VALUE self)
990
1008
  {
@@ -1287,6 +1305,29 @@ static VALUE cState_ascii_only_p(VALUE self)
1287
1305
  return state->ascii_only ? Qtrue : Qfalse;
1288
1306
  }
1289
1307
 
1308
+ /*
1309
+ * call-seq: quirks_mode?
1310
+ *
1311
+ * Returns true, if quirks mode is enabled. Otherwise returns false.
1312
+ */
1313
+ static VALUE cState_quirks_mode_p(VALUE self)
1314
+ {
1315
+ GET_STATE(self);
1316
+ return state->quirks_mode ? Qtrue : Qfalse;
1317
+ }
1318
+
1319
+ /*
1320
+ * call-seq: quirks_mode=(enable)
1321
+ *
1322
+ * If set to true, enables the quirks_mode mode.
1323
+ */
1324
+ static VALUE cState_quirks_mode_set(VALUE self, VALUE enable)
1325
+ {
1326
+ GET_STATE(self);
1327
+ state->quirks_mode = RTEST(enable);
1328
+ return Qnil;
1329
+ }
1330
+
1290
1331
  /*
1291
1332
  * call-seq: depth
1292
1333
  *
@@ -1345,6 +1386,9 @@ void Init_generator()
1345
1386
  rb_define_method(cState, "check_circular?", cState_check_circular_p, 0);
1346
1387
  rb_define_method(cState, "allow_nan?", cState_allow_nan_p, 0);
1347
1388
  rb_define_method(cState, "ascii_only?", cState_ascii_only_p, 0);
1389
+ rb_define_method(cState, "quirks_mode?", cState_quirks_mode_p, 0);
1390
+ rb_define_method(cState, "quirks_mode", cState_quirks_mode_p, 0);
1391
+ rb_define_method(cState, "quirks_mode=", cState_quirks_mode_set, 1);
1348
1392
  rb_define_method(cState, "depth", cState_depth, 0);
1349
1393
  rb_define_method(cState, "depth=", cState_depth_set, 1);
1350
1394
  rb_define_method(cState, "configure", cState_configure, 1);
@@ -1392,6 +1436,7 @@ void Init_generator()
1392
1436
  i_max_nesting = rb_intern("max_nesting");
1393
1437
  i_allow_nan = rb_intern("allow_nan");
1394
1438
  i_ascii_only = rb_intern("ascii_only");
1439
+ i_quirks_mode = rb_intern("quirks_mode");
1395
1440
  i_depth = rb_intern("depth");
1396
1441
  i_pack = rb_intern("pack");
1397
1442
  i_unpack = rb_intern("unpack");
@@ -7,11 +7,9 @@
7
7
 
8
8
  #include "ruby.h"
9
9
 
10
- #if HAVE_RUBY_RE_H
10
+ #ifdef HAVE_RUBY_RE_H
11
11
  #include "ruby/re.h"
12
- #endif
13
-
14
- #if HAVE_RE_H
12
+ #else
15
13
  #include "re.h"
16
14
  #endif
17
15
 
@@ -45,7 +43,10 @@
45
43
  #define RSTRING_LEN(string) RSTRING(string)->len
46
44
  #endif
47
45
 
48
- #define RSTRING_PAIR(string) RSTRING_PTR(string), RSTRING_LEN(string)
46
+ /* We don't need to guard objects for rbx, so let's do nothing at all. */
47
+ #ifndef RB_GC_GUARD
48
+ #define RB_GC_GUARD(object)
49
+ #endif
49
50
 
50
51
  /* fbuffer implementation */
51
52
 
@@ -123,6 +124,7 @@ typedef struct JSON_Generator_StateStruct {
123
124
  long max_nesting;
124
125
  char allow_nan;
125
126
  char ascii_only;
127
+ char quirks_mode;
126
128
  long depth;
127
129
  } JSON_Generator_State;
128
130
 
@@ -1,5 +1,4 @@
1
1
  require 'mkmf'
2
- require 'rbconfig'
3
2
 
4
3
  unless $CFLAGS.gsub!(/ -O[\dsz]?/, ' -O3')
5
4
  $CFLAGS << ' -O3'
@@ -11,6 +10,4 @@ if CONFIG['CC'] =~ /gcc/
11
10
  #end
12
11
  end
13
12
 
14
- have_header("re.h")
15
- have_header("ruby/st.h")
16
13
  create_makefile 'json/ext/parser'
@@ -78,15 +78,16 @@ static VALUE mJSON, mExt, cParser, eParserError, eNestingError;
78
78
  static VALUE CNaN, CInfinity, CMinusInfinity;
79
79
 
80
80
  static ID i_json_creatable_p, i_json_create, i_create_id, i_create_additions,
81
- i_chr, i_max_nesting, i_allow_nan, i_symbolize_names, i_object_class,
82
- i_array_class, i_key_p, i_deep_const_get, i_match, i_match_string, i_aset, i_leftshift;
81
+ i_chr, i_max_nesting, i_allow_nan, i_symbolize_names, i_quirks_mode,
82
+ i_object_class, i_array_class, i_key_p, i_deep_const_get, i_match,
83
+ i_match_string, i_aset, i_leftshift;
83
84
 
84
85
 
85
- #line 108 "parser.rl"
86
+ #line 109 "parser.rl"
86
87
 
87
88
 
88
89
 
89
- #line 90 "parser.c"
90
+ #line 91 "parser.c"
90
91
  static const int JSON_object_start = 1;
91
92
  static const int JSON_object_first_final = 27;
92
93
  static const int JSON_object_error = 0;
@@ -94,10 +95,10 @@ static const int JSON_object_error = 0;
94
95
  static const int JSON_object_en_main = 1;
95
96
 
96
97
 
97
- #line 148 "parser.rl"
98
+ #line 150 "parser.rl"
98
99
 
99
100
 
100
- static const char *JSON_parse_object(JSON_Parser *json, const char *p, const char *pe, VALUE *result)
101
+ static char *JSON_parse_object(JSON_Parser *json, char *p, char *pe, VALUE *result)
101
102
  {
102
103
  int cs = EVIL;
103
104
  VALUE last_name = Qnil;
@@ -110,14 +111,14 @@ static const char *JSON_parse_object(JSON_Parser *json, const char *p, const cha
110
111
  *result = NIL_P(object_class) ? rb_hash_new() : rb_class_new_instance(0, 0, object_class);
111
112
 
112
113
 
113
- #line 114 "parser.c"
114
+ #line 115 "parser.c"
114
115
  {
115
116
  cs = JSON_object_start;
116
117
  }
117
118
 
118
- #line 163 "parser.rl"
119
+ #line 165 "parser.rl"
119
120
 
120
- #line 121 "parser.c"
121
+ #line 122 "parser.c"
121
122
  {
122
123
  if ( p == pe )
123
124
  goto _test_eof;
@@ -145,9 +146,9 @@ case 2:
145
146
  goto st2;
146
147
  goto st0;
147
148
  tr2:
148
- #line 131 "parser.rl"
149
+ #line 132 "parser.rl"
149
150
  {
150
- const char *np;
151
+ char *np;
151
152
  json->parsing_name = 1;
152
153
  np = JSON_parse_string(json, p, pe, &last_name);
153
154
  json->parsing_name = 0;
@@ -158,7 +159,7 @@ st3:
158
159
  if ( ++p == pe )
159
160
  goto _test_eof3;
160
161
  case 3:
161
- #line 162 "parser.c"
162
+ #line 163 "parser.c"
162
163
  switch( (*p) ) {
163
164
  case 13: goto st3;
164
165
  case 32: goto st3;
@@ -225,10 +226,10 @@ case 8:
225
226
  goto st8;
226
227
  goto st0;
227
228
  tr11:
228
- #line 116 "parser.rl"
229
+ #line 117 "parser.rl"
229
230
  {
230
231
  VALUE v = Qnil;
231
- const char *np = JSON_parse_value(json, p, pe, &v);
232
+ char *np = JSON_parse_value(json, p, pe, &v);
232
233
  if (np == NULL) {
233
234
  p--; {p++; cs = 9; goto _out;}
234
235
  } else {
@@ -245,7 +246,7 @@ st9:
245
246
  if ( ++p == pe )
246
247
  goto _test_eof9;
247
248
  case 9:
248
- #line 249 "parser.c"
249
+ #line 250 "parser.c"
249
250
  switch( (*p) ) {
250
251
  case 13: goto st9;
251
252
  case 32: goto st9;
@@ -334,14 +335,14 @@ case 18:
334
335
  goto st9;
335
336
  goto st18;
336
337
  tr4:
337
- #line 139 "parser.rl"
338
+ #line 140 "parser.rl"
338
339
  { p--; {p++; cs = 27; goto _out;} }
339
340
  goto st27;
340
341
  st27:
341
342
  if ( ++p == pe )
342
343
  goto _test_eof27;
343
344
  case 27:
344
- #line 345 "parser.c"
345
+ #line 346 "parser.c"
345
346
  goto st0;
346
347
  st19:
347
348
  if ( ++p == pe )
@@ -439,7 +440,7 @@ case 26:
439
440
  _out: {}
440
441
  }
441
442
 
442
- #line 164 "parser.rl"
443
+ #line 166 "parser.rl"
443
444
 
444
445
  if (cs >= JSON_object_first_final) {
445
446
  if (json->create_additions) {
@@ -458,7 +459,8 @@ case 26:
458
459
  }
459
460
 
460
461
 
461
- #line 462 "parser.c"
462
+
463
+ #line 464 "parser.c"
462
464
  static const int JSON_value_start = 1;
463
465
  static const int JSON_value_first_final = 21;
464
466
  static const int JSON_value_error = 0;
@@ -466,22 +468,22 @@ static const int JSON_value_error = 0;
466
468
  static const int JSON_value_en_main = 1;
467
469
 
468
470
 
469
- #line 262 "parser.rl"
471
+ #line 265 "parser.rl"
470
472
 
471
473
 
472
- static const char *JSON_parse_value(JSON_Parser *json, const char *p, const char *pe, VALUE *result)
474
+ static char *JSON_parse_value(JSON_Parser *json, char *p, char *pe, VALUE *result)
473
475
  {
474
476
  int cs = EVIL;
475
477
 
476
478
 
477
- #line 478 "parser.c"
479
+ #line 480 "parser.c"
478
480
  {
479
481
  cs = JSON_value_start;
480
482
  }
481
483
 
482
- #line 269 "parser.rl"
484
+ #line 272 "parser.rl"
483
485
 
484
- #line 485 "parser.c"
486
+ #line 487 "parser.c"
485
487
  {
486
488
  if ( p == pe )
487
489
  goto _test_eof;
@@ -506,17 +508,17 @@ st0:
506
508
  cs = 0;
507
509
  goto _out;
508
510
  tr0:
509
- #line 210 "parser.rl"
511
+ #line 213 "parser.rl"
510
512
  {
511
- const char *np = JSON_parse_string(json, p, pe, result);
513
+ char *np = JSON_parse_string(json, p, pe, result);
512
514
  if (np == NULL) { p--; {p++; cs = 21; goto _out;} } else {p = (( np))-1;}
513
515
  }
514
516
  goto st21;
515
517
  tr2:
516
- #line 215 "parser.rl"
518
+ #line 218 "parser.rl"
517
519
  {
518
- const char *np;
519
- if(pe > p + 9 && !strncmp(MinusInfinity, p, 9)) {
520
+ char *np;
521
+ if(pe > p + 9 - json->quirks_mode && !strncmp(MinusInfinity, p, 9)) {
520
522
  if (json->allow_nan) {
521
523
  *result = CMinusInfinity;
522
524
  {p = (( p + 10))-1;}
@@ -533,9 +535,9 @@ tr2:
533
535
  }
534
536
  goto st21;
535
537
  tr5:
536
- #line 233 "parser.rl"
538
+ #line 236 "parser.rl"
537
539
  {
538
- const char *np;
540
+ char *np;
539
541
  json->current_nesting++;
540
542
  np = JSON_parse_array(json, p, pe, result);
541
543
  json->current_nesting--;
@@ -543,9 +545,9 @@ tr5:
543
545
  }
544
546
  goto st21;
545
547
  tr9:
546
- #line 241 "parser.rl"
548
+ #line 244 "parser.rl"
547
549
  {
548
- const char *np;
550
+ char *np;
549
551
  json->current_nesting++;
550
552
  np = JSON_parse_object(json, p, pe, result);
551
553
  json->current_nesting--;
@@ -553,7 +555,7 @@ tr9:
553
555
  }
554
556
  goto st21;
555
557
  tr16:
556
- #line 203 "parser.rl"
558
+ #line 206 "parser.rl"
557
559
  {
558
560
  if (json->allow_nan) {
559
561
  *result = CInfinity;
@@ -563,7 +565,7 @@ tr16:
563
565
  }
564
566
  goto st21;
565
567
  tr18:
566
- #line 196 "parser.rl"
568
+ #line 199 "parser.rl"
567
569
  {
568
570
  if (json->allow_nan) {
569
571
  *result = CNaN;
@@ -573,19 +575,19 @@ tr18:
573
575
  }
574
576
  goto st21;
575
577
  tr22:
576
- #line 190 "parser.rl"
578
+ #line 193 "parser.rl"
577
579
  {
578
580
  *result = Qfalse;
579
581
  }
580
582
  goto st21;
581
583
  tr25:
582
- #line 187 "parser.rl"
584
+ #line 190 "parser.rl"
583
585
  {
584
586
  *result = Qnil;
585
587
  }
586
588
  goto st21;
587
589
  tr28:
588
- #line 193 "parser.rl"
590
+ #line 196 "parser.rl"
589
591
  {
590
592
  *result = Qtrue;
591
593
  }
@@ -594,9 +596,9 @@ st21:
594
596
  if ( ++p == pe )
595
597
  goto _test_eof21;
596
598
  case 21:
597
- #line 249 "parser.rl"
599
+ #line 252 "parser.rl"
598
600
  { p--; {p++; cs = 21; goto _out;} }
599
- #line 600 "parser.c"
601
+ #line 602 "parser.c"
600
602
  goto st0;
601
603
  st2:
602
604
  if ( ++p == pe )
@@ -757,7 +759,7 @@ case 20:
757
759
  _out: {}
758
760
  }
759
761
 
760
- #line 270 "parser.rl"
762
+ #line 273 "parser.rl"
761
763
 
762
764
  if (cs >= JSON_value_first_final) {
763
765
  return p;
@@ -767,31 +769,31 @@ case 20:
767
769
  }
768
770
 
769
771
 
770
- #line 771 "parser.c"
772
+ #line 773 "parser.c"
771
773
  static const int JSON_integer_start = 1;
772
- static const int JSON_integer_first_final = 5;
774
+ static const int JSON_integer_first_final = 3;
773
775
  static const int JSON_integer_error = 0;
774
776
 
775
777
  static const int JSON_integer_en_main = 1;
776
778
 
777
779
 
778
- #line 286 "parser.rl"
780
+ #line 289 "parser.rl"
779
781
 
780
782
 
781
- static const char *JSON_parse_integer(JSON_Parser *json, const char *p, const char *pe, VALUE *result)
783
+ static char *JSON_parse_integer(JSON_Parser *json, char *p, char *pe, VALUE *result)
782
784
  {
783
785
  int cs = EVIL;
784
786
 
785
787
 
786
- #line 787 "parser.c"
788
+ #line 789 "parser.c"
787
789
  {
788
790
  cs = JSON_integer_start;
789
791
  }
790
792
 
791
- #line 293 "parser.rl"
793
+ #line 296 "parser.rl"
792
794
  json->memo = p;
793
795
 
794
- #line 795 "parser.c"
796
+ #line 797 "parser.c"
795
797
  {
796
798
  if ( p == pe )
797
799
  goto _test_eof;
@@ -803,7 +805,7 @@ case 1:
803
805
  case 48: goto st3;
804
806
  }
805
807
  if ( 49 <= (*p) && (*p) <= 57 )
806
- goto st4;
808
+ goto st5;
807
809
  goto st0;
808
810
  st0:
809
811
  cs = 0;
@@ -815,7 +817,7 @@ case 2:
815
817
  if ( (*p) == 48 )
816
818
  goto st3;
817
819
  if ( 49 <= (*p) && (*p) <= 57 )
818
- goto st4;
820
+ goto st5;
819
821
  goto st0;
820
822
  st3:
821
823
  if ( ++p == pe )
@@ -825,33 +827,33 @@ case 3:
825
827
  goto st0;
826
828
  goto tr4;
827
829
  tr4:
828
- #line 283 "parser.rl"
829
- { p--; {p++; cs = 5; goto _out;} }
830
- goto st5;
831
- st5:
832
- if ( ++p == pe )
833
- goto _test_eof5;
834
- case 5:
835
- #line 836 "parser.c"
836
- goto st0;
830
+ #line 286 "parser.rl"
831
+ { p--; {p++; cs = 4; goto _out;} }
832
+ goto st4;
837
833
  st4:
838
834
  if ( ++p == pe )
839
835
  goto _test_eof4;
840
836
  case 4:
837
+ #line 838 "parser.c"
838
+ goto st0;
839
+ st5:
840
+ if ( ++p == pe )
841
+ goto _test_eof5;
842
+ case 5:
841
843
  if ( 48 <= (*p) && (*p) <= 57 )
842
- goto st4;
844
+ goto st5;
843
845
  goto tr4;
844
846
  }
845
847
  _test_eof2: cs = 2; goto _test_eof;
846
848
  _test_eof3: cs = 3; goto _test_eof;
847
- _test_eof5: cs = 5; goto _test_eof;
848
849
  _test_eof4: cs = 4; goto _test_eof;
850
+ _test_eof5: cs = 5; goto _test_eof;
849
851
 
850
852
  _test_eof: {}
851
853
  _out: {}
852
854
  }
853
855
 
854
- #line 295 "parser.rl"
856
+ #line 298 "parser.rl"
855
857
 
856
858
  if (cs >= JSON_integer_first_final) {
857
859
  long len = p - json->memo;
@@ -863,31 +865,31 @@ case 4:
863
865
  }
864
866
 
865
867
 
866
- #line 867 "parser.c"
868
+ #line 869 "parser.c"
867
869
  static const int JSON_float_start = 1;
868
- static const int JSON_float_first_final = 10;
870
+ static const int JSON_float_first_final = 8;
869
871
  static const int JSON_float_error = 0;
870
872
 
871
873
  static const int JSON_float_en_main = 1;
872
874
 
873
875
 
874
- #line 317 "parser.rl"
876
+ #line 320 "parser.rl"
875
877
 
876
878
 
877
- static const char *JSON_parse_float(JSON_Parser *json, const char *p, const char *pe, VALUE *result)
879
+ static char *JSON_parse_float(JSON_Parser *json, char *p, char *pe, VALUE *result)
878
880
  {
879
881
  int cs = EVIL;
880
882
 
881
883
 
882
- #line 883 "parser.c"
884
+ #line 885 "parser.c"
883
885
  {
884
886
  cs = JSON_float_start;
885
887
  }
886
888
 
887
- #line 324 "parser.rl"
889
+ #line 327 "parser.rl"
888
890
  json->memo = p;
889
891
 
890
- #line 891 "parser.c"
892
+ #line 893 "parser.c"
891
893
  {
892
894
  if ( p == pe )
893
895
  goto _test_eof;
@@ -899,7 +901,7 @@ case 1:
899
901
  case 48: goto st3;
900
902
  }
901
903
  if ( 49 <= (*p) && (*p) <= 57 )
902
- goto st9;
904
+ goto st7;
903
905
  goto st0;
904
906
  st0:
905
907
  cs = 0;
@@ -911,7 +913,7 @@ case 2:
911
913
  if ( (*p) == 48 )
912
914
  goto st3;
913
915
  if ( 49 <= (*p) && (*p) <= 57 )
914
- goto st9;
916
+ goto st7;
915
917
  goto st0;
916
918
  st3:
917
919
  if ( ++p == pe )
@@ -919,8 +921,8 @@ st3:
919
921
  case 3:
920
922
  switch( (*p) ) {
921
923
  case 46: goto st4;
922
- case 69: goto st6;
923
- case 101: goto st6;
924
+ case 69: goto st5;
925
+ case 101: goto st5;
924
926
  }
925
927
  goto st0;
926
928
  st4:
@@ -928,92 +930,92 @@ st4:
928
930
  goto _test_eof4;
929
931
  case 4:
930
932
  if ( 48 <= (*p) && (*p) <= 57 )
931
- goto st5;
933
+ goto st8;
932
934
  goto st0;
933
- st5:
935
+ st8:
934
936
  if ( ++p == pe )
935
- goto _test_eof5;
936
- case 5:
937
+ goto _test_eof8;
938
+ case 8:
937
939
  switch( (*p) ) {
938
- case 69: goto st6;
939
- case 101: goto st6;
940
+ case 69: goto st5;
941
+ case 101: goto st5;
940
942
  }
941
943
  if ( (*p) > 46 ) {
942
944
  if ( 48 <= (*p) && (*p) <= 57 )
943
- goto st5;
945
+ goto st8;
944
946
  } else if ( (*p) >= 45 )
945
947
  goto st0;
946
- goto tr7;
947
- tr7:
948
- #line 311 "parser.rl"
949
- { p--; {p++; cs = 10; goto _out;} }
950
- goto st10;
951
- st10:
948
+ goto tr9;
949
+ tr9:
950
+ #line 314 "parser.rl"
951
+ { p--; {p++; cs = 9; goto _out;} }
952
+ goto st9;
953
+ st9:
952
954
  if ( ++p == pe )
953
- goto _test_eof10;
954
- case 10:
955
- #line 956 "parser.c"
955
+ goto _test_eof9;
956
+ case 9:
957
+ #line 958 "parser.c"
956
958
  goto st0;
957
- st6:
959
+ st5:
958
960
  if ( ++p == pe )
959
- goto _test_eof6;
960
- case 6:
961
+ goto _test_eof5;
962
+ case 5:
961
963
  switch( (*p) ) {
962
- case 43: goto st7;
963
- case 45: goto st7;
964
+ case 43: goto st6;
965
+ case 45: goto st6;
964
966
  }
965
967
  if ( 48 <= (*p) && (*p) <= 57 )
966
- goto st8;
968
+ goto st10;
967
969
  goto st0;
968
- st7:
970
+ st6:
969
971
  if ( ++p == pe )
970
- goto _test_eof7;
971
- case 7:
972
+ goto _test_eof6;
973
+ case 6:
972
974
  if ( 48 <= (*p) && (*p) <= 57 )
973
- goto st8;
975
+ goto st10;
974
976
  goto st0;
975
- st8:
977
+ st10:
976
978
  if ( ++p == pe )
977
- goto _test_eof8;
978
- case 8:
979
+ goto _test_eof10;
980
+ case 10:
979
981
  switch( (*p) ) {
980
982
  case 69: goto st0;
981
983
  case 101: goto st0;
982
984
  }
983
985
  if ( (*p) > 46 ) {
984
986
  if ( 48 <= (*p) && (*p) <= 57 )
985
- goto st8;
987
+ goto st10;
986
988
  } else if ( (*p) >= 45 )
987
989
  goto st0;
988
- goto tr7;
989
- st9:
990
+ goto tr9;
991
+ st7:
990
992
  if ( ++p == pe )
991
- goto _test_eof9;
992
- case 9:
993
+ goto _test_eof7;
994
+ case 7:
993
995
  switch( (*p) ) {
994
996
  case 46: goto st4;
995
- case 69: goto st6;
996
- case 101: goto st6;
997
+ case 69: goto st5;
998
+ case 101: goto st5;
997
999
  }
998
1000
  if ( 48 <= (*p) && (*p) <= 57 )
999
- goto st9;
1001
+ goto st7;
1000
1002
  goto st0;
1001
1003
  }
1002
1004
  _test_eof2: cs = 2; goto _test_eof;
1003
1005
  _test_eof3: cs = 3; goto _test_eof;
1004
1006
  _test_eof4: cs = 4; goto _test_eof;
1007
+ _test_eof8: cs = 8; goto _test_eof;
1008
+ _test_eof9: cs = 9; goto _test_eof;
1005
1009
  _test_eof5: cs = 5; goto _test_eof;
1006
- _test_eof10: cs = 10; goto _test_eof;
1007
1010
  _test_eof6: cs = 6; goto _test_eof;
1011
+ _test_eof10: cs = 10; goto _test_eof;
1008
1012
  _test_eof7: cs = 7; goto _test_eof;
1009
- _test_eof8: cs = 8; goto _test_eof;
1010
- _test_eof9: cs = 9; goto _test_eof;
1011
1013
 
1012
1014
  _test_eof: {}
1013
1015
  _out: {}
1014
1016
  }
1015
1017
 
1016
- #line 326 "parser.rl"
1018
+ #line 329 "parser.rl"
1017
1019
 
1018
1020
  if (cs >= JSON_float_first_final) {
1019
1021
  long len = p - json->memo;
@@ -1026,7 +1028,7 @@ case 9:
1026
1028
 
1027
1029
 
1028
1030
 
1029
- #line 1030 "parser.c"
1031
+ #line 1032 "parser.c"
1030
1032
  static const int JSON_array_start = 1;
1031
1033
  static const int JSON_array_first_final = 17;
1032
1034
  static const int JSON_array_error = 0;
@@ -1034,10 +1036,10 @@ static const int JSON_array_error = 0;
1034
1036
  static const int JSON_array_en_main = 1;
1035
1037
 
1036
1038
 
1037
- #line 366 "parser.rl"
1039
+ #line 369 "parser.rl"
1038
1040
 
1039
1041
 
1040
- static const char *JSON_parse_array(JSON_Parser *json, const char *p, const char *pe, VALUE *result)
1042
+ static char *JSON_parse_array(JSON_Parser *json, char *p, char *pe, VALUE *result)
1041
1043
  {
1042
1044
  int cs = EVIL;
1043
1045
  VALUE array_class = json->array_class;
@@ -1048,14 +1050,14 @@ static const char *JSON_parse_array(JSON_Parser *json, const char *p, const char
1048
1050
  *result = NIL_P(array_class) ? rb_ary_new() : rb_class_new_instance(0, 0, array_class);
1049
1051
 
1050
1052
 
1051
- #line 1052 "parser.c"
1053
+ #line 1054 "parser.c"
1052
1054
  {
1053
1055
  cs = JSON_array_start;
1054
1056
  }
1055
1057
 
1056
- #line 379 "parser.rl"
1058
+ #line 382 "parser.rl"
1057
1059
 
1058
- #line 1059 "parser.c"
1060
+ #line 1061 "parser.c"
1059
1061
  {
1060
1062
  if ( p == pe )
1061
1063
  goto _test_eof;
@@ -1094,10 +1096,10 @@ case 2:
1094
1096
  goto st2;
1095
1097
  goto st0;
1096
1098
  tr2:
1097
- #line 343 "parser.rl"
1099
+ #line 346 "parser.rl"
1098
1100
  {
1099
1101
  VALUE v = Qnil;
1100
- const char *np = JSON_parse_value(json, p, pe, &v);
1102
+ char *np = JSON_parse_value(json, p, pe, &v);
1101
1103
  if (np == NULL) {
1102
1104
  p--; {p++; cs = 3; goto _out;}
1103
1105
  } else {
@@ -1114,7 +1116,7 @@ st3:
1114
1116
  if ( ++p == pe )
1115
1117
  goto _test_eof3;
1116
1118
  case 3:
1117
- #line 1118 "parser.c"
1119
+ #line 1120 "parser.c"
1118
1120
  switch( (*p) ) {
1119
1121
  case 13: goto st3;
1120
1122
  case 32: goto st3;
@@ -1214,14 +1216,14 @@ case 12:
1214
1216
  goto st3;
1215
1217
  goto st12;
1216
1218
  tr4:
1217
- #line 358 "parser.rl"
1219
+ #line 361 "parser.rl"
1218
1220
  { p--; {p++; cs = 17; goto _out;} }
1219
1221
  goto st17;
1220
1222
  st17:
1221
1223
  if ( ++p == pe )
1222
1224
  goto _test_eof17;
1223
1225
  case 17:
1224
- #line 1225 "parser.c"
1226
+ #line 1227 "parser.c"
1225
1227
  goto st0;
1226
1228
  st13:
1227
1229
  if ( ++p == pe )
@@ -1277,7 +1279,7 @@ case 16:
1277
1279
  _out: {}
1278
1280
  }
1279
1281
 
1280
- #line 380 "parser.rl"
1282
+ #line 383 "parser.rl"
1281
1283
 
1282
1284
  if(cs >= JSON_array_first_final) {
1283
1285
  return p + 1;
@@ -1287,9 +1289,9 @@ case 16:
1287
1289
  }
1288
1290
  }
1289
1291
 
1290
- static VALUE json_string_unescape(VALUE result, const char *string, const char *stringEnd)
1292
+ static VALUE json_string_unescape(VALUE result, char *string, char *stringEnd)
1291
1293
  {
1292
- const char *p = string, *pe = string, *unescape;
1294
+ char *p = string, *pe = string, *unescape;
1293
1295
  int unescape_len;
1294
1296
 
1295
1297
  while (pe < stringEnd) {
@@ -1358,7 +1360,7 @@ static VALUE json_string_unescape(VALUE result, const char *string, const char *
1358
1360
  }
1359
1361
 
1360
1362
 
1361
- #line 1362 "parser.c"
1363
+ #line 1364 "parser.c"
1362
1364
  static const int JSON_string_start = 1;
1363
1365
  static const int JSON_string_first_final = 8;
1364
1366
  static const int JSON_string_error = 0;
@@ -1366,7 +1368,7 @@ static const int JSON_string_error = 0;
1366
1368
  static const int JSON_string_en_main = 1;
1367
1369
 
1368
1370
 
1369
- #line 479 "parser.rl"
1371
+ #line 482 "parser.rl"
1370
1372
 
1371
1373
 
1372
1374
  static int
@@ -1381,20 +1383,22 @@ match_i(VALUE regexp, VALUE klass, VALUE memo)
1381
1383
  return ST_CONTINUE;
1382
1384
  }
1383
1385
 
1384
- static const char *JSON_parse_string(JSON_Parser *json, const char *p, const char *pe, VALUE *result)
1386
+ static char *JSON_parse_string(JSON_Parser *json, char *p, char *pe, VALUE *result)
1385
1387
  {
1386
1388
  int cs = EVIL;
1389
+ VALUE match_string;
1390
+
1387
1391
  *result = rb_str_buf_new(0);
1388
1392
 
1389
- #line 1390 "parser.c"
1393
+ #line 1394 "parser.c"
1390
1394
  {
1391
1395
  cs = JSON_string_start;
1392
1396
  }
1393
1397
 
1394
- #line 498 "parser.rl"
1398
+ #line 503 "parser.rl"
1395
1399
  json->memo = p;
1396
1400
 
1397
- #line 1398 "parser.c"
1401
+ #line 1402 "parser.c"
1398
1402
  {
1399
1403
  if ( p == pe )
1400
1404
  goto _test_eof;
@@ -1419,7 +1423,7 @@ case 2:
1419
1423
  goto st0;
1420
1424
  goto st2;
1421
1425
  tr2:
1422
- #line 465 "parser.rl"
1426
+ #line 468 "parser.rl"
1423
1427
  {
1424
1428
  *result = json_string_unescape(*result, json->memo + 1, p);
1425
1429
  if (NIL_P(*result)) {
@@ -1430,14 +1434,14 @@ tr2:
1430
1434
  {p = (( p + 1))-1;}
1431
1435
  }
1432
1436
  }
1433
- #line 476 "parser.rl"
1437
+ #line 479 "parser.rl"
1434
1438
  { p--; {p++; cs = 8; goto _out;} }
1435
1439
  goto st8;
1436
1440
  st8:
1437
1441
  if ( ++p == pe )
1438
1442
  goto _test_eof8;
1439
1443
  case 8:
1440
- #line 1441 "parser.c"
1444
+ #line 1445 "parser.c"
1441
1445
  goto st0;
1442
1446
  st3:
1443
1447
  if ( ++p == pe )
@@ -1513,11 +1517,9 @@ case 7:
1513
1517
  _out: {}
1514
1518
  }
1515
1519
 
1516
- #line 500 "parser.rl"
1520
+ #line 505 "parser.rl"
1517
1521
 
1518
- if (json->create_additions) {
1519
- VALUE match_string = json->match_string;
1520
- if (RTEST(match_string)) {
1522
+ if (json->create_additions && RTEST(match_string = json->match_string)) {
1521
1523
  VALUE klass;
1522
1524
  VALUE memo = rb_ary_new2(2);
1523
1525
  rb_ary_push(memo, *result);
@@ -1526,7 +1528,6 @@ case 7:
1526
1528
  if (RTEST(klass)) {
1527
1529
  *result = rb_funcall(klass, i_json_create, 1, *result);
1528
1530
  }
1529
- }
1530
1531
  }
1531
1532
 
1532
1533
  if (json->symbolize_names && json->parsing_name) {
@@ -1539,19 +1540,6 @@ case 7:
1539
1540
  }
1540
1541
  }
1541
1542
 
1542
-
1543
-
1544
- #line 1545 "parser.c"
1545
- static const int JSON_start = 1;
1546
- static const int JSON_first_final = 10;
1547
- static const int JSON_error = 0;
1548
-
1549
- static const int JSON_en_main = 1;
1550
-
1551
-
1552
- #line 551 "parser.rl"
1553
-
1554
-
1555
1543
  /*
1556
1544
  * Document-class: JSON::Ext::Parser
1557
1545
  *
@@ -1566,7 +1554,7 @@ static const int JSON_en_main = 1;
1566
1554
 
1567
1555
  static VALUE convert_encoding(VALUE source)
1568
1556
  {
1569
- const char *ptr = RSTRING_PTR(source);
1557
+ char *ptr = RSTRING_PTR(source);
1570
1558
  long len = RSTRING_LEN(source);
1571
1559
  if (len < 2) {
1572
1560
  rb_raise(eParserError, "A JSON text must at least contain two octets!");
@@ -1605,12 +1593,15 @@ static VALUE convert_encoding(VALUE source)
1605
1593
  return source;
1606
1594
  }
1607
1595
 
1608
- static inline void parser_iv_set(JSON_Parser *json, const char* iv_name, VALUE v)
1609
- {
1610
- // store reference to v in a Ruby instVar to keep v alive
1611
- // without using a gc_mark function in Data_Wrap_Struct calls
1612
- rb_iv_set(json->dwrapped_parser, iv_name, v);
1613
- }
1596
+ #if defined MAGLEV
1597
+ // Maglev doesn't support the mark function, keep a reference in the object
1598
+ #define QUOTE(x) #x
1599
+ #define PARSER_SET_REFERENCE(json, field, val) \
1600
+ (json)->field = (val); \
1601
+ rb_iv_set(json->dwrapped_parser, QUOTE(@field), (json)->field);
1602
+ #else
1603
+ #define PARSER_SET_REFERENCE(json, field, val) (json)->field = (val);
1604
+ #endif
1614
1605
 
1615
1606
  /*
1616
1607
  * call-seq: new(source, opts => {})
@@ -1637,27 +1628,19 @@ static inline void parser_iv_set(JSON_Parser *json, const char* iv_name, VALUE v
1637
1628
  * defaults to true.
1638
1629
  * * *object_class*: Defaults to Hash
1639
1630
  * * *array_class*: Defaults to Array
1631
+ * * *quirks_mode*: Enables quirks_mode for parser, that is for example
1632
+ * parsing single JSON values instead of documents is possible.
1633
+ *
1640
1634
  */
1641
-
1642
- static int init_count = 0;
1643
1635
  static VALUE cParser_initialize(int argc, VALUE *argv, VALUE self)
1644
1636
  {
1645
- const char *ptr;
1646
- long len;
1647
1637
  VALUE source, opts;
1648
-
1649
1638
  GET_PARSER_INIT;
1650
- init_count += 1;
1651
1639
 
1652
- #ifndef MAGLEV
1653
- if (json->Vsource) {
1640
+ if (RTEST(json->Vsource)) {
1654
1641
  rb_raise(rb_eTypeError, "already initialized instance");
1655
1642
  }
1656
- #endif
1657
1643
  rb_scan_args(argc, argv, "11", &source, &opts);
1658
- source = convert_encoding(StringValue(source));
1659
- ptr = RSTRING_PTR(source);
1660
- len = RSTRING_LEN(source);
1661
1644
  if (!NIL_P(opts)) {
1662
1645
  opts = rb_convert_type(opts, T_HASH, "Hash", "to_hash");
1663
1646
  if (NIL_P(opts)) {
@@ -1687,6 +1670,13 @@ static VALUE cParser_initialize(int argc, VALUE *argv, VALUE self)
1687
1670
  } else {
1688
1671
  json->symbolize_names = 0;
1689
1672
  }
1673
+ tmp = ID2SYM(i_quirks_mode);
1674
+ if (option_given_p(opts, tmp)) {
1675
+ VALUE quirks_mode = rb_hash_aref(opts, tmp);
1676
+ json->quirks_mode = RTEST(quirks_mode) ? 1 : 0;
1677
+ } else {
1678
+ json->quirks_mode = 0;
1679
+ }
1690
1680
  tmp = ID2SYM(i_create_additions);
1691
1681
  if (option_given_p(opts, tmp)) {
1692
1682
  json->create_additions = RTEST(rb_hash_aref(opts, tmp));
@@ -1695,52 +1685,63 @@ static VALUE cParser_initialize(int argc, VALUE *argv, VALUE self)
1695
1685
  }
1696
1686
  tmp = ID2SYM(i_create_id);
1697
1687
  if (option_given_p(opts, tmp)) {
1698
- json->create_id = rb_hash_aref(opts, tmp);
1688
+ PARSER_SET_REFERENCE(json, create_id, rb_hash_aref(opts, tmp));
1699
1689
  } else {
1700
- json->create_id = rb_funcall(mJSON, i_create_id, 0);
1690
+ PARSER_SET_REFERENCE(json, create_id, rb_funcall(mJSON, i_create_id, 0));
1701
1691
  }
1702
- parser_iv_set(json, "@create_id", json->create_id);
1703
1692
  tmp = ID2SYM(i_object_class);
1704
1693
  if (option_given_p(opts, tmp)) {
1705
- json->object_class = rb_hash_aref(opts, tmp);
1706
- parser_iv_set(json, "@object_class", json->object_class);
1694
+ PARSER_SET_REFERENCE(json, object_class, rb_hash_aref(opts, tmp));
1695
+ } else {
1696
+ PARSER_SET_REFERENCE(json, object_class, Qnil);
1707
1697
  }
1708
1698
  tmp = ID2SYM(i_array_class);
1709
1699
  if (option_given_p(opts, tmp)) {
1710
- json->array_class = rb_hash_aref(opts, tmp);
1711
- parser_iv_set(json, "@array_class", json->array_class);
1700
+ PARSER_SET_REFERENCE(json, array_class, rb_hash_aref(opts, tmp));
1701
+ } else {
1702
+ PARSER_SET_REFERENCE(json, array_class, Qnil);
1712
1703
  }
1713
1704
  tmp = ID2SYM(i_match_string);
1714
1705
  if (option_given_p(opts, tmp)) {
1715
1706
  VALUE match_string = rb_hash_aref(opts, tmp);
1716
- json->match_string = RTEST(match_string) ? match_string : Qnil;
1717
- parser_iv_set(json, "@match_string", json->match_string);
1707
+ PARSER_SET_REFERENCE(json, match_string, RTEST(match_string) ? match_string : Qnil);
1708
+ } else {
1709
+ PARSER_SET_REFERENCE(json, match_string, Qnil);
1718
1710
  }
1719
1711
  }
1720
1712
  } else {
1721
1713
  json->max_nesting = 19;
1722
1714
  json->allow_nan = 0;
1723
1715
  json->create_additions = 1;
1724
- json->create_id = rb_funcall(mJSON, i_create_id, 0);
1725
- parser_iv_set(json, "@create_id", json->create_id);
1716
+ PARSER_SET_REFERENCE(json, create_id, rb_funcall(mJSON, i_create_id, 0));
1717
+ json->object_class = Qnil;
1718
+ json->array_class = Qnil;
1719
+ }
1720
+ if (!json->quirks_mode) {
1721
+ source = convert_encoding(StringValue(source));
1726
1722
  }
1727
1723
  json->current_nesting = 0;
1728
- json->len = len;
1729
- json->source = ptr;
1730
- json->Vsource = source;
1731
- parser_iv_set(json, "@vsource", json->Vsource);
1724
+ json->len = RSTRING_LEN(source);
1725
+ json->source = RSTRING_PTR(source);;
1726
+ PARSER_SET_REFERENCE(json, Vsource, source);
1732
1727
  return self;
1733
1728
  }
1734
1729
 
1735
- /*
1736
- * call-seq: parse()
1737
- *
1738
- * Parses the current JSON text _source_ and returns the complete data
1739
- * structure as a result.
1740
- */
1741
- static VALUE cParser_parse(VALUE self)
1730
+
1731
+ #line 1729 "parser.c"
1732
+ static const int JSON_start = 1;
1733
+ static const int JSON_first_final = 10;
1734
+ static const int JSON_error = 0;
1735
+
1736
+ static const int JSON_en_main = 1;
1737
+
1738
+
1739
+ #line 736 "parser.rl"
1740
+
1741
+
1742
+ static VALUE cParser_parse_strict(VALUE self)
1742
1743
  {
1743
- const char *p, *pe;
1744
+ char *p, *pe;
1744
1745
  int cs = EVIL;
1745
1746
  VALUE result = Qnil;
1746
1747
  GET_PARSER;
@@ -1751,7 +1752,7 @@ static VALUE cParser_parse(VALUE self)
1751
1752
  cs = JSON_start;
1752
1753
  }
1753
1754
 
1754
- #line 745 "parser.rl"
1755
+ #line 746 "parser.rl"
1755
1756
  p = json->source;
1756
1757
  pe = p + json->len;
1757
1758
 
@@ -1811,18 +1812,18 @@ case 5:
1811
1812
  goto st1;
1812
1813
  goto st5;
1813
1814
  tr3:
1814
- #line 540 "parser.rl"
1815
+ #line 725 "parser.rl"
1815
1816
  {
1816
- const char *np;
1817
+ char *np;
1817
1818
  json->current_nesting = 1;
1818
1819
  np = JSON_parse_array(json, p, pe, &result);
1819
1820
  if (np == NULL) { p--; {p++; cs = 10; goto _out;} } else {p = (( np))-1;}
1820
1821
  }
1821
1822
  goto st10;
1822
1823
  tr4:
1823
- #line 533 "parser.rl"
1824
+ #line 718 "parser.rl"
1824
1825
  {
1825
- const char *np;
1826
+ char *np;
1826
1827
  json->current_nesting = 1;
1827
1828
  np = JSON_parse_object(json, p, pe, &result);
1828
1829
  if (np == NULL) { p--; {p++; cs = 10; goto _out;} } else {p = (( np))-1;}
@@ -1889,7 +1890,7 @@ case 9:
1889
1890
  _out: {}
1890
1891
  }
1891
1892
 
1892
- #line 748 "parser.rl"
1893
+ #line 749 "parser.rl"
1893
1894
 
1894
1895
  if (cs >= JSON_first_final && p == pe) {
1895
1896
  return result;
@@ -1899,6 +1900,197 @@ case 9:
1899
1900
  }
1900
1901
  }
1901
1902
 
1903
+
1904
+
1905
+ #line 1903 "parser.c"
1906
+ static const int JSON_quirks_mode_start = 1;
1907
+ static const int JSON_quirks_mode_first_final = 10;
1908
+ static const int JSON_quirks_mode_error = 0;
1909
+
1910
+ static const int JSON_quirks_mode_en_main = 1;
1911
+
1912
+
1913
+ #line 774 "parser.rl"
1914
+
1915
+
1916
+ static VALUE cParser_parse_quirks_mode(VALUE self)
1917
+ {
1918
+ char *p, *pe;
1919
+ int cs = EVIL;
1920
+ VALUE result = Qnil;
1921
+ GET_PARSER;
1922
+
1923
+
1924
+ #line 1922 "parser.c"
1925
+ {
1926
+ cs = JSON_quirks_mode_start;
1927
+ }
1928
+
1929
+ #line 784 "parser.rl"
1930
+ p = json->source;
1931
+ pe = p + json->len;
1932
+
1933
+ #line 1931 "parser.c"
1934
+ {
1935
+ if ( p == pe )
1936
+ goto _test_eof;
1937
+ switch ( cs )
1938
+ {
1939
+ st1:
1940
+ if ( ++p == pe )
1941
+ goto _test_eof1;
1942
+ case 1:
1943
+ switch( (*p) ) {
1944
+ case 13: goto st1;
1945
+ case 32: goto st1;
1946
+ case 34: goto tr2;
1947
+ case 45: goto tr2;
1948
+ case 47: goto st6;
1949
+ case 73: goto tr2;
1950
+ case 78: goto tr2;
1951
+ case 91: goto tr2;
1952
+ case 102: goto tr2;
1953
+ case 110: goto tr2;
1954
+ case 116: goto tr2;
1955
+ case 123: goto tr2;
1956
+ }
1957
+ if ( (*p) > 10 ) {
1958
+ if ( 48 <= (*p) && (*p) <= 57 )
1959
+ goto tr2;
1960
+ } else if ( (*p) >= 9 )
1961
+ goto st1;
1962
+ goto st0;
1963
+ st0:
1964
+ cs = 0;
1965
+ goto _out;
1966
+ tr2:
1967
+ #line 766 "parser.rl"
1968
+ {
1969
+ char *np = JSON_parse_value(json, p, pe, &result);
1970
+ if (np == NULL) { p--; {p++; cs = 10; goto _out;} } else {p = (( np))-1;}
1971
+ }
1972
+ goto st10;
1973
+ st10:
1974
+ if ( ++p == pe )
1975
+ goto _test_eof10;
1976
+ case 10:
1977
+ #line 1975 "parser.c"
1978
+ switch( (*p) ) {
1979
+ case 13: goto st10;
1980
+ case 32: goto st10;
1981
+ case 47: goto st2;
1982
+ }
1983
+ if ( 9 <= (*p) && (*p) <= 10 )
1984
+ goto st10;
1985
+ goto st0;
1986
+ st2:
1987
+ if ( ++p == pe )
1988
+ goto _test_eof2;
1989
+ case 2:
1990
+ switch( (*p) ) {
1991
+ case 42: goto st3;
1992
+ case 47: goto st5;
1993
+ }
1994
+ goto st0;
1995
+ st3:
1996
+ if ( ++p == pe )
1997
+ goto _test_eof3;
1998
+ case 3:
1999
+ if ( (*p) == 42 )
2000
+ goto st4;
2001
+ goto st3;
2002
+ st4:
2003
+ if ( ++p == pe )
2004
+ goto _test_eof4;
2005
+ case 4:
2006
+ switch( (*p) ) {
2007
+ case 42: goto st4;
2008
+ case 47: goto st10;
2009
+ }
2010
+ goto st3;
2011
+ st5:
2012
+ if ( ++p == pe )
2013
+ goto _test_eof5;
2014
+ case 5:
2015
+ if ( (*p) == 10 )
2016
+ goto st10;
2017
+ goto st5;
2018
+ st6:
2019
+ if ( ++p == pe )
2020
+ goto _test_eof6;
2021
+ case 6:
2022
+ switch( (*p) ) {
2023
+ case 42: goto st7;
2024
+ case 47: goto st9;
2025
+ }
2026
+ goto st0;
2027
+ st7:
2028
+ if ( ++p == pe )
2029
+ goto _test_eof7;
2030
+ case 7:
2031
+ if ( (*p) == 42 )
2032
+ goto st8;
2033
+ goto st7;
2034
+ st8:
2035
+ if ( ++p == pe )
2036
+ goto _test_eof8;
2037
+ case 8:
2038
+ switch( (*p) ) {
2039
+ case 42: goto st8;
2040
+ case 47: goto st1;
2041
+ }
2042
+ goto st7;
2043
+ st9:
2044
+ if ( ++p == pe )
2045
+ goto _test_eof9;
2046
+ case 9:
2047
+ if ( (*p) == 10 )
2048
+ goto st1;
2049
+ goto st9;
2050
+ }
2051
+ _test_eof1: cs = 1; goto _test_eof;
2052
+ _test_eof10: cs = 10; goto _test_eof;
2053
+ _test_eof2: cs = 2; goto _test_eof;
2054
+ _test_eof3: cs = 3; goto _test_eof;
2055
+ _test_eof4: cs = 4; goto _test_eof;
2056
+ _test_eof5: cs = 5; goto _test_eof;
2057
+ _test_eof6: cs = 6; goto _test_eof;
2058
+ _test_eof7: cs = 7; goto _test_eof;
2059
+ _test_eof8: cs = 8; goto _test_eof;
2060
+ _test_eof9: cs = 9; goto _test_eof;
2061
+
2062
+ _test_eof: {}
2063
+ _out: {}
2064
+ }
2065
+
2066
+ #line 787 "parser.rl"
2067
+
2068
+ if (cs >= JSON_quirks_mode_first_final && p == pe) {
2069
+ return result;
2070
+ } else {
2071
+ rb_raise(eParserError, "%u: unexpected token at '%s'", __LINE__, p);
2072
+ return Qnil;
2073
+ }
2074
+ }
2075
+
2076
+ /*
2077
+ * call-seq: parse()
2078
+ *
2079
+ * Parses the current JSON text _source_ and returns the complete data
2080
+ * structure as a result.
2081
+ */
2082
+ static VALUE cParser_parse(VALUE self)
2083
+ {
2084
+ GET_PARSER;
2085
+
2086
+ if (json->quirks_mode) {
2087
+ return cParser_parse_quirks_mode(self);
2088
+ } else {
2089
+ return cParser_parse_strict(self);
2090
+ }
2091
+ }
2092
+
2093
+
1902
2094
  static JSON_Parser *JSON_allocate()
1903
2095
  {
1904
2096
  JSON_Parser *json = ALLOC(JSON_Parser);
@@ -1913,7 +2105,14 @@ static JSON_Parser *JSON_allocate()
1913
2105
  return json;
1914
2106
  }
1915
2107
 
1916
- /* deleted JSON_mark function */
2108
+ static void JSON_mark(JSON_Parser *json)
2109
+ {
2110
+ rb_gc_mark_maybe(json->Vsource);
2111
+ rb_gc_mark_maybe(json->create_id);
2112
+ rb_gc_mark_maybe(json->object_class);
2113
+ rb_gc_mark_maybe(json->array_class);
2114
+ rb_gc_mark_maybe(json->match_string);
2115
+ }
1917
2116
 
1918
2117
  static void JSON_free(JSON_Parser *json)
1919
2118
  {
@@ -1923,9 +2122,7 @@ static void JSON_free(JSON_Parser *json)
1923
2122
  static VALUE cJSON_parser_s_allocate(VALUE klass)
1924
2123
  {
1925
2124
  JSON_Parser *json = JSON_allocate();
1926
- VALUE data_obj = Data_Wrap_Struct(klass, NULL, JSON_free, json);
1927
- json->dwrapped_parser = data_obj;
1928
- return data_obj;
2125
+ return json->dwrapped_parser = Data_Wrap_Struct(klass, JSON_mark, JSON_free, json);
1929
2126
  }
1930
2127
 
1931
2128
  /*
@@ -1940,6 +2137,18 @@ static VALUE cParser_source(VALUE self)
1940
2137
  return rb_str_dup(json->Vsource);
1941
2138
  }
1942
2139
 
2140
+ /*
2141
+ * call-seq: quirks_mode?()
2142
+ *
2143
+ * Returns a true, if this parser is in quirks_mode, false otherwise.
2144
+ */
2145
+ static VALUE cParser_quirks_mode_p(VALUE self)
2146
+ {
2147
+ GET_PARSER;
2148
+ return json->quirks_mode ? Qtrue : Qfalse;
2149
+ }
2150
+
2151
+
1943
2152
  void Init_parser()
1944
2153
  {
1945
2154
  rb_require("json/common");
@@ -1952,6 +2161,7 @@ void Init_parser()
1952
2161
  rb_define_method(cParser, "initialize", cParser_initialize, -1);
1953
2162
  rb_define_method(cParser, "parse", cParser_parse, 0);
1954
2163
  rb_define_method(cParser, "source", cParser_source, 0);
2164
+ rb_define_method(cParser, "quirks_mode?", cParser_quirks_mode_p, 0);
1955
2165
 
1956
2166
  CNaN = rb_const_get(mJSON, rb_intern("NaN"));
1957
2167
  CInfinity = rb_const_get(mJSON, rb_intern("Infinity"));
@@ -1965,6 +2175,7 @@ void Init_parser()
1965
2175
  i_max_nesting = rb_intern("max_nesting");
1966
2176
  i_allow_nan = rb_intern("allow_nan");
1967
2177
  i_symbolize_names = rb_intern("symbolize_names");
2178
+ i_quirks_mode = rb_intern("quirks_mode");
1968
2179
  i_object_class = rb_intern("object_class");
1969
2180
  i_array_class = rb_intern("array_class");
1970
2181
  i_match = rb_intern("match");