json 1.5.3 → 1.5.4
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of json might be problematic. Click here for more details.
- data/CHANGES +8 -0
- data/Gemfile +3 -5
- data/Rakefile +34 -5
- data/VERSION +1 -1
- data/bin/prettify_json.rb +12 -39
- data/ext/json/ext/generator/generator.c +62 -22
- data/ext/json/ext/generator/generator.h +5 -2
- data/ext/json/ext/parser/parser.c +496 -285
- data/ext/json/ext/parser/parser.h +5 -1
- data/ext/json/ext/parser/parser.rl +155 -81
- data/java/src/json/ext/Generator.java +5 -5
- data/java/src/json/ext/GeneratorMethods.java +8 -7
- data/java/src/json/ext/GeneratorService.java +5 -4
- data/java/src/json/ext/GeneratorState.java +44 -16
- data/java/src/json/ext/OptionsReader.java +3 -3
- data/java/src/json/ext/Parser.java +399 -117
- data/java/src/json/ext/Parser.rl +118 -38
- data/java/src/json/ext/ParserService.java +4 -3
- data/java/src/json/ext/RuntimeInfo.java +23 -21
- data/java/src/json/ext/Utils.java +2 -2
- data/json.gemspec +17 -17
- data/json_pure.gemspec +22 -16
- data/lib/json.rb +7 -7
- data/lib/json/add/complex.rb +22 -0
- data/lib/json/add/core.rb +9 -9
- data/lib/json/add/rational.rb +22 -0
- data/lib/json/common.rb +50 -38
- data/lib/json/editor.rb +16 -16
- data/lib/json/ext.rb +2 -15
- data/lib/json/pure/generator.rb +18 -3
- data/lib/json/pure/parser.rb +92 -58
- data/lib/json/version.rb +1 -1
- data/tests/test_json.rb +52 -1
- data/tests/test_json_addition.rb +9 -2
- data/tests/test_json_generate.rb +34 -1
- data/tools/fuzz.rb +1 -1
- metadata +50 -52
- data/lib/json/add/rails.rb +0 -8
data/CHANGES
CHANGED
@@ -1,3 +1,11 @@
|
|
1
|
+
2011-08-31 (1.5.4)
|
2
|
+
* Fix memory leak when used from multiple JRuby. (Patch by
|
3
|
+
jfirebaugh@github).
|
4
|
+
* Apply patch by Eric Wong <nocode@yhbt.net> that fixes garbage collection problem
|
5
|
+
reported in https://github.com/flori/json/issues/46.
|
6
|
+
* Add :quirks_mode option to parser and generator.
|
7
|
+
* Add support for Rational and Complex number additions via json/add/complex
|
8
|
+
and json/add/rational requires.
|
1
9
|
2011-06-20 (1.5.3)
|
2
10
|
* Alias State#configure method as State#merge to increase duck type synonymy with Hash.
|
3
11
|
* Add as_json methods in json/add/core, so rails can create its json objects
|
data/Gemfile
CHANGED
data/Rakefile
CHANGED
@@ -4,7 +4,12 @@ rescue LoadError
|
|
4
4
|
end
|
5
5
|
|
6
6
|
require 'rbconfig'
|
7
|
-
|
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'
|
@@ -63,6 +68,7 @@ task :install_ext_really do
|
|
63
68
|
mkdir_p File.dirname(d)
|
64
69
|
install(file, d)
|
65
70
|
end
|
71
|
+
warn " *** Installed EXT ruby library."
|
66
72
|
end
|
67
73
|
end
|
68
74
|
|
@@ -89,6 +95,8 @@ if defined?(Gem) and defined?(Gem::PackageTask)
|
|
89
95
|
s.add_development_dependency 'permutation'
|
90
96
|
s.add_development_dependency 'bullshit'
|
91
97
|
s.add_development_dependency 'sdoc'
|
98
|
+
s.add_development_dependency 'rake', '~>0.9.2'
|
99
|
+
s.add_dependency 'spruz', '~>0.2.8'
|
92
100
|
|
93
101
|
s.bindir = "bin"
|
94
102
|
s.executables = [ "edit_json.rb", "prettify_json.rb" ]
|
@@ -191,7 +199,22 @@ end
|
|
191
199
|
desc "Testing library (pure ruby and extension)"
|
192
200
|
task :test => [ :test_pure, :test_ext ]
|
193
201
|
|
202
|
+
namespace :gems do
|
203
|
+
task :install do
|
204
|
+
sh 'bundle'
|
205
|
+
end
|
206
|
+
end
|
207
|
+
|
194
208
|
if defined?(RUBY_ENGINE) and RUBY_ENGINE == 'jruby'
|
209
|
+
if ENV.key?('JAVA_HOME')
|
210
|
+
warn " *** JAVA_HOME was set to #{ENV['JAVA_HOME'].inspect}"
|
211
|
+
else File.directory?(local_java = '/usr/local/java/jdk')
|
212
|
+
ENV['JAVA_HOME'] = local_java
|
213
|
+
warn " *** JAVA_HOME is set to #{ENV['JAVA_HOME'].inspect}"
|
214
|
+
ENV['PATH'] = ENV['PATH'].split(/:/).unshift(java_path = "#{ENV['JAVA_HOME']}/bin") * ':'
|
215
|
+
warn " *** java binaries are assumed to be in #{java_path.inspect}"
|
216
|
+
end
|
217
|
+
|
195
218
|
file JAVA_PARSER_SRC => JAVA_RAGEL_PATH do
|
196
219
|
cd JAVA_DIR do
|
197
220
|
if RAGEL_CODEGEN == 'ragel'
|
@@ -210,7 +233,7 @@ if defined?(RUBY_ENGINE) and RUBY_ENGINE == 'jruby'
|
|
210
233
|
rm_rf JAVA_PARSER_SRC
|
211
234
|
end
|
212
235
|
|
213
|
-
JRUBY_JAR = File.join(
|
236
|
+
JRUBY_JAR = File.join(CONFIG["libdir"], "jruby.jar")
|
214
237
|
if File.exist?(JRUBY_JAR)
|
215
238
|
JAVA_SOURCES.each do |src|
|
216
239
|
classpath = (Dir['java/lib/*.jar'] << 'java/src' << JRUBY_JAR) * ':'
|
@@ -280,7 +303,9 @@ if defined?(RUBY_ENGINE) and RUBY_ENGINE == 'jruby'
|
|
280
303
|
task :create_jar => [ :create_parser_jar, :create_generator_jar ]
|
281
304
|
|
282
305
|
desc "Build all gems and archives for a new release of the jruby extension."
|
283
|
-
task :
|
306
|
+
task :build => [ :clean, :version, :jruby_gem ]
|
307
|
+
|
308
|
+
task :release => :build
|
284
309
|
else
|
285
310
|
desc "Compiling extension"
|
286
311
|
task :compile => [ EXT_PARSER_DL, EXT_GENERATOR_DL ]
|
@@ -345,6 +370,8 @@ else
|
|
345
370
|
else
|
346
371
|
sh "ragel -x parser.rl | #{RAGEL_CODEGEN} -G2"
|
347
372
|
end
|
373
|
+
src = File.read("parser.c").gsub(/[ \t]+$/, '')
|
374
|
+
File.open("parser.c", "w") {|f| f.print src}
|
348
375
|
end
|
349
376
|
end
|
350
377
|
|
@@ -380,8 +407,10 @@ else
|
|
380
407
|
task :ragel_dot => [ :ragel_dot_png, :ragel_dot_ps ]
|
381
408
|
|
382
409
|
desc "Build all gems and archives for a new release of json and json_pure."
|
383
|
-
task :
|
410
|
+
task :build => [ :clean, :gemspec, :package ]
|
411
|
+
|
412
|
+
task :release => :build
|
384
413
|
end
|
385
414
|
|
386
415
|
desc "Compile in the the source directory"
|
387
|
-
task :default => [ :clean, :gemspec, :
|
416
|
+
task :default => [ :clean, :gemspec, :test ]
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
1.5.
|
1
|
+
1.5.4
|
data/bin/prettify_json.rb
CHANGED
@@ -3,37 +3,8 @@
|
|
3
3
|
require 'json'
|
4
4
|
require 'fileutils'
|
5
5
|
include FileUtils
|
6
|
-
|
7
|
-
|
8
|
-
# retrieve the single character command line options from it. If _s_ is
|
9
|
-
# 'xy:' an option '-x' without an option argument is searched, and an
|
10
|
-
# option '-y foo' with an option argument ('foo').
|
11
|
-
#
|
12
|
-
# An option hash is returned with all found options set to true or the
|
13
|
-
# found option argument.
|
14
|
-
def go(s, args = ARGV)
|
15
|
-
b, v = s.scan(/(.)(:?)/).inject([{},{}]) { |t,(o,a)|
|
16
|
-
t[a.empty? ? 0 : 1][o] = a.empty? ? false : nil
|
17
|
-
t
|
18
|
-
}
|
19
|
-
while a = args.shift
|
20
|
-
a !~ /\A-(.+)/ and args.unshift a and break
|
21
|
-
p = $1
|
22
|
-
until p == ''
|
23
|
-
o = p.slice!(0, 1)
|
24
|
-
if v.key?(o)
|
25
|
-
v[o] = if p == '' then args.shift or break 1 else p end
|
26
|
-
break
|
27
|
-
elsif b.key?(o)
|
28
|
-
b[o] = true
|
29
|
-
else
|
30
|
-
args.unshift a
|
31
|
-
break 1
|
32
|
-
end
|
33
|
-
end and break
|
34
|
-
end
|
35
|
-
b.merge(v)
|
36
|
-
end
|
6
|
+
require 'spruz/go'
|
7
|
+
include Spruz::GO
|
37
8
|
|
38
9
|
opts = go 'slhi:', args = ARGV.dup
|
39
10
|
if opts['h'] || opts['l'] && opts['s']
|
@@ -52,19 +23,21 @@ EOT
|
|
52
23
|
exit 0
|
53
24
|
end
|
54
25
|
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
26
|
+
json_opts = { :max_nesting => false, :create_additions => false }
|
27
|
+
|
28
|
+
document =
|
29
|
+
if filename = args.first or filename == '-'
|
30
|
+
File.read(filename)
|
59
31
|
else
|
60
|
-
|
32
|
+
STDIN.read
|
61
33
|
end
|
62
|
-
|
34
|
+
|
35
|
+
json = JSON.parse document, json_opts
|
63
36
|
|
64
37
|
output = if opts['s']
|
65
|
-
JSON.fast_generate json
|
38
|
+
JSON.fast_generate json, json_opts
|
66
39
|
else # default is -l
|
67
|
-
JSON.pretty_generate json
|
40
|
+
JSON.pretty_generate json, json_opts
|
68
41
|
end
|
69
42
|
|
70
43
|
if opts['i'] && filename
|
@@ -13,14 +13,14 @@ 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,
|
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.
|
21
|
-
*
|
21
|
+
*
|
22
22
|
* Disclaimer
|
23
|
-
*
|
23
|
+
*
|
24
24
|
* This source code is provided as is by Unicode, Inc. No claims are
|
25
25
|
* made as to fitness for any particular purpose. No warranties of any
|
26
26
|
* kind are expressed or implied. The recipient agrees to determine
|
@@ -28,9 +28,9 @@ static ID i_to_s, i_to_json, i_new, i_indent, i_space, i_space_before,
|
|
28
28
|
* purchased on magnetic or optical media from Unicode, Inc., the
|
29
29
|
* sole remedy for any claim will be exchange of defective media
|
30
30
|
* within 90 days of receipt.
|
31
|
-
*
|
31
|
+
*
|
32
32
|
* Limitations on Rights to Redistribute This Code
|
33
|
-
*
|
33
|
+
*
|
34
34
|
* Unicode, Inc. hereby grants the right to freely use the information
|
35
35
|
* supplied in this file in the creation of products supporting the
|
36
36
|
* Unicode Standard, and to make copies of this file in any form
|
@@ -61,7 +61,7 @@ static const char trailingBytesForUTF8[256] = {
|
|
61
61
|
* This table contains as many values as there might be trailing bytes
|
62
62
|
* in a UTF-8 sequence.
|
63
63
|
*/
|
64
|
-
static const UTF32 offsetsFromUTF8[6] = { 0x00000000UL, 0x00003080UL, 0x000E2080UL,
|
64
|
+
static const UTF32 offsetsFromUTF8[6] = { 0x00000000UL, 0x00003080UL, 0x000E2080UL,
|
65
65
|
0x03C82080UL, 0xFA082080UL, 0x82082080UL };
|
66
66
|
|
67
67
|
/*
|
@@ -318,11 +318,6 @@ static void fbuffer_free(FBuffer *fb)
|
|
318
318
|
ruby_xfree(fb);
|
319
319
|
}
|
320
320
|
|
321
|
-
static void fbuffer_free_only_buffer(FBuffer *fb)
|
322
|
-
{
|
323
|
-
ruby_xfree(fb);
|
324
|
-
}
|
325
|
-
|
326
321
|
static void fbuffer_clear(FBuffer *fb)
|
327
322
|
{
|
328
323
|
fb->len = 0;
|
@@ -354,6 +349,16 @@ static void fbuffer_append(FBuffer *fb, const char *newstr, unsigned long len)
|
|
354
349
|
}
|
355
350
|
}
|
356
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
|
+
|
357
362
|
static void fbuffer_append_char(FBuffer *fb, char newchr)
|
358
363
|
{
|
359
364
|
fbuffer_inc_capa(fb, 1);
|
@@ -404,7 +409,7 @@ static FBuffer *fbuffer_dup(FBuffer *fb)
|
|
404
409
|
return result;
|
405
410
|
}
|
406
411
|
|
407
|
-
/*
|
412
|
+
/*
|
408
413
|
* Document-module: JSON::Ext::Generator
|
409
414
|
*
|
410
415
|
* This is the JSON generator implemented as a C extension. It can be
|
@@ -693,6 +698,8 @@ static VALUE cState_configure(VALUE self, VALUE opts)
|
|
693
698
|
state->allow_nan = RTEST(tmp);
|
694
699
|
tmp = rb_hash_aref(opts, ID2SYM(i_ascii_only));
|
695
700
|
state->ascii_only = RTEST(tmp);
|
701
|
+
tmp = rb_hash_aref(opts, ID2SYM(i_quirks_mode));
|
702
|
+
state->quirks_mode = RTEST(tmp);
|
696
703
|
return self;
|
697
704
|
}
|
698
705
|
|
@@ -713,6 +720,7 @@ static VALUE cState_to_h(VALUE self)
|
|
713
720
|
rb_hash_aset(result, ID2SYM(i_array_nl), rb_str_new(state->array_nl, state->array_nl_len));
|
714
721
|
rb_hash_aset(result, ID2SYM(i_allow_nan), state->allow_nan ? Qtrue : Qfalse);
|
715
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);
|
716
724
|
rb_hash_aset(result, ID2SYM(i_max_nesting), LONG2FIX(state->max_nesting));
|
717
725
|
rb_hash_aset(result, ID2SYM(i_depth), LONG2FIX(state->depth));
|
718
726
|
return result;
|
@@ -857,7 +865,7 @@ static void generate_json_fixnum(FBuffer *buffer, VALUE Vstate, JSON_Generator_S
|
|
857
865
|
static void generate_json_bignum(FBuffer *buffer, VALUE Vstate, JSON_Generator_State *state, VALUE obj)
|
858
866
|
{
|
859
867
|
VALUE tmp = rb_funcall(obj, i_to_s, 0);
|
860
|
-
|
868
|
+
fbuffer_append_str(buffer, tmp);
|
861
869
|
}
|
862
870
|
|
863
871
|
static void generate_json_float(FBuffer *buffer, VALUE Vstate, JSON_Generator_State *state, VALUE obj)
|
@@ -874,7 +882,7 @@ static void generate_json_float(FBuffer *buffer, VALUE Vstate, JSON_Generator_St
|
|
874
882
|
rb_raise(eGeneratorError, "%u: %s not allowed in JSON", __LINE__, StringValueCStr(tmp));
|
875
883
|
}
|
876
884
|
}
|
877
|
-
|
885
|
+
fbuffer_append_str(buffer, tmp);
|
878
886
|
}
|
879
887
|
|
880
888
|
static void generate_json(FBuffer *buffer, VALUE Vstate, JSON_Generator_State *state, VALUE obj)
|
@@ -902,7 +910,7 @@ static void generate_json(FBuffer *buffer, VALUE Vstate, JSON_Generator_State *s
|
|
902
910
|
} else if (rb_respond_to(obj, i_to_json)) {
|
903
911
|
tmp = rb_funcall(obj, i_to_json, 1, Vstate);
|
904
912
|
Check_Type(tmp, T_STRING);
|
905
|
-
|
913
|
+
fbuffer_append_str(buffer, tmp);
|
906
914
|
} else {
|
907
915
|
tmp = rb_funcall(obj, i_to_s, 0);
|
908
916
|
Check_Type(tmp, T_STRING);
|
@@ -966,11 +974,14 @@ static VALUE cState_generate(VALUE self, VALUE obj)
|
|
966
974
|
{
|
967
975
|
VALUE result = cState_partial_generate(self, obj);
|
968
976
|
VALUE re, args[2];
|
969
|
-
|
970
|
-
|
971
|
-
|
972
|
-
|
973
|
-
|
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
|
+
}
|
974
985
|
}
|
975
986
|
return result;
|
976
987
|
}
|
@@ -985,11 +996,13 @@ static VALUE cState_generate(VALUE self, VALUE obj)
|
|
985
996
|
* * *indent*: a string used to indent levels (default: ''),
|
986
997
|
* * *space*: a string that is put after, a : or , delimiter (default: ''),
|
987
998
|
* * *space_before*: a string that is put before a : pair delimiter (default: ''),
|
988
|
-
* * *object_nl*: a string that is put at the end of a JSON object (default: ''),
|
999
|
+
* * *object_nl*: a string that is put at the end of a JSON object (default: ''),
|
989
1000
|
* * *array_nl*: a string that is put at the end of a JSON array (default: ''),
|
990
1001
|
* * *allow_nan*: true if NaN, Infinity, and -Infinity should be
|
991
1002
|
* generated, otherwise an exception is thrown, if these values are
|
992
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.
|
993
1006
|
*/
|
994
1007
|
static VALUE cState_initialize(int argc, VALUE *argv, VALUE self)
|
995
1008
|
{
|
@@ -1292,6 +1305,29 @@ static VALUE cState_ascii_only_p(VALUE self)
|
|
1292
1305
|
return state->ascii_only ? Qtrue : Qfalse;
|
1293
1306
|
}
|
1294
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
|
+
|
1295
1331
|
/*
|
1296
1332
|
* call-seq: depth
|
1297
1333
|
*
|
@@ -1350,6 +1386,9 @@ void Init_generator()
|
|
1350
1386
|
rb_define_method(cState, "check_circular?", cState_check_circular_p, 0);
|
1351
1387
|
rb_define_method(cState, "allow_nan?", cState_allow_nan_p, 0);
|
1352
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);
|
1353
1392
|
rb_define_method(cState, "depth", cState_depth, 0);
|
1354
1393
|
rb_define_method(cState, "depth=", cState_depth_set, 1);
|
1355
1394
|
rb_define_method(cState, "configure", cState_configure, 1);
|
@@ -1397,6 +1436,7 @@ void Init_generator()
|
|
1397
1436
|
i_max_nesting = rb_intern("max_nesting");
|
1398
1437
|
i_allow_nan = rb_intern("allow_nan");
|
1399
1438
|
i_ascii_only = rb_intern("ascii_only");
|
1439
|
+
i_quirks_mode = rb_intern("quirks_mode");
|
1400
1440
|
i_depth = rb_intern("depth");
|
1401
1441
|
i_pack = rb_intern("pack");
|
1402
1442
|
i_unpack = rb_intern("unpack");
|
@@ -45,7 +45,10 @@
|
|
45
45
|
#define RSTRING_LEN(string) RSTRING(string)->len
|
46
46
|
#endif
|
47
47
|
|
48
|
-
|
48
|
+
/* We don't need to guard objects for rbx, so let's do nothing at all. */
|
49
|
+
#ifndef RB_GC_GUARD
|
50
|
+
#define RB_GC_GUARD(object)
|
51
|
+
#endif
|
49
52
|
|
50
53
|
/* fbuffer implementation */
|
51
54
|
|
@@ -67,7 +70,6 @@ static char *fstrndup(const char *ptr, unsigned long len);
|
|
67
70
|
static FBuffer *fbuffer_alloc();
|
68
71
|
static FBuffer *fbuffer_alloc_with_length(unsigned long initial_length);
|
69
72
|
static void fbuffer_free(FBuffer *fb);
|
70
|
-
static void fbuffer_free_only_buffer(FBuffer *fb);
|
71
73
|
static void fbuffer_clear(FBuffer *fb);
|
72
74
|
static void fbuffer_append(FBuffer *fb, const char *newstr, unsigned long len);
|
73
75
|
static void fbuffer_append_long(FBuffer *fb, long number);
|
@@ -124,6 +126,7 @@ typedef struct JSON_Generator_StateStruct {
|
|
124
126
|
long max_nesting;
|
125
127
|
char allow_nan;
|
126
128
|
char ascii_only;
|
129
|
+
char quirks_mode;
|
127
130
|
long depth;
|
128
131
|
} JSON_Generator_State;
|
129
132
|
|
@@ -4,7 +4,7 @@
|
|
4
4
|
|
5
5
|
/* unicode */
|
6
6
|
|
7
|
-
static const char digit_values[256] = {
|
7
|
+
static const char digit_values[256] = {
|
8
8
|
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
9
9
|
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
10
10
|
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -1,
|
@@ -40,7 +40,7 @@ static UTF32 unescape_unicode(const unsigned char *p)
|
|
40
40
|
return result;
|
41
41
|
}
|
42
42
|
|
43
|
-
static int convert_UTF32_to_UTF8(char *buf, UTF32 ch)
|
43
|
+
static int convert_UTF32_to_UTF8(char *buf, UTF32 ch)
|
44
44
|
{
|
45
45
|
int len = 1;
|
46
46
|
if (ch <= 0x7F) {
|
@@ -69,7 +69,7 @@ static int convert_UTF32_to_UTF8(char *buf, UTF32 ch)
|
|
69
69
|
#ifdef HAVE_RUBY_ENCODING_H
|
70
70
|
static VALUE CEncoding_ASCII_8BIT, CEncoding_UTF_8, CEncoding_UTF_16BE,
|
71
71
|
CEncoding_UTF_16LE, CEncoding_UTF_32BE, CEncoding_UTF_32LE;
|
72
|
-
static ID i_encoding, i_encode
|
72
|
+
static ID i_encoding, i_encode;
|
73
73
|
#else
|
74
74
|
static ID i_iconv;
|
75
75
|
#endif
|
@@ -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,
|
82
|
-
i_array_class, i_key_p, i_deep_const_get, i_match,
|
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
|
86
|
+
#line 109 "parser.rl"
|
86
87
|
|
87
88
|
|
88
89
|
|
89
|
-
#line
|
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,7 +95,7 @@ static const int JSON_object_error = 0;
|
|
94
95
|
static const int JSON_object_en_main = 1;
|
95
96
|
|
96
97
|
|
97
|
-
#line
|
98
|
+
#line 150 "parser.rl"
|
98
99
|
|
99
100
|
|
100
101
|
static char *JSON_parse_object(JSON_Parser *json, char *p, char *pe, VALUE *result)
|
@@ -109,15 +110,15 @@ static char *JSON_parse_object(JSON_Parser *json, char *p, char *pe, VALUE *resu
|
|
109
110
|
|
110
111
|
*result = NIL_P(object_class) ? rb_hash_new() : rb_class_new_instance(0, 0, object_class);
|
111
112
|
|
112
|
-
|
113
|
-
#line
|
113
|
+
|
114
|
+
#line 115 "parser.c"
|
114
115
|
{
|
115
116
|
cs = JSON_object_start;
|
116
117
|
}
|
117
118
|
|
118
|
-
#line
|
119
|
-
|
120
|
-
#line
|
119
|
+
#line 165 "parser.rl"
|
120
|
+
|
121
|
+
#line 122 "parser.c"
|
121
122
|
{
|
122
123
|
if ( p == pe )
|
123
124
|
goto _test_eof;
|
@@ -145,7 +146,7 @@ case 2:
|
|
145
146
|
goto st2;
|
146
147
|
goto st0;
|
147
148
|
tr2:
|
148
|
-
#line
|
149
|
+
#line 132 "parser.rl"
|
149
150
|
{
|
150
151
|
char *np;
|
151
152
|
json->parsing_name = 1;
|
@@ -158,7 +159,7 @@ st3:
|
|
158
159
|
if ( ++p == pe )
|
159
160
|
goto _test_eof3;
|
160
161
|
case 3:
|
161
|
-
#line
|
162
|
+
#line 163 "parser.c"
|
162
163
|
switch( (*p) ) {
|
163
164
|
case 13: goto st3;
|
164
165
|
case 32: goto st3;
|
@@ -225,17 +226,17 @@ case 8:
|
|
225
226
|
goto st8;
|
226
227
|
goto st0;
|
227
228
|
tr11:
|
228
|
-
#line
|
229
|
+
#line 117 "parser.rl"
|
229
230
|
{
|
230
231
|
VALUE v = Qnil;
|
231
|
-
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 {
|
235
236
|
if (NIL_P(json->object_class)) {
|
236
|
-
|
237
|
+
rb_hash_aset(*result, last_name, v);
|
237
238
|
} else {
|
238
|
-
|
239
|
+
rb_funcall(*result, i_aset, 2, last_name, v);
|
239
240
|
}
|
240
241
|
{p = (( np))-1;}
|
241
242
|
}
|
@@ -245,7 +246,7 @@ st9:
|
|
245
246
|
if ( ++p == pe )
|
246
247
|
goto _test_eof9;
|
247
248
|
case 9:
|
248
|
-
#line
|
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
|
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
|
+
#line 346 "parser.c"
|
345
346
|
goto st0;
|
346
347
|
st19:
|
347
348
|
if ( ++p == pe )
|
@@ -408,38 +409,38 @@ case 26:
|
|
408
409
|
goto st2;
|
409
410
|
goto st26;
|
410
411
|
}
|
411
|
-
_test_eof2: cs = 2; goto _test_eof;
|
412
|
-
_test_eof3: cs = 3; goto _test_eof;
|
413
|
-
_test_eof4: cs = 4; goto _test_eof;
|
414
|
-
_test_eof5: cs = 5; goto _test_eof;
|
415
|
-
_test_eof6: cs = 6; goto _test_eof;
|
416
|
-
_test_eof7: cs = 7; goto _test_eof;
|
417
|
-
_test_eof8: cs = 8; goto _test_eof;
|
418
|
-
_test_eof9: cs = 9; goto _test_eof;
|
419
|
-
_test_eof10: cs = 10; goto _test_eof;
|
420
|
-
_test_eof11: cs = 11; goto _test_eof;
|
421
|
-
_test_eof12: cs = 12; goto _test_eof;
|
422
|
-
_test_eof13: cs = 13; goto _test_eof;
|
423
|
-
_test_eof14: cs = 14; goto _test_eof;
|
424
|
-
_test_eof15: cs = 15; goto _test_eof;
|
425
|
-
_test_eof16: cs = 16; goto _test_eof;
|
426
|
-
_test_eof17: cs = 17; goto _test_eof;
|
427
|
-
_test_eof18: cs = 18; goto _test_eof;
|
428
|
-
_test_eof27: cs = 27; goto _test_eof;
|
429
|
-
_test_eof19: cs = 19; goto _test_eof;
|
430
|
-
_test_eof20: cs = 20; goto _test_eof;
|
431
|
-
_test_eof21: cs = 21; goto _test_eof;
|
432
|
-
_test_eof22: cs = 22; goto _test_eof;
|
433
|
-
_test_eof23: cs = 23; goto _test_eof;
|
434
|
-
_test_eof24: cs = 24; goto _test_eof;
|
435
|
-
_test_eof25: cs = 25; goto _test_eof;
|
436
|
-
_test_eof26: cs = 26; goto _test_eof;
|
412
|
+
_test_eof2: cs = 2; goto _test_eof;
|
413
|
+
_test_eof3: cs = 3; goto _test_eof;
|
414
|
+
_test_eof4: cs = 4; goto _test_eof;
|
415
|
+
_test_eof5: cs = 5; goto _test_eof;
|
416
|
+
_test_eof6: cs = 6; goto _test_eof;
|
417
|
+
_test_eof7: cs = 7; goto _test_eof;
|
418
|
+
_test_eof8: cs = 8; goto _test_eof;
|
419
|
+
_test_eof9: cs = 9; goto _test_eof;
|
420
|
+
_test_eof10: cs = 10; goto _test_eof;
|
421
|
+
_test_eof11: cs = 11; goto _test_eof;
|
422
|
+
_test_eof12: cs = 12; goto _test_eof;
|
423
|
+
_test_eof13: cs = 13; goto _test_eof;
|
424
|
+
_test_eof14: cs = 14; goto _test_eof;
|
425
|
+
_test_eof15: cs = 15; goto _test_eof;
|
426
|
+
_test_eof16: cs = 16; goto _test_eof;
|
427
|
+
_test_eof17: cs = 17; goto _test_eof;
|
428
|
+
_test_eof18: cs = 18; goto _test_eof;
|
429
|
+
_test_eof27: cs = 27; goto _test_eof;
|
430
|
+
_test_eof19: cs = 19; goto _test_eof;
|
431
|
+
_test_eof20: cs = 20; goto _test_eof;
|
432
|
+
_test_eof21: cs = 21; goto _test_eof;
|
433
|
+
_test_eof22: cs = 22; goto _test_eof;
|
434
|
+
_test_eof23: cs = 23; goto _test_eof;
|
435
|
+
_test_eof24: cs = 24; goto _test_eof;
|
436
|
+
_test_eof25: cs = 25; goto _test_eof;
|
437
|
+
_test_eof26: cs = 26; goto _test_eof;
|
437
438
|
|
438
439
|
_test_eof: {}
|
439
440
|
_out: {}
|
440
441
|
}
|
441
442
|
|
442
|
-
#line
|
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
|
-
|
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
|
471
|
+
#line 265 "parser.rl"
|
470
472
|
|
471
473
|
|
472
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
|
-
|
477
|
-
#line
|
478
|
+
|
479
|
+
#line 480 "parser.c"
|
478
480
|
{
|
479
481
|
cs = JSON_value_start;
|
480
482
|
}
|
481
483
|
|
482
|
-
#line
|
483
|
-
|
484
|
-
#line
|
484
|
+
#line 272 "parser.rl"
|
485
|
+
|
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
|
511
|
+
#line 213 "parser.rl"
|
510
512
|
{
|
511
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
|
518
|
+
#line 218 "parser.rl"
|
517
519
|
{
|
518
520
|
char *np;
|
519
|
-
if(pe > p + 9 && !strncmp(MinusInfinity, p, 9)) {
|
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,8 +535,8 @@ tr2:
|
|
533
535
|
}
|
534
536
|
goto st21;
|
535
537
|
tr5:
|
536
|
-
#line
|
537
|
-
{
|
538
|
+
#line 236 "parser.rl"
|
539
|
+
{
|
538
540
|
char *np;
|
539
541
|
json->current_nesting++;
|
540
542
|
np = JSON_parse_array(json, p, pe, result);
|
@@ -543,8 +545,8 @@ tr5:
|
|
543
545
|
}
|
544
546
|
goto st21;
|
545
547
|
tr9:
|
546
|
-
#line
|
547
|
-
{
|
548
|
+
#line 244 "parser.rl"
|
549
|
+
{
|
548
550
|
char *np;
|
549
551
|
json->current_nesting++;
|
550
552
|
np = JSON_parse_object(json, p, pe, result);
|
@@ -553,7 +555,7 @@ tr9:
|
|
553
555
|
}
|
554
556
|
goto st21;
|
555
557
|
tr16:
|
556
|
-
#line
|
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
|
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
|
578
|
+
#line 193 "parser.rl"
|
577
579
|
{
|
578
580
|
*result = Qfalse;
|
579
581
|
}
|
580
582
|
goto st21;
|
581
583
|
tr25:
|
582
|
-
#line
|
584
|
+
#line 190 "parser.rl"
|
583
585
|
{
|
584
586
|
*result = Qnil;
|
585
587
|
}
|
586
588
|
goto st21;
|
587
589
|
tr28:
|
588
|
-
#line
|
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
|
599
|
+
#line 252 "parser.rl"
|
598
600
|
{ p--; {p++; cs = 21; goto _out;} }
|
599
|
-
#line
|
601
|
+
#line 602 "parser.c"
|
600
602
|
goto st0;
|
601
603
|
st2:
|
602
604
|
if ( ++p == pe )
|
@@ -732,32 +734,32 @@ case 20:
|
|
732
734
|
goto tr28;
|
733
735
|
goto st0;
|
734
736
|
}
|
735
|
-
_test_eof21: cs = 21; goto _test_eof;
|
736
|
-
_test_eof2: cs = 2; goto _test_eof;
|
737
|
-
_test_eof3: cs = 3; goto _test_eof;
|
738
|
-
_test_eof4: cs = 4; goto _test_eof;
|
739
|
-
_test_eof5: cs = 5; goto _test_eof;
|
740
|
-
_test_eof6: cs = 6; goto _test_eof;
|
741
|
-
_test_eof7: cs = 7; goto _test_eof;
|
742
|
-
_test_eof8: cs = 8; goto _test_eof;
|
743
|
-
_test_eof9: cs = 9; goto _test_eof;
|
744
|
-
_test_eof10: cs = 10; goto _test_eof;
|
745
|
-
_test_eof11: cs = 11; goto _test_eof;
|
746
|
-
_test_eof12: cs = 12; goto _test_eof;
|
747
|
-
_test_eof13: cs = 13; goto _test_eof;
|
748
|
-
_test_eof14: cs = 14; goto _test_eof;
|
749
|
-
_test_eof15: cs = 15; goto _test_eof;
|
750
|
-
_test_eof16: cs = 16; goto _test_eof;
|
751
|
-
_test_eof17: cs = 17; goto _test_eof;
|
752
|
-
_test_eof18: cs = 18; goto _test_eof;
|
753
|
-
_test_eof19: cs = 19; goto _test_eof;
|
754
|
-
_test_eof20: cs = 20; goto _test_eof;
|
737
|
+
_test_eof21: cs = 21; goto _test_eof;
|
738
|
+
_test_eof2: cs = 2; goto _test_eof;
|
739
|
+
_test_eof3: cs = 3; goto _test_eof;
|
740
|
+
_test_eof4: cs = 4; goto _test_eof;
|
741
|
+
_test_eof5: cs = 5; goto _test_eof;
|
742
|
+
_test_eof6: cs = 6; goto _test_eof;
|
743
|
+
_test_eof7: cs = 7; goto _test_eof;
|
744
|
+
_test_eof8: cs = 8; goto _test_eof;
|
745
|
+
_test_eof9: cs = 9; goto _test_eof;
|
746
|
+
_test_eof10: cs = 10; goto _test_eof;
|
747
|
+
_test_eof11: cs = 11; goto _test_eof;
|
748
|
+
_test_eof12: cs = 12; goto _test_eof;
|
749
|
+
_test_eof13: cs = 13; goto _test_eof;
|
750
|
+
_test_eof14: cs = 14; goto _test_eof;
|
751
|
+
_test_eof15: cs = 15; goto _test_eof;
|
752
|
+
_test_eof16: cs = 16; goto _test_eof;
|
753
|
+
_test_eof17: cs = 17; goto _test_eof;
|
754
|
+
_test_eof18: cs = 18; goto _test_eof;
|
755
|
+
_test_eof19: cs = 19; goto _test_eof;
|
756
|
+
_test_eof20: cs = 20; goto _test_eof;
|
755
757
|
|
756
758
|
_test_eof: {}
|
757
759
|
_out: {}
|
758
760
|
}
|
759
761
|
|
760
|
-
#line
|
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
|
772
|
+
#line 773 "parser.c"
|
771
773
|
static const int JSON_integer_start = 1;
|
772
|
-
static const int JSON_integer_first_final =
|
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
|
780
|
+
#line 289 "parser.rl"
|
779
781
|
|
780
782
|
|
781
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
|
-
|
786
|
-
#line
|
787
|
+
|
788
|
+
#line 789 "parser.c"
|
787
789
|
{
|
788
790
|
cs = JSON_integer_start;
|
789
791
|
}
|
790
792
|
|
791
|
-
#line
|
793
|
+
#line 296 "parser.rl"
|
792
794
|
json->memo = p;
|
793
|
-
|
794
|
-
#line
|
795
|
+
|
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
|
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
|
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
|
829
|
-
{ p--; {p++; cs =
|
830
|
-
goto
|
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
|
844
|
+
goto st5;
|
843
845
|
goto tr4;
|
844
846
|
}
|
845
|
-
_test_eof2: cs = 2; goto _test_eof;
|
846
|
-
_test_eof3: cs = 3; goto _test_eof;
|
847
|
-
|
848
|
-
|
847
|
+
_test_eof2: cs = 2; goto _test_eof;
|
848
|
+
_test_eof3: cs = 3; goto _test_eof;
|
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
|
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
|
868
|
+
#line 869 "parser.c"
|
867
869
|
static const int JSON_float_start = 1;
|
868
|
-
static const int JSON_float_first_final =
|
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
|
876
|
+
#line 320 "parser.rl"
|
875
877
|
|
876
878
|
|
877
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
|
-
|
882
|
-
#line
|
883
|
+
|
884
|
+
#line 885 "parser.c"
|
883
885
|
{
|
884
886
|
cs = JSON_float_start;
|
885
887
|
}
|
886
888
|
|
887
|
-
#line
|
889
|
+
#line 327 "parser.rl"
|
888
890
|
json->memo = p;
|
889
|
-
|
890
|
-
#line
|
891
|
+
|
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
|
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
|
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
|
923
|
-
case 101: goto
|
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
|
933
|
+
goto st8;
|
932
934
|
goto st0;
|
933
|
-
|
935
|
+
st8:
|
934
936
|
if ( ++p == pe )
|
935
|
-
goto
|
936
|
-
case
|
937
|
+
goto _test_eof8;
|
938
|
+
case 8:
|
937
939
|
switch( (*p) ) {
|
938
|
-
case 69: goto
|
939
|
-
case 101: goto
|
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
|
945
|
+
goto st8;
|
944
946
|
} else if ( (*p) >= 45 )
|
945
947
|
goto st0;
|
946
|
-
goto
|
947
|
-
|
948
|
-
#line
|
949
|
-
{ p--; {p++; cs =
|
950
|
-
goto
|
951
|
-
|
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
|
954
|
-
case
|
955
|
-
#line
|
955
|
+
goto _test_eof9;
|
956
|
+
case 9:
|
957
|
+
#line 958 "parser.c"
|
956
958
|
goto st0;
|
957
|
-
|
959
|
+
st5:
|
958
960
|
if ( ++p == pe )
|
959
|
-
goto
|
960
|
-
case
|
961
|
+
goto _test_eof5;
|
962
|
+
case 5:
|
961
963
|
switch( (*p) ) {
|
962
|
-
case 43: goto
|
963
|
-
case 45: goto
|
964
|
+
case 43: goto st6;
|
965
|
+
case 45: goto st6;
|
964
966
|
}
|
965
967
|
if ( 48 <= (*p) && (*p) <= 57 )
|
966
|
-
goto
|
968
|
+
goto st10;
|
967
969
|
goto st0;
|
968
|
-
|
970
|
+
st6:
|
969
971
|
if ( ++p == pe )
|
970
|
-
goto
|
971
|
-
case
|
972
|
+
goto _test_eof6;
|
973
|
+
case 6:
|
972
974
|
if ( 48 <= (*p) && (*p) <= 57 )
|
973
|
-
goto
|
975
|
+
goto st10;
|
974
976
|
goto st0;
|
975
|
-
|
977
|
+
st10:
|
976
978
|
if ( ++p == pe )
|
977
|
-
goto
|
978
|
-
case
|
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
|
987
|
+
goto st10;
|
986
988
|
} else if ( (*p) >= 45 )
|
987
989
|
goto st0;
|
988
|
-
goto
|
989
|
-
|
990
|
+
goto tr9;
|
991
|
+
st7:
|
990
992
|
if ( ++p == pe )
|
991
|
-
goto
|
992
|
-
case
|
993
|
+
goto _test_eof7;
|
994
|
+
case 7:
|
993
995
|
switch( (*p) ) {
|
994
996
|
case 46: goto st4;
|
995
|
-
case 69: goto
|
996
|
-
case 101: goto
|
997
|
+
case 69: goto st5;
|
998
|
+
case 101: goto st5;
|
997
999
|
}
|
998
1000
|
if ( 48 <= (*p) && (*p) <= 57 )
|
999
|
-
goto
|
1001
|
+
goto st7;
|
1000
1002
|
goto st0;
|
1001
1003
|
}
|
1002
|
-
_test_eof2: cs = 2; goto _test_eof;
|
1003
|
-
_test_eof3: cs = 3; goto _test_eof;
|
1004
|
-
_test_eof4: cs = 4; goto _test_eof;
|
1005
|
-
|
1006
|
-
|
1007
|
-
|
1008
|
-
|
1009
|
-
|
1010
|
-
|
1004
|
+
_test_eof2: cs = 2; goto _test_eof;
|
1005
|
+
_test_eof3: cs = 3; goto _test_eof;
|
1006
|
+
_test_eof4: cs = 4; goto _test_eof;
|
1007
|
+
_test_eof8: cs = 8; goto _test_eof;
|
1008
|
+
_test_eof9: cs = 9; goto _test_eof;
|
1009
|
+
_test_eof5: cs = 5; goto _test_eof;
|
1010
|
+
_test_eof6: cs = 6; goto _test_eof;
|
1011
|
+
_test_eof10: cs = 10; goto _test_eof;
|
1012
|
+
_test_eof7: cs = 7; goto _test_eof;
|
1011
1013
|
|
1012
1014
|
_test_eof: {}
|
1013
1015
|
_out: {}
|
1014
1016
|
}
|
1015
1017
|
|
1016
|
-
#line
|
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
|
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,7 +1036,7 @@ static const int JSON_array_error = 0;
|
|
1034
1036
|
static const int JSON_array_en_main = 1;
|
1035
1037
|
|
1036
1038
|
|
1037
|
-
#line
|
1039
|
+
#line 369 "parser.rl"
|
1038
1040
|
|
1039
1041
|
|
1040
1042
|
static char *JSON_parse_array(JSON_Parser *json, char *p, char *pe, VALUE *result)
|
@@ -1047,15 +1049,15 @@ static char *JSON_parse_array(JSON_Parser *json, char *p, char *pe, VALUE *resul
|
|
1047
1049
|
}
|
1048
1050
|
*result = NIL_P(array_class) ? rb_ary_new() : rb_class_new_instance(0, 0, array_class);
|
1049
1051
|
|
1050
|
-
|
1051
|
-
#line
|
1052
|
+
|
1053
|
+
#line 1054 "parser.c"
|
1052
1054
|
{
|
1053
1055
|
cs = JSON_array_start;
|
1054
1056
|
}
|
1055
1057
|
|
1056
|
-
#line
|
1057
|
-
|
1058
|
-
#line
|
1058
|
+
#line 382 "parser.rl"
|
1059
|
+
|
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
|
1099
|
+
#line 346 "parser.rl"
|
1098
1100
|
{
|
1099
1101
|
VALUE v = Qnil;
|
1100
|
-
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
|
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
|
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
|
1226
|
+
#line 1227 "parser.c"
|
1225
1227
|
goto st0;
|
1226
1228
|
st13:
|
1227
1229
|
if ( ++p == pe )
|
@@ -1256,28 +1258,28 @@ case 16:
|
|
1256
1258
|
goto st2;
|
1257
1259
|
goto st16;
|
1258
1260
|
}
|
1259
|
-
_test_eof2: cs = 2; goto _test_eof;
|
1260
|
-
_test_eof3: cs = 3; goto _test_eof;
|
1261
|
-
_test_eof4: cs = 4; goto _test_eof;
|
1262
|
-
_test_eof5: cs = 5; goto _test_eof;
|
1263
|
-
_test_eof6: cs = 6; goto _test_eof;
|
1264
|
-
_test_eof7: cs = 7; goto _test_eof;
|
1265
|
-
_test_eof8: cs = 8; goto _test_eof;
|
1266
|
-
_test_eof9: cs = 9; goto _test_eof;
|
1267
|
-
_test_eof10: cs = 10; goto _test_eof;
|
1268
|
-
_test_eof11: cs = 11; goto _test_eof;
|
1269
|
-
_test_eof12: cs = 12; goto _test_eof;
|
1270
|
-
_test_eof17: cs = 17; goto _test_eof;
|
1271
|
-
_test_eof13: cs = 13; goto _test_eof;
|
1272
|
-
_test_eof14: cs = 14; goto _test_eof;
|
1273
|
-
_test_eof15: cs = 15; goto _test_eof;
|
1274
|
-
_test_eof16: cs = 16; goto _test_eof;
|
1261
|
+
_test_eof2: cs = 2; goto _test_eof;
|
1262
|
+
_test_eof3: cs = 3; goto _test_eof;
|
1263
|
+
_test_eof4: cs = 4; goto _test_eof;
|
1264
|
+
_test_eof5: cs = 5; goto _test_eof;
|
1265
|
+
_test_eof6: cs = 6; goto _test_eof;
|
1266
|
+
_test_eof7: cs = 7; goto _test_eof;
|
1267
|
+
_test_eof8: cs = 8; goto _test_eof;
|
1268
|
+
_test_eof9: cs = 9; goto _test_eof;
|
1269
|
+
_test_eof10: cs = 10; goto _test_eof;
|
1270
|
+
_test_eof11: cs = 11; goto _test_eof;
|
1271
|
+
_test_eof12: cs = 12; goto _test_eof;
|
1272
|
+
_test_eof17: cs = 17; goto _test_eof;
|
1273
|
+
_test_eof13: cs = 13; goto _test_eof;
|
1274
|
+
_test_eof14: cs = 14; goto _test_eof;
|
1275
|
+
_test_eof15: cs = 15; goto _test_eof;
|
1276
|
+
_test_eof16: cs = 16; goto _test_eof;
|
1275
1277
|
|
1276
1278
|
_test_eof: {}
|
1277
1279
|
_out: {}
|
1278
1280
|
}
|
1279
1281
|
|
1280
|
-
#line
|
1282
|
+
#line 383 "parser.rl"
|
1281
1283
|
|
1282
1284
|
if(cs >= JSON_array_first_final) {
|
1283
1285
|
return p + 1;
|
@@ -1320,7 +1322,7 @@ static VALUE json_string_unescape(VALUE result, char *string, char *stringEnd)
|
|
1320
1322
|
unescape = (char *) "\f";
|
1321
1323
|
break;
|
1322
1324
|
case 'u':
|
1323
|
-
if (pe > stringEnd - 4) {
|
1325
|
+
if (pe > stringEnd - 4) {
|
1324
1326
|
return Qnil;
|
1325
1327
|
} else {
|
1326
1328
|
char buf[4];
|
@@ -1358,7 +1360,7 @@ static VALUE json_string_unescape(VALUE result, char *string, char *stringEnd)
|
|
1358
1360
|
}
|
1359
1361
|
|
1360
1362
|
|
1361
|
-
#line
|
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
|
1371
|
+
#line 482 "parser.rl"
|
1370
1372
|
|
1371
1373
|
|
1372
1374
|
static int
|
@@ -1387,16 +1389,16 @@ static char *JSON_parse_string(JSON_Parser *json, char *p, char *pe, VALUE *resu
|
|
1387
1389
|
VALUE match_string;
|
1388
1390
|
|
1389
1391
|
*result = rb_str_buf_new(0);
|
1390
|
-
|
1391
|
-
#line
|
1392
|
+
|
1393
|
+
#line 1394 "parser.c"
|
1392
1394
|
{
|
1393
1395
|
cs = JSON_string_start;
|
1394
1396
|
}
|
1395
1397
|
|
1396
|
-
#line
|
1398
|
+
#line 503 "parser.rl"
|
1397
1399
|
json->memo = p;
|
1398
|
-
|
1399
|
-
#line
|
1400
|
+
|
1401
|
+
#line 1402 "parser.c"
|
1400
1402
|
{
|
1401
1403
|
if ( p == pe )
|
1402
1404
|
goto _test_eof;
|
@@ -1421,7 +1423,7 @@ case 2:
|
|
1421
1423
|
goto st0;
|
1422
1424
|
goto st2;
|
1423
1425
|
tr2:
|
1424
|
-
#line
|
1426
|
+
#line 468 "parser.rl"
|
1425
1427
|
{
|
1426
1428
|
*result = json_string_unescape(*result, json->memo + 1, p);
|
1427
1429
|
if (NIL_P(*result)) {
|
@@ -1432,14 +1434,14 @@ tr2:
|
|
1432
1434
|
{p = (( p + 1))-1;}
|
1433
1435
|
}
|
1434
1436
|
}
|
1435
|
-
#line
|
1437
|
+
#line 479 "parser.rl"
|
1436
1438
|
{ p--; {p++; cs = 8; goto _out;} }
|
1437
1439
|
goto st8;
|
1438
1440
|
st8:
|
1439
1441
|
if ( ++p == pe )
|
1440
1442
|
goto _test_eof8;
|
1441
1443
|
case 8:
|
1442
|
-
#line
|
1444
|
+
#line 1445 "parser.c"
|
1443
1445
|
goto st0;
|
1444
1446
|
st3:
|
1445
1447
|
if ( ++p == pe )
|
@@ -1503,19 +1505,19 @@ case 7:
|
|
1503
1505
|
goto st2;
|
1504
1506
|
goto st0;
|
1505
1507
|
}
|
1506
|
-
_test_eof2: cs = 2; goto _test_eof;
|
1507
|
-
_test_eof8: cs = 8; goto _test_eof;
|
1508
|
-
_test_eof3: cs = 3; goto _test_eof;
|
1509
|
-
_test_eof4: cs = 4; goto _test_eof;
|
1510
|
-
_test_eof5: cs = 5; goto _test_eof;
|
1511
|
-
_test_eof6: cs = 6; goto _test_eof;
|
1512
|
-
_test_eof7: cs = 7; goto _test_eof;
|
1508
|
+
_test_eof2: cs = 2; goto _test_eof;
|
1509
|
+
_test_eof8: cs = 8; goto _test_eof;
|
1510
|
+
_test_eof3: cs = 3; goto _test_eof;
|
1511
|
+
_test_eof4: cs = 4; goto _test_eof;
|
1512
|
+
_test_eof5: cs = 5; goto _test_eof;
|
1513
|
+
_test_eof6: cs = 6; goto _test_eof;
|
1514
|
+
_test_eof7: cs = 7; goto _test_eof;
|
1513
1515
|
|
1514
1516
|
_test_eof: {}
|
1515
1517
|
_out: {}
|
1516
1518
|
}
|
1517
1519
|
|
1518
|
-
#line
|
1520
|
+
#line 505 "parser.rl"
|
1519
1521
|
|
1520
1522
|
if (json->create_additions && RTEST(match_string = json->match_string)) {
|
1521
1523
|
VALUE klass;
|
@@ -1538,20 +1540,7 @@ case 7:
|
|
1538
1540
|
}
|
1539
1541
|
}
|
1540
1542
|
|
1541
|
-
|
1542
|
-
|
1543
|
-
#line 1544 "parser.c"
|
1544
|
-
static const int JSON_start = 1;
|
1545
|
-
static const int JSON_first_final = 10;
|
1546
|
-
static const int JSON_error = 0;
|
1547
|
-
|
1548
|
-
static const int JSON_en_main = 1;
|
1549
|
-
|
1550
|
-
|
1551
|
-
#line 550 "parser.rl"
|
1552
|
-
|
1553
|
-
|
1554
|
-
/*
|
1543
|
+
/*
|
1555
1544
|
* Document-class: JSON::Ext::Parser
|
1556
1545
|
*
|
1557
1546
|
* This is the JSON parser implemented as a C extension. It can be configured
|
@@ -1575,22 +1564,15 @@ static VALUE convert_encoding(VALUE source)
|
|
1575
1564
|
VALUE encoding = rb_funcall(source, i_encoding, 0);
|
1576
1565
|
if (encoding == CEncoding_ASCII_8BIT) {
|
1577
1566
|
if (len >= 4 && ptr[0] == 0 && ptr[1] == 0 && ptr[2] == 0) {
|
1578
|
-
source =
|
1579
|
-
rb_funcall(source, i_force_encoding, 1, CEncoding_UTF_32BE);
|
1580
|
-
source = rb_funcall(source, i_encode_bang, 1, CEncoding_UTF_8);
|
1567
|
+
source = rb_funcall(source, i_encode, 2, CEncoding_UTF_8, CEncoding_UTF_32BE);
|
1581
1568
|
} else if (len >= 4 && ptr[0] == 0 && ptr[2] == 0) {
|
1582
|
-
source =
|
1583
|
-
rb_funcall(source, i_force_encoding, 1, CEncoding_UTF_16BE);
|
1584
|
-
source = rb_funcall(source, i_encode_bang, 1, CEncoding_UTF_8);
|
1569
|
+
source = rb_funcall(source, i_encode, 2, CEncoding_UTF_8, CEncoding_UTF_16BE);
|
1585
1570
|
} else if (len >= 4 && ptr[1] == 0 && ptr[2] == 0 && ptr[3] == 0) {
|
1586
|
-
source =
|
1587
|
-
rb_funcall(source, i_force_encoding, 1, CEncoding_UTF_32LE);
|
1588
|
-
source = rb_funcall(source, i_encode_bang, 1, CEncoding_UTF_8);
|
1571
|
+
source = rb_funcall(source, i_encode, 2, CEncoding_UTF_8, CEncoding_UTF_32LE);
|
1589
1572
|
} else if (len >= 4 && ptr[1] == 0 && ptr[3] == 0) {
|
1590
|
-
source =
|
1591
|
-
rb_funcall(source, i_force_encoding, 1, CEncoding_UTF_16LE);
|
1592
|
-
source = rb_funcall(source, i_encode_bang, 1, CEncoding_UTF_8);
|
1573
|
+
source = rb_funcall(source, i_encode, 2, CEncoding_UTF_8, CEncoding_UTF_16LE);
|
1593
1574
|
} else {
|
1575
|
+
source = rb_str_dup(source);
|
1594
1576
|
FORCE_UTF8(source);
|
1595
1577
|
}
|
1596
1578
|
} else {
|
@@ -1636,17 +1618,19 @@ static VALUE convert_encoding(VALUE source)
|
|
1636
1618
|
* defaults to true.
|
1637
1619
|
* * *object_class*: Defaults to Hash
|
1638
1620
|
* * *array_class*: Defaults to Array
|
1621
|
+
* * *quirks_mode*: Enables quirks_mode for parser, that is for example
|
1622
|
+
* parsing single JSON values instead of documents is possible.
|
1623
|
+
*
|
1639
1624
|
*/
|
1640
1625
|
static VALUE cParser_initialize(int argc, VALUE *argv, VALUE self)
|
1641
1626
|
{
|
1642
|
-
char *ptr;
|
1643
|
-
long len;
|
1644
1627
|
VALUE source, opts;
|
1645
|
-
|
1628
|
+
GET_PARSER_INIT;
|
1629
|
+
|
1630
|
+
if (json->Vsource) {
|
1631
|
+
rb_raise(rb_eTypeError, "already initialized instance");
|
1632
|
+
}
|
1646
1633
|
rb_scan_args(argc, argv, "11", &source, &opts);
|
1647
|
-
source = convert_encoding(StringValue(source));
|
1648
|
-
ptr = RSTRING_PTR(source);
|
1649
|
-
len = RSTRING_LEN(source);
|
1650
1634
|
if (!NIL_P(opts)) {
|
1651
1635
|
opts = rb_convert_type(opts, T_HASH, "Hash", "to_hash");
|
1652
1636
|
if (NIL_P(opts)) {
|
@@ -1676,6 +1660,13 @@ static VALUE cParser_initialize(int argc, VALUE *argv, VALUE self)
|
|
1676
1660
|
} else {
|
1677
1661
|
json->symbolize_names = 0;
|
1678
1662
|
}
|
1663
|
+
tmp = ID2SYM(i_quirks_mode);
|
1664
|
+
if (option_given_p(opts, tmp)) {
|
1665
|
+
VALUE quirks_mode = rb_hash_aref(opts, tmp);
|
1666
|
+
json->quirks_mode = RTEST(quirks_mode) ? 1 : 0;
|
1667
|
+
} else {
|
1668
|
+
json->quirks_mode = 0;
|
1669
|
+
}
|
1679
1670
|
tmp = ID2SYM(i_create_additions);
|
1680
1671
|
if (option_given_p(opts, tmp)) {
|
1681
1672
|
json->create_additions = RTEST(rb_hash_aref(opts, tmp));
|
@@ -1716,37 +1707,46 @@ static VALUE cParser_initialize(int argc, VALUE *argv, VALUE self)
|
|
1716
1707
|
json->object_class = Qnil;
|
1717
1708
|
json->array_class = Qnil;
|
1718
1709
|
}
|
1710
|
+
if (!json->quirks_mode) {
|
1711
|
+
source = convert_encoding(StringValue(source));
|
1712
|
+
}
|
1719
1713
|
json->current_nesting = 0;
|
1720
|
-
json->len =
|
1721
|
-
json->source =
|
1714
|
+
json->len = RSTRING_LEN(source);
|
1715
|
+
json->source = RSTRING_PTR(source);;
|
1722
1716
|
json->Vsource = source;
|
1723
1717
|
return self;
|
1724
1718
|
}
|
1725
1719
|
|
1726
|
-
|
1727
|
-
|
1728
|
-
|
1729
|
-
|
1730
|
-
|
1731
|
-
|
1732
|
-
static
|
1720
|
+
|
1721
|
+
#line 1719 "parser.c"
|
1722
|
+
static const int JSON_start = 1;
|
1723
|
+
static const int JSON_first_final = 10;
|
1724
|
+
static const int JSON_error = 0;
|
1725
|
+
|
1726
|
+
static const int JSON_en_main = 1;
|
1727
|
+
|
1728
|
+
|
1729
|
+
#line 726 "parser.rl"
|
1730
|
+
|
1731
|
+
|
1732
|
+
static VALUE cParser_parse_strict(VALUE self)
|
1733
1733
|
{
|
1734
1734
|
char *p, *pe;
|
1735
1735
|
int cs = EVIL;
|
1736
1736
|
VALUE result = Qnil;
|
1737
1737
|
GET_PARSER;
|
1738
1738
|
|
1739
|
-
|
1740
|
-
#line
|
1739
|
+
|
1740
|
+
#line 1738 "parser.c"
|
1741
1741
|
{
|
1742
1742
|
cs = JSON_start;
|
1743
1743
|
}
|
1744
1744
|
|
1745
|
-
#line
|
1745
|
+
#line 736 "parser.rl"
|
1746
1746
|
p = json->source;
|
1747
1747
|
pe = p + json->len;
|
1748
|
-
|
1749
|
-
#line
|
1748
|
+
|
1749
|
+
#line 1747 "parser.c"
|
1750
1750
|
{
|
1751
1751
|
if ( p == pe )
|
1752
1752
|
goto _test_eof;
|
@@ -1802,7 +1802,7 @@ case 5:
|
|
1802
1802
|
goto st1;
|
1803
1803
|
goto st5;
|
1804
1804
|
tr3:
|
1805
|
-
#line
|
1805
|
+
#line 715 "parser.rl"
|
1806
1806
|
{
|
1807
1807
|
char *np;
|
1808
1808
|
json->current_nesting = 1;
|
@@ -1811,7 +1811,7 @@ tr3:
|
|
1811
1811
|
}
|
1812
1812
|
goto st10;
|
1813
1813
|
tr4:
|
1814
|
-
#line
|
1814
|
+
#line 708 "parser.rl"
|
1815
1815
|
{
|
1816
1816
|
char *np;
|
1817
1817
|
json->current_nesting = 1;
|
@@ -1823,7 +1823,7 @@ st10:
|
|
1823
1823
|
if ( ++p == pe )
|
1824
1824
|
goto _test_eof10;
|
1825
1825
|
case 10:
|
1826
|
-
#line
|
1826
|
+
#line 1824 "parser.c"
|
1827
1827
|
switch( (*p) ) {
|
1828
1828
|
case 13: goto st10;
|
1829
1829
|
case 32: goto st10;
|
@@ -1865,22 +1865,22 @@ case 9:
|
|
1865
1865
|
goto st10;
|
1866
1866
|
goto st9;
|
1867
1867
|
}
|
1868
|
-
_test_eof1: cs = 1; goto _test_eof;
|
1869
|
-
_test_eof2: cs = 2; goto _test_eof;
|
1870
|
-
_test_eof3: cs = 3; goto _test_eof;
|
1871
|
-
_test_eof4: cs = 4; goto _test_eof;
|
1872
|
-
_test_eof5: cs = 5; goto _test_eof;
|
1873
|
-
_test_eof10: cs = 10; goto _test_eof;
|
1874
|
-
_test_eof6: cs = 6; goto _test_eof;
|
1875
|
-
_test_eof7: cs = 7; goto _test_eof;
|
1876
|
-
_test_eof8: cs = 8; goto _test_eof;
|
1877
|
-
_test_eof9: cs = 9; goto _test_eof;
|
1868
|
+
_test_eof1: cs = 1; goto _test_eof;
|
1869
|
+
_test_eof2: cs = 2; goto _test_eof;
|
1870
|
+
_test_eof3: cs = 3; goto _test_eof;
|
1871
|
+
_test_eof4: cs = 4; goto _test_eof;
|
1872
|
+
_test_eof5: cs = 5; goto _test_eof;
|
1873
|
+
_test_eof10: cs = 10; goto _test_eof;
|
1874
|
+
_test_eof6: cs = 6; goto _test_eof;
|
1875
|
+
_test_eof7: cs = 7; goto _test_eof;
|
1876
|
+
_test_eof8: cs = 8; goto _test_eof;
|
1877
|
+
_test_eof9: cs = 9; goto _test_eof;
|
1878
1878
|
|
1879
1879
|
_test_eof: {}
|
1880
1880
|
_out: {}
|
1881
1881
|
}
|
1882
1882
|
|
1883
|
-
#line
|
1883
|
+
#line 739 "parser.rl"
|
1884
1884
|
|
1885
1885
|
if (cs >= JSON_first_final && p == pe) {
|
1886
1886
|
return result;
|
@@ -1890,6 +1890,197 @@ case 9:
|
|
1890
1890
|
}
|
1891
1891
|
}
|
1892
1892
|
|
1893
|
+
|
1894
|
+
|
1895
|
+
#line 1893 "parser.c"
|
1896
|
+
static const int JSON_quirks_mode_start = 1;
|
1897
|
+
static const int JSON_quirks_mode_first_final = 10;
|
1898
|
+
static const int JSON_quirks_mode_error = 0;
|
1899
|
+
|
1900
|
+
static const int JSON_quirks_mode_en_main = 1;
|
1901
|
+
|
1902
|
+
|
1903
|
+
#line 764 "parser.rl"
|
1904
|
+
|
1905
|
+
|
1906
|
+
static VALUE cParser_parse_quirks_mode(VALUE self)
|
1907
|
+
{
|
1908
|
+
char *p, *pe;
|
1909
|
+
int cs = EVIL;
|
1910
|
+
VALUE result = Qnil;
|
1911
|
+
GET_PARSER;
|
1912
|
+
|
1913
|
+
|
1914
|
+
#line 1912 "parser.c"
|
1915
|
+
{
|
1916
|
+
cs = JSON_quirks_mode_start;
|
1917
|
+
}
|
1918
|
+
|
1919
|
+
#line 774 "parser.rl"
|
1920
|
+
p = json->source;
|
1921
|
+
pe = p + json->len;
|
1922
|
+
|
1923
|
+
#line 1921 "parser.c"
|
1924
|
+
{
|
1925
|
+
if ( p == pe )
|
1926
|
+
goto _test_eof;
|
1927
|
+
switch ( cs )
|
1928
|
+
{
|
1929
|
+
st1:
|
1930
|
+
if ( ++p == pe )
|
1931
|
+
goto _test_eof1;
|
1932
|
+
case 1:
|
1933
|
+
switch( (*p) ) {
|
1934
|
+
case 13: goto st1;
|
1935
|
+
case 32: goto st1;
|
1936
|
+
case 34: goto tr2;
|
1937
|
+
case 45: goto tr2;
|
1938
|
+
case 47: goto st6;
|
1939
|
+
case 73: goto tr2;
|
1940
|
+
case 78: goto tr2;
|
1941
|
+
case 91: goto tr2;
|
1942
|
+
case 102: goto tr2;
|
1943
|
+
case 110: goto tr2;
|
1944
|
+
case 116: goto tr2;
|
1945
|
+
case 123: goto tr2;
|
1946
|
+
}
|
1947
|
+
if ( (*p) > 10 ) {
|
1948
|
+
if ( 48 <= (*p) && (*p) <= 57 )
|
1949
|
+
goto tr2;
|
1950
|
+
} else if ( (*p) >= 9 )
|
1951
|
+
goto st1;
|
1952
|
+
goto st0;
|
1953
|
+
st0:
|
1954
|
+
cs = 0;
|
1955
|
+
goto _out;
|
1956
|
+
tr2:
|
1957
|
+
#line 756 "parser.rl"
|
1958
|
+
{
|
1959
|
+
char *np = JSON_parse_value(json, p, pe, &result);
|
1960
|
+
if (np == NULL) { p--; {p++; cs = 10; goto _out;} } else {p = (( np))-1;}
|
1961
|
+
}
|
1962
|
+
goto st10;
|
1963
|
+
st10:
|
1964
|
+
if ( ++p == pe )
|
1965
|
+
goto _test_eof10;
|
1966
|
+
case 10:
|
1967
|
+
#line 1965 "parser.c"
|
1968
|
+
switch( (*p) ) {
|
1969
|
+
case 13: goto st10;
|
1970
|
+
case 32: goto st10;
|
1971
|
+
case 47: goto st2;
|
1972
|
+
}
|
1973
|
+
if ( 9 <= (*p) && (*p) <= 10 )
|
1974
|
+
goto st10;
|
1975
|
+
goto st0;
|
1976
|
+
st2:
|
1977
|
+
if ( ++p == pe )
|
1978
|
+
goto _test_eof2;
|
1979
|
+
case 2:
|
1980
|
+
switch( (*p) ) {
|
1981
|
+
case 42: goto st3;
|
1982
|
+
case 47: goto st5;
|
1983
|
+
}
|
1984
|
+
goto st0;
|
1985
|
+
st3:
|
1986
|
+
if ( ++p == pe )
|
1987
|
+
goto _test_eof3;
|
1988
|
+
case 3:
|
1989
|
+
if ( (*p) == 42 )
|
1990
|
+
goto st4;
|
1991
|
+
goto st3;
|
1992
|
+
st4:
|
1993
|
+
if ( ++p == pe )
|
1994
|
+
goto _test_eof4;
|
1995
|
+
case 4:
|
1996
|
+
switch( (*p) ) {
|
1997
|
+
case 42: goto st4;
|
1998
|
+
case 47: goto st10;
|
1999
|
+
}
|
2000
|
+
goto st3;
|
2001
|
+
st5:
|
2002
|
+
if ( ++p == pe )
|
2003
|
+
goto _test_eof5;
|
2004
|
+
case 5:
|
2005
|
+
if ( (*p) == 10 )
|
2006
|
+
goto st10;
|
2007
|
+
goto st5;
|
2008
|
+
st6:
|
2009
|
+
if ( ++p == pe )
|
2010
|
+
goto _test_eof6;
|
2011
|
+
case 6:
|
2012
|
+
switch( (*p) ) {
|
2013
|
+
case 42: goto st7;
|
2014
|
+
case 47: goto st9;
|
2015
|
+
}
|
2016
|
+
goto st0;
|
2017
|
+
st7:
|
2018
|
+
if ( ++p == pe )
|
2019
|
+
goto _test_eof7;
|
2020
|
+
case 7:
|
2021
|
+
if ( (*p) == 42 )
|
2022
|
+
goto st8;
|
2023
|
+
goto st7;
|
2024
|
+
st8:
|
2025
|
+
if ( ++p == pe )
|
2026
|
+
goto _test_eof8;
|
2027
|
+
case 8:
|
2028
|
+
switch( (*p) ) {
|
2029
|
+
case 42: goto st8;
|
2030
|
+
case 47: goto st1;
|
2031
|
+
}
|
2032
|
+
goto st7;
|
2033
|
+
st9:
|
2034
|
+
if ( ++p == pe )
|
2035
|
+
goto _test_eof9;
|
2036
|
+
case 9:
|
2037
|
+
if ( (*p) == 10 )
|
2038
|
+
goto st1;
|
2039
|
+
goto st9;
|
2040
|
+
}
|
2041
|
+
_test_eof1: cs = 1; goto _test_eof;
|
2042
|
+
_test_eof10: cs = 10; goto _test_eof;
|
2043
|
+
_test_eof2: cs = 2; goto _test_eof;
|
2044
|
+
_test_eof3: cs = 3; goto _test_eof;
|
2045
|
+
_test_eof4: cs = 4; goto _test_eof;
|
2046
|
+
_test_eof5: cs = 5; goto _test_eof;
|
2047
|
+
_test_eof6: cs = 6; goto _test_eof;
|
2048
|
+
_test_eof7: cs = 7; goto _test_eof;
|
2049
|
+
_test_eof8: cs = 8; goto _test_eof;
|
2050
|
+
_test_eof9: cs = 9; goto _test_eof;
|
2051
|
+
|
2052
|
+
_test_eof: {}
|
2053
|
+
_out: {}
|
2054
|
+
}
|
2055
|
+
|
2056
|
+
#line 777 "parser.rl"
|
2057
|
+
|
2058
|
+
if (cs >= JSON_quirks_mode_first_final && p == pe) {
|
2059
|
+
return result;
|
2060
|
+
} else {
|
2061
|
+
rb_raise(eParserError, "%u: unexpected token at '%s'", __LINE__, p);
|
2062
|
+
return Qnil;
|
2063
|
+
}
|
2064
|
+
}
|
2065
|
+
|
2066
|
+
/*
|
2067
|
+
* call-seq: parse()
|
2068
|
+
*
|
2069
|
+
* Parses the current JSON text _source_ and returns the complete data
|
2070
|
+
* structure as a result.
|
2071
|
+
*/
|
2072
|
+
static VALUE cParser_parse(VALUE self)
|
2073
|
+
{
|
2074
|
+
GET_PARSER;
|
2075
|
+
|
2076
|
+
if (json->quirks_mode) {
|
2077
|
+
return cParser_parse_quirks_mode(self);
|
2078
|
+
} else {
|
2079
|
+
return cParser_parse_strict(self);
|
2080
|
+
}
|
2081
|
+
}
|
2082
|
+
|
2083
|
+
|
1893
2084
|
static JSON_Parser *JSON_allocate()
|
1894
2085
|
{
|
1895
2086
|
JSON_Parser *json = ALLOC(JSON_Parser);
|
@@ -1929,6 +2120,18 @@ static VALUE cParser_source(VALUE self)
|
|
1929
2120
|
return rb_str_dup(json->Vsource);
|
1930
2121
|
}
|
1931
2122
|
|
2123
|
+
/*
|
2124
|
+
* call-seq: quirks_mode?()
|
2125
|
+
*
|
2126
|
+
* Returns a true, if this parser is in quirks_mode, false otherwise.
|
2127
|
+
*/
|
2128
|
+
static VALUE cParser_quirks_mode_p(VALUE self)
|
2129
|
+
{
|
2130
|
+
GET_PARSER;
|
2131
|
+
return json->quirks_mode ? Qtrue : Qfalse;
|
2132
|
+
}
|
2133
|
+
|
2134
|
+
|
1932
2135
|
void Init_parser()
|
1933
2136
|
{
|
1934
2137
|
rb_require("json/common");
|
@@ -1941,6 +2144,7 @@ void Init_parser()
|
|
1941
2144
|
rb_define_method(cParser, "initialize", cParser_initialize, -1);
|
1942
2145
|
rb_define_method(cParser, "parse", cParser_parse, 0);
|
1943
2146
|
rb_define_method(cParser, "source", cParser_source, 0);
|
2147
|
+
rb_define_method(cParser, "quirks_mode?", cParser_quirks_mode_p, 0);
|
1944
2148
|
|
1945
2149
|
CNaN = rb_const_get(mJSON, rb_intern("NaN"));
|
1946
2150
|
CInfinity = rb_const_get(mJSON, rb_intern("Infinity"));
|
@@ -1954,6 +2158,7 @@ void Init_parser()
|
|
1954
2158
|
i_max_nesting = rb_intern("max_nesting");
|
1955
2159
|
i_allow_nan = rb_intern("allow_nan");
|
1956
2160
|
i_symbolize_names = rb_intern("symbolize_names");
|
2161
|
+
i_quirks_mode = rb_intern("quirks_mode");
|
1957
2162
|
i_object_class = rb_intern("object_class");
|
1958
2163
|
i_array_class = rb_intern("array_class");
|
1959
2164
|
i_match = rb_intern("match");
|
@@ -1971,9 +2176,15 @@ void Init_parser()
|
|
1971
2176
|
CEncoding_ASCII_8BIT = rb_funcall(rb_path2class("Encoding"), rb_intern("find"), 1, rb_str_new2("ascii-8bit"));
|
1972
2177
|
i_encoding = rb_intern("encoding");
|
1973
2178
|
i_encode = rb_intern("encode");
|
1974
|
-
i_encode_bang = rb_intern("encode!");
|
1975
|
-
i_force_encoding = rb_intern("force_encoding");
|
1976
2179
|
#else
|
1977
2180
|
i_iconv = rb_intern("iconv");
|
1978
2181
|
#endif
|
1979
2182
|
}
|
2183
|
+
|
2184
|
+
/*
|
2185
|
+
* Local variables:
|
2186
|
+
* mode: c
|
2187
|
+
* c-file-style: ruby
|
2188
|
+
* indent-tabs-mode: nil
|
2189
|
+
* End:
|
2190
|
+
*/
|