json-maglev- 1.5.4 → 1.6.1

Sign up to get free protection for your applications and to get access to all the features.
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");