json_pure 1.5.3 → 1.5.4
Sign up to get free protection for your applications and to get access to all the features.
- 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 +70 -51
- 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
|
+
*/
|