json 0.4.3 → 1.0.0
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 +6 -1
- data/README +49 -7
- data/Rakefile +216 -52
- data/TODO +1 -0
- data/VERSION +1 -1
- data/benchmarks/benchmark.txt +133 -0
- data/benchmarks/benchmark_generator.rb +44 -0
- data/benchmarks/benchmark_parser.rb +22 -0
- data/benchmarks/benchmark_rails.rb +26 -0
- data/data/example.json +1 -0
- data/data/index.html +37 -0
- data/data/prototype.js +2515 -0
- data/ext/json/ext/generator/Makefile +149 -0
- data/ext/json/ext/generator/extconf.rb +9 -0
- data/ext/json/ext/generator/generator.c +729 -0
- data/ext/json/ext/generator/unicode.c +184 -0
- data/ext/json/ext/generator/unicode.h +40 -0
- data/ext/json/ext/parser/Makefile +149 -0
- data/ext/json/ext/parser/extconf.rb +9 -0
- data/ext/json/ext/parser/parser.c +1551 -0
- data/ext/json/ext/parser/parser.rl +515 -0
- data/ext/json/ext/parser/unicode.c +156 -0
- data/ext/json/ext/parser/unicode.h +44 -0
- data/install.rb +13 -8
- data/lib/json.rb +101 -614
- data/lib/json/common.rb +184 -0
- data/lib/json/editor.rb +19 -10
- data/lib/json/ext.rb +13 -0
- data/lib/json/pure.rb +75 -0
- data/lib/json/pure/generator.rb +321 -0
- data/lib/json/pure/parser.rb +210 -0
- data/lib/json/version.rb +8 -0
- data/tests/fixtures/fail1.json +1 -0
- data/tests/fixtures/fail10.json +1 -0
- data/tests/fixtures/fail11.json +1 -0
- data/tests/fixtures/fail12.json +1 -0
- data/tests/fixtures/fail13.json +1 -0
- data/tests/fixtures/fail14.json +1 -0
- data/tests/fixtures/fail15.json +1 -0
- data/tests/fixtures/fail16.json +1 -0
- data/tests/fixtures/fail17.json +1 -0
- data/tests/fixtures/fail19.json +1 -0
- data/tests/fixtures/fail2.json +1 -0
- data/tests/fixtures/fail20.json +1 -0
- data/tests/fixtures/fail21.json +1 -0
- data/tests/fixtures/fail22.json +1 -0
- data/tests/fixtures/fail23.json +1 -0
- data/tests/fixtures/fail24.json +1 -0
- data/tests/fixtures/fail25.json +1 -0
- data/tests/fixtures/fail26.json +1 -0
- data/tests/fixtures/fail27.json +2 -0
- data/tests/fixtures/fail28.json +2 -0
- data/tests/fixtures/fail3.json +1 -0
- data/tests/fixtures/fail4.json +1 -0
- data/tests/fixtures/fail5.json +1 -0
- data/tests/fixtures/fail6.json +1 -0
- data/tests/fixtures/fail7.json +1 -0
- data/tests/fixtures/fail8.json +1 -0
- data/tests/fixtures/fail9.json +1 -0
- data/tests/fixtures/pass1.json +56 -0
- data/tests/fixtures/pass18.json +1 -0
- data/tests/fixtures/pass2.json +1 -0
- data/tests/fixtures/pass3.json +6 -0
- data/tests/runner.rb +8 -2
- data/tests/test_json.rb +102 -154
- data/tests/test_json_addition.rb +94 -0
- data/tests/test_json_fixtures.rb +30 -0
- data/tests/test_json_generate.rb +81 -0
- data/tests/test_json_unicode.rb +55 -0
- data/tools/fuzz.rb +133 -0
- data/tools/server.rb +62 -0
- metadata +87 -10
- data/bla.json.tmp +0 -0
- data/lib/json.rb.orig +0 -708
@@ -0,0 +1,184 @@
|
|
1
|
+
/* vim: set cin et sw=4 ts=4: */
|
2
|
+
|
3
|
+
#include "unicode.h"
|
4
|
+
|
5
|
+
#define unicode_escape(buffer, character) \
|
6
|
+
sprintf(buf, "\\u%04x", (unsigned int) (character)); \
|
7
|
+
rb_str_buf_cat(buffer, buf, 6);
|
8
|
+
|
9
|
+
/*
|
10
|
+
* Copyright 2001-2004 Unicode, Inc.
|
11
|
+
*
|
12
|
+
* Disclaimer
|
13
|
+
*
|
14
|
+
* This source code is provided as is by Unicode, Inc. No claims are
|
15
|
+
* made as to fitness for any particular purpose. No warranties of any
|
16
|
+
* kind are expressed or implied. The recipient agrees to determine
|
17
|
+
* applicability of information provided. If this file has been
|
18
|
+
* purchased on magnetic or optical media from Unicode, Inc., the
|
19
|
+
* sole remedy for any claim will be exchange of defective media
|
20
|
+
* within 90 days of receipt.
|
21
|
+
*
|
22
|
+
* Limitations on Rights to Redistribute This Code
|
23
|
+
*
|
24
|
+
* Unicode, Inc. hereby grants the right to freely use the information
|
25
|
+
* supplied in this file in the creation of products supporting the
|
26
|
+
* Unicode Standard, and to make copies of this file in any form
|
27
|
+
* for internal or external distribution as long as this notice
|
28
|
+
* remains attached.
|
29
|
+
*/
|
30
|
+
|
31
|
+
/*
|
32
|
+
* Index into the table below with the first byte of a UTF-8 sequence to
|
33
|
+
* get the number of trailing bytes that are supposed to follow it.
|
34
|
+
* Note that *legal* UTF-8 values can't have 4 or 5-bytes. The table is
|
35
|
+
* left as-is for anyone who may want to do such conversion, which was
|
36
|
+
* allowed in earlier algorithms.
|
37
|
+
*/
|
38
|
+
static const char trailingBytesForUTF8[256] = {
|
39
|
+
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
40
|
+
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
41
|
+
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
42
|
+
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
43
|
+
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
44
|
+
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
45
|
+
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
|
46
|
+
2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 3,3,3,3,3,3,3,3,4,4,4,4,5,5,5,5
|
47
|
+
};
|
48
|
+
|
49
|
+
/*
|
50
|
+
* Magic values subtracted from a buffer value during UTF8 conversion.
|
51
|
+
* This table contains as many values as there might be trailing bytes
|
52
|
+
* in a UTF-8 sequence.
|
53
|
+
*/
|
54
|
+
static const UTF32 offsetsFromUTF8[6] = { 0x00000000UL, 0x00003080UL, 0x000E2080UL,
|
55
|
+
0x03C82080UL, 0xFA082080UL, 0x82082080UL };
|
56
|
+
|
57
|
+
/*
|
58
|
+
* Once the bits are split out into bytes of UTF-8, this is a mask OR-ed
|
59
|
+
* into the first byte, depending on how many bytes follow. There are
|
60
|
+
* as many entries in this table as there are UTF-8 sequence types.
|
61
|
+
* (I.e., one byte sequence, two byte... etc.). Remember that sequencs
|
62
|
+
* for *legal* UTF-8 will be 4 or fewer bytes total.
|
63
|
+
*/
|
64
|
+
static const UTF8 firstByteMark[7] = { 0x00, 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC };
|
65
|
+
|
66
|
+
/*
|
67
|
+
* Utility routine to tell whether a sequence of bytes is legal UTF-8.
|
68
|
+
* This must be called with the length pre-determined by the first byte.
|
69
|
+
* If not calling this from ConvertUTF8to*, then the length can be set by:
|
70
|
+
* length = trailingBytesForUTF8[*source]+1;
|
71
|
+
* and the sequence is illegal right away if there aren't that many bytes
|
72
|
+
* available.
|
73
|
+
* If presented with a length > 4, this returns 0. The Unicode
|
74
|
+
* definition of UTF-8 goes up to 4-byte sequences.
|
75
|
+
*/
|
76
|
+
|
77
|
+
inline static unsigned char isLegalUTF8(const UTF8 *source, int length)
|
78
|
+
{
|
79
|
+
UTF8 a;
|
80
|
+
const UTF8 *srcptr = source+length;
|
81
|
+
switch (length) {
|
82
|
+
default: return 0;
|
83
|
+
/* Everything else falls through when "1"... */
|
84
|
+
case 4: if ((a = (*--srcptr)) < 0x80 || a > 0xBF) return 0;
|
85
|
+
case 3: if ((a = (*--srcptr)) < 0x80 || a > 0xBF) return 0;
|
86
|
+
case 2: if ((a = (*--srcptr)) > 0xBF) return 0;
|
87
|
+
|
88
|
+
switch (*source) {
|
89
|
+
/* no fall-through in this inner switch */
|
90
|
+
case 0xE0: if (a < 0xA0) return 0; break;
|
91
|
+
case 0xED: if (a > 0x9F) return 0; break;
|
92
|
+
case 0xF0: if (a < 0x90) return 0; break;
|
93
|
+
case 0xF4: if (a > 0x8F) return 0; break;
|
94
|
+
default: if (a < 0x80) return 0;
|
95
|
+
}
|
96
|
+
|
97
|
+
case 1: if (*source >= 0x80 && *source < 0xC2) return 0;
|
98
|
+
}
|
99
|
+
if (*source > 0xF4) return 0;
|
100
|
+
return 1;
|
101
|
+
}
|
102
|
+
|
103
|
+
inline void JSON_convert_UTF8_to_JSON(VALUE buffer, VALUE string, ConversionFlags flags)
|
104
|
+
{
|
105
|
+
char buf[7];
|
106
|
+
const UTF8* source = (UTF8 *) RSTRING(string)->ptr;
|
107
|
+
const UTF8* sourceEnd = source + RSTRING(string)->len;
|
108
|
+
|
109
|
+
while (source < sourceEnd) {
|
110
|
+
UTF32 ch = 0;
|
111
|
+
unsigned short extraBytesToRead = trailingBytesForUTF8[*source];
|
112
|
+
if (source + extraBytesToRead >= sourceEnd) {
|
113
|
+
rb_raise(rb_path2class("JSON::GeneratorError"),
|
114
|
+
"partial character in source, but hit end");
|
115
|
+
}
|
116
|
+
if (!isLegalUTF8(source, extraBytesToRead+1)) {
|
117
|
+
rb_raise(rb_path2class("JSON::GeneratorError"),
|
118
|
+
"source sequence is illegal/malformed");
|
119
|
+
}
|
120
|
+
/*
|
121
|
+
* The cases all fall through. See "Note A" below.
|
122
|
+
*/
|
123
|
+
switch (extraBytesToRead) {
|
124
|
+
case 5: ch += *source++; ch <<= 6; /* remember, illegal UTF-8 */
|
125
|
+
case 4: ch += *source++; ch <<= 6; /* remember, illegal UTF-8 */
|
126
|
+
case 3: ch += *source++; ch <<= 6;
|
127
|
+
case 2: ch += *source++; ch <<= 6;
|
128
|
+
case 1: ch += *source++; ch <<= 6;
|
129
|
+
case 0: ch += *source++;
|
130
|
+
}
|
131
|
+
ch -= offsetsFromUTF8[extraBytesToRead];
|
132
|
+
|
133
|
+
if (ch <= UNI_MAX_BMP) { /* Target is a character <= 0xFFFF */
|
134
|
+
/* UTF-16 surrogate values are illegal in UTF-32 */
|
135
|
+
if (ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_LOW_END) {
|
136
|
+
if (flags == strictConversion) {
|
137
|
+
source -= (extraBytesToRead+1); /* return to the illegal value itself */
|
138
|
+
rb_raise(rb_path2class("JSON::GeneratorError"),
|
139
|
+
"source sequence is illegal/malformed");
|
140
|
+
} else {
|
141
|
+
unicode_escape(buffer, UNI_REPLACEMENT_CHAR);
|
142
|
+
}
|
143
|
+
} else {
|
144
|
+
/* normal case */
|
145
|
+
if (ch == '"') {
|
146
|
+
rb_str_buf_cat2(buffer, "\\\"");
|
147
|
+
} else if (ch == '\\') {
|
148
|
+
rb_str_buf_cat2(buffer, "\\\\");
|
149
|
+
} else if (ch == '/') {
|
150
|
+
rb_str_buf_cat2(buffer, "\\/");
|
151
|
+
} else if (ch >= 0x20 && ch <= 0x7f) {
|
152
|
+
rb_str_buf_cat(buffer, (char *) source - 1, 1);
|
153
|
+
} else if (ch == '\n') {
|
154
|
+
rb_str_buf_cat2(buffer, "\\n");
|
155
|
+
} else if (ch == '\r') {
|
156
|
+
rb_str_buf_cat2(buffer, "\\r");
|
157
|
+
} else if (ch == '\t') {
|
158
|
+
rb_str_buf_cat2(buffer, "\\t");
|
159
|
+
} else if (ch == '\f') {
|
160
|
+
rb_str_buf_cat2(buffer, "\\f");
|
161
|
+
} else if (ch == '\b') {
|
162
|
+
rb_str_buf_cat2(buffer, "\\b");
|
163
|
+
} else if (ch < 0x20) {
|
164
|
+
unicode_escape(buffer, (UTF16) ch);
|
165
|
+
} else {
|
166
|
+
unicode_escape(buffer, (UTF16) ch);
|
167
|
+
}
|
168
|
+
}
|
169
|
+
} else if (ch > UNI_MAX_UTF16) {
|
170
|
+
if (flags == strictConversion) {
|
171
|
+
source -= (extraBytesToRead+1); /* return to the start */
|
172
|
+
rb_raise(rb_path2class("JSON::GeneratorError"),
|
173
|
+
"source sequence is illegal/malformed");
|
174
|
+
} else {
|
175
|
+
unicode_escape(buffer, UNI_REPLACEMENT_CHAR);
|
176
|
+
}
|
177
|
+
} else {
|
178
|
+
/* target is a character in range 0xFFFF - 0x10FFFF. */
|
179
|
+
ch -= halfBase;
|
180
|
+
unicode_escape(buffer, (UTF16)((ch >> halfShift) + UNI_SUR_HIGH_START));
|
181
|
+
unicode_escape(buffer, (UTF16)((ch & halfMask) + UNI_SUR_LOW_START));
|
182
|
+
}
|
183
|
+
}
|
184
|
+
}
|
@@ -0,0 +1,40 @@
|
|
1
|
+
#include "ruby.h"
|
2
|
+
|
3
|
+
#ifndef _GENERATOR_UNICODE_H_
|
4
|
+
#define _GENERATOR_UNICODE_H_
|
5
|
+
|
6
|
+
typedef enum {
|
7
|
+
conversionOK = 0, /* conversion successful */
|
8
|
+
sourceExhausted, /* partial character in source, but hit end */
|
9
|
+
targetExhausted, /* insuff. room in target for conversion */
|
10
|
+
sourceIllegal /* source sequence is illegal/malformed */
|
11
|
+
} ConversionResult;
|
12
|
+
|
13
|
+
typedef enum {
|
14
|
+
strictConversion = 0,
|
15
|
+
lenientConversion
|
16
|
+
} ConversionFlags;
|
17
|
+
|
18
|
+
typedef unsigned long UTF32; /* at least 32 bits */
|
19
|
+
typedef unsigned short UTF16; /* at least 16 bits */
|
20
|
+
typedef unsigned char UTF8; /* typically 8 bits */
|
21
|
+
|
22
|
+
#define UNI_REPLACEMENT_CHAR (UTF32)0x0000FFFD
|
23
|
+
#define UNI_MAX_BMP (UTF32)0x0000FFFF
|
24
|
+
#define UNI_MAX_UTF16 (UTF32)0x0010FFFF
|
25
|
+
#define UNI_MAX_UTF32 (UTF32)0x7FFFFFFF
|
26
|
+
#define UNI_MAX_LEGAL_UTF32 (UTF32)0x0010FFFF
|
27
|
+
|
28
|
+
#define UNI_SUR_HIGH_START (UTF32)0xD800
|
29
|
+
#define UNI_SUR_HIGH_END (UTF32)0xDBFF
|
30
|
+
#define UNI_SUR_LOW_START (UTF32)0xDC00
|
31
|
+
#define UNI_SUR_LOW_END (UTF32)0xDFFF
|
32
|
+
|
33
|
+
static const int halfShift = 10; /* used for shifting by 10 bits */
|
34
|
+
|
35
|
+
static const UTF32 halfBase = 0x0010000UL;
|
36
|
+
static const UTF32 halfMask = 0x3FFUL;
|
37
|
+
|
38
|
+
void JSON_convert_UTF8_to_JSON(VALUE buffer, VALUE string, ConversionFlags flags);
|
39
|
+
|
40
|
+
#endif
|
@@ -0,0 +1,149 @@
|
|
1
|
+
|
2
|
+
SHELL = /bin/sh
|
3
|
+
|
4
|
+
#### Start of system configuration section. ####
|
5
|
+
|
6
|
+
srcdir = .
|
7
|
+
topdir = /usr/lib/ruby/1.8/i686-linux
|
8
|
+
hdrdir = $(topdir)
|
9
|
+
VPATH = $(srcdir):$(topdir):$(hdrdir)
|
10
|
+
prefix = $(DESTDIR)/usr
|
11
|
+
exec_prefix = $(prefix)
|
12
|
+
sitedir = $(DESTDIR)/usr/lib/ruby/site_ruby
|
13
|
+
rubylibdir = $(libdir)/ruby/$(ruby_version)
|
14
|
+
docdir = $(datarootdir)/doc/$(PACKAGE)
|
15
|
+
dvidir = $(docdir)
|
16
|
+
datarootdir = $(prefix)/share
|
17
|
+
archdir = $(rubylibdir)/$(arch)
|
18
|
+
sbindir = $(exec_prefix)/sbin
|
19
|
+
psdir = $(docdir)
|
20
|
+
localedir = $(datarootdir)/locale
|
21
|
+
htmldir = $(docdir)
|
22
|
+
datadir = $(DESTDIR)/usr/share
|
23
|
+
includedir = $(prefix)/include
|
24
|
+
infodir = $(DESTDIR)/usr/share/info
|
25
|
+
sysconfdir = $(DESTDIR)/etc
|
26
|
+
mandir = $(DESTDIR)/usr/share/man
|
27
|
+
libdir = $(exec_prefix)/lib
|
28
|
+
sharedstatedir = $(prefix)/com
|
29
|
+
oldincludedir = $(DESTDIR)/usr/include
|
30
|
+
pdfdir = $(docdir)
|
31
|
+
sitearchdir = $(sitelibdir)/$(sitearch)
|
32
|
+
bindir = $(exec_prefix)/bin
|
33
|
+
localstatedir = $(DESTDIR)/var/lib
|
34
|
+
sitelibdir = $(sitedir)/$(ruby_version)
|
35
|
+
libexecdir = $(exec_prefix)/libexec
|
36
|
+
|
37
|
+
CC = i686-pc-linux-gnu-gcc -Wall
|
38
|
+
LIBRUBY = $(LIBRUBY_SO)
|
39
|
+
LIBRUBY_A = lib$(RUBY_SO_NAME)-static.a
|
40
|
+
LIBRUBYARG_SHARED = -Wl,-R -Wl,$(libdir) -L$(libdir) -L. -l$(RUBY_SO_NAME)
|
41
|
+
LIBRUBYARG_STATIC = -l$(RUBY_SO_NAME)-static
|
42
|
+
|
43
|
+
RUBY_EXTCONF_H =
|
44
|
+
CFLAGS = -fPIC -march=pentium4 -O2 -pipe -ggdb -fPIC
|
45
|
+
INCFLAGS = -I. -I$(topdir) -I$(hdrdir) -I$(srcdir)
|
46
|
+
CPPFLAGS =
|
47
|
+
CXXFLAGS = $(CFLAGS)
|
48
|
+
DLDFLAGS =
|
49
|
+
LDSHARED = $(CC) -shared
|
50
|
+
AR = i686-pc-linux-gnu-ar
|
51
|
+
EXEEXT =
|
52
|
+
|
53
|
+
RUBY_INSTALL_NAME = ruby18
|
54
|
+
RUBY_SO_NAME = ruby18
|
55
|
+
arch = i686-linux
|
56
|
+
sitearch = i686-linux
|
57
|
+
ruby_version = 1.8
|
58
|
+
ruby = /usr/bin/ruby18
|
59
|
+
RUBY = $(ruby)
|
60
|
+
RM = rm -f
|
61
|
+
MAKEDIRS = mkdir -p
|
62
|
+
INSTALL = /bin/install -c
|
63
|
+
INSTALL_PROG = $(INSTALL) -m 0755
|
64
|
+
INSTALL_DATA = $(INSTALL) -m 644
|
65
|
+
COPY = cp
|
66
|
+
|
67
|
+
#### End of system configuration section. ####
|
68
|
+
|
69
|
+
preload =
|
70
|
+
|
71
|
+
libpath = $(libdir)
|
72
|
+
LIBPATH = -L'$(libdir)' -Wl,-R'$(libdir)'
|
73
|
+
DEFFILE =
|
74
|
+
|
75
|
+
CLEANFILES =
|
76
|
+
DISTCLEANFILES =
|
77
|
+
|
78
|
+
extout =
|
79
|
+
extout_prefix =
|
80
|
+
target_prefix =
|
81
|
+
LOCAL_LIBS =
|
82
|
+
LIBS = $(LIBRUBYARG_SHARED) -ldl -lcrypt -lm -lc
|
83
|
+
SRCS = parser.c unicode.c
|
84
|
+
OBJS = parser.o unicode.o
|
85
|
+
TARGET = parser
|
86
|
+
DLLIB = $(TARGET).so
|
87
|
+
EXTSTATIC =
|
88
|
+
STATIC_LIB =
|
89
|
+
|
90
|
+
RUBYCOMMONDIR = $(sitedir)$(target_prefix)
|
91
|
+
RUBYLIBDIR = $(sitelibdir)$(target_prefix)
|
92
|
+
RUBYARCHDIR = $(sitearchdir)$(target_prefix)
|
93
|
+
|
94
|
+
TARGET_SO = $(DLLIB)
|
95
|
+
CLEANLIBS = $(TARGET).so $(TARGET).il? $(TARGET).tds $(TARGET).map
|
96
|
+
CLEANOBJS = *.o *.a *.s[ol] *.pdb *.exp *.bak
|
97
|
+
|
98
|
+
all: $(DLLIB)
|
99
|
+
static: $(STATIC_LIB)
|
100
|
+
|
101
|
+
clean:
|
102
|
+
@-$(RM) $(CLEANLIBS) $(CLEANOBJS) $(CLEANFILES)
|
103
|
+
|
104
|
+
distclean: clean
|
105
|
+
@-$(RM) Makefile $(RUBY_EXTCONF_H) conftest.* mkmf.log
|
106
|
+
@-$(RM) core ruby$(EXEEXT) *~ $(DISTCLEANFILES)
|
107
|
+
|
108
|
+
realclean: distclean
|
109
|
+
install: install-so install-rb
|
110
|
+
|
111
|
+
install-so: $(RUBYARCHDIR)
|
112
|
+
install-so: $(RUBYARCHDIR)/$(DLLIB)
|
113
|
+
$(RUBYARCHDIR)/$(DLLIB): $(DLLIB)
|
114
|
+
$(INSTALL_PROG) $(DLLIB) $(RUBYARCHDIR)
|
115
|
+
install-rb: pre-install-rb install-rb-default
|
116
|
+
install-rb-default: pre-install-rb-default
|
117
|
+
pre-install-rb: Makefile
|
118
|
+
pre-install-rb-default: Makefile
|
119
|
+
$(RUBYARCHDIR):
|
120
|
+
$(MAKEDIRS) $@
|
121
|
+
|
122
|
+
site-install: site-install-so site-install-rb
|
123
|
+
site-install-so: install-so
|
124
|
+
site-install-rb: install-rb
|
125
|
+
|
126
|
+
.SUFFIXES: .c .m .cc .cxx .cpp .C .o
|
127
|
+
|
128
|
+
.cc.o:
|
129
|
+
$(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) -c $<
|
130
|
+
|
131
|
+
.cxx.o:
|
132
|
+
$(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) -c $<
|
133
|
+
|
134
|
+
.cpp.o:
|
135
|
+
$(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) -c $<
|
136
|
+
|
137
|
+
.C.o:
|
138
|
+
$(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) -c $<
|
139
|
+
|
140
|
+
.c.o:
|
141
|
+
$(CC) $(INCFLAGS) $(CPPFLAGS) $(CFLAGS) -c $<
|
142
|
+
|
143
|
+
$(DLLIB): $(OBJS)
|
144
|
+
@-$(RM) $@
|
145
|
+
$(LDSHARED) $(DLDFLAGS) $(LIBPATH) -o $@ $(OBJS) $(LOCAL_LIBS) $(LIBS)
|
146
|
+
|
147
|
+
|
148
|
+
|
149
|
+
$(OBJS): ruby.h defines.h
|
@@ -0,0 +1,1551 @@
|
|
1
|
+
#line 1 "parser.rl"
|
2
|
+
/* vim: set cin et sw=4 ts=4: */
|
3
|
+
|
4
|
+
#include "ruby.h"
|
5
|
+
#include "re.h"
|
6
|
+
#include "unicode.h"
|
7
|
+
|
8
|
+
#ifndef swap16
|
9
|
+
#define swap16(x) ((((x)&0xFF)<<8) | (((x)>>8)&0xFF))
|
10
|
+
#endif
|
11
|
+
|
12
|
+
#define EVIL 0x666
|
13
|
+
|
14
|
+
static VALUE mJSON, mExt, cParser, eParserError;
|
15
|
+
|
16
|
+
static ID i_json_creatable_p, i_json_create, i_create_id, i_chr;
|
17
|
+
|
18
|
+
typedef struct JSON_ParserStruct {
|
19
|
+
VALUE Vsource;
|
20
|
+
char *source;
|
21
|
+
long len;
|
22
|
+
char *memo;
|
23
|
+
VALUE create_id;
|
24
|
+
} JSON_Parser;
|
25
|
+
|
26
|
+
static char *JSON_parse_object(JSON_Parser *json, char *p, char *pe, VALUE *result);
|
27
|
+
static char *JSON_parse_array(JSON_Parser *json, char *p, char *pe, VALUE *result);
|
28
|
+
static char *JSON_parse_value(JSON_Parser *json, char *p, char *pe, VALUE *result);
|
29
|
+
static char *JSON_parse_string(JSON_Parser *json, char *p, char *pe, VALUE *result);
|
30
|
+
static char *JSON_parse_integer(JSON_Parser *json, char *p, char *pe, VALUE *result);
|
31
|
+
static char *JSON_parse_float(JSON_Parser *json, char *p, char *pe, VALUE *result);
|
32
|
+
|
33
|
+
#define GET_STRUCT \
|
34
|
+
JSON_Parser *json; \
|
35
|
+
Data_Get_Struct(self, JSON_Parser, json);
|
36
|
+
|
37
|
+
#line 59 "parser.rl"
|
38
|
+
|
39
|
+
|
40
|
+
|
41
|
+
#line 42 "parser.c"
|
42
|
+
static const int JSON_object_start = 0;
|
43
|
+
|
44
|
+
static const int JSON_object_first_final = 27;
|
45
|
+
|
46
|
+
static const int JSON_object_error = 1;
|
47
|
+
|
48
|
+
#line 92 "parser.rl"
|
49
|
+
|
50
|
+
|
51
|
+
static char *JSON_parse_object(JSON_Parser *json, char *p, char *pe, VALUE *result)
|
52
|
+
{
|
53
|
+
int cs = EVIL;
|
54
|
+
VALUE last_name = Qnil;
|
55
|
+
*result = rb_hash_new();
|
56
|
+
|
57
|
+
|
58
|
+
#line 59 "parser.c"
|
59
|
+
{
|
60
|
+
cs = JSON_object_start;
|
61
|
+
}
|
62
|
+
#line 101 "parser.rl"
|
63
|
+
|
64
|
+
#line 65 "parser.c"
|
65
|
+
{
|
66
|
+
if ( p == pe )
|
67
|
+
goto _out;
|
68
|
+
switch ( cs )
|
69
|
+
{
|
70
|
+
case 0:
|
71
|
+
if ( (*p) == 123 )
|
72
|
+
goto st2;
|
73
|
+
goto st1;
|
74
|
+
st1:
|
75
|
+
goto _out1;
|
76
|
+
st2:
|
77
|
+
if ( ++p == pe )
|
78
|
+
goto _out2;
|
79
|
+
case 2:
|
80
|
+
switch( (*p) ) {
|
81
|
+
case 13: goto st2;
|
82
|
+
case 32: goto st2;
|
83
|
+
case 34: goto tr13;
|
84
|
+
case 47: goto st23;
|
85
|
+
case 125: goto tr10;
|
86
|
+
}
|
87
|
+
if ( 9 <= (*p) && (*p) <= 10 )
|
88
|
+
goto st2;
|
89
|
+
goto st1;
|
90
|
+
tr13:
|
91
|
+
#line 78 "parser.rl"
|
92
|
+
{
|
93
|
+
char *np = JSON_parse_string(json, p, pe, &last_name);
|
94
|
+
if (np == NULL) goto _out3; else {p = (( np))-1;}
|
95
|
+
}
|
96
|
+
goto st3;
|
97
|
+
st3:
|
98
|
+
if ( ++p == pe )
|
99
|
+
goto _out3;
|
100
|
+
case 3:
|
101
|
+
#line 102 "parser.c"
|
102
|
+
switch( (*p) ) {
|
103
|
+
case 13: goto st3;
|
104
|
+
case 32: goto st3;
|
105
|
+
case 47: goto st4;
|
106
|
+
case 58: goto st8;
|
107
|
+
}
|
108
|
+
if ( 9 <= (*p) && (*p) <= 10 )
|
109
|
+
goto st3;
|
110
|
+
goto st1;
|
111
|
+
st4:
|
112
|
+
if ( ++p == pe )
|
113
|
+
goto _out4;
|
114
|
+
case 4:
|
115
|
+
switch( (*p) ) {
|
116
|
+
case 42: goto st5;
|
117
|
+
case 47: goto st7;
|
118
|
+
}
|
119
|
+
goto st1;
|
120
|
+
st5:
|
121
|
+
if ( ++p == pe )
|
122
|
+
goto _out5;
|
123
|
+
case 5:
|
124
|
+
if ( (*p) == 42 )
|
125
|
+
goto st6;
|
126
|
+
goto st5;
|
127
|
+
st6:
|
128
|
+
if ( ++p == pe )
|
129
|
+
goto _out6;
|
130
|
+
case 6:
|
131
|
+
switch( (*p) ) {
|
132
|
+
case 42: goto st6;
|
133
|
+
case 47: goto st3;
|
134
|
+
}
|
135
|
+
goto st5;
|
136
|
+
st7:
|
137
|
+
if ( ++p == pe )
|
138
|
+
goto _out7;
|
139
|
+
case 7:
|
140
|
+
if ( (*p) == 10 )
|
141
|
+
goto st3;
|
142
|
+
goto st7;
|
143
|
+
st8:
|
144
|
+
if ( ++p == pe )
|
145
|
+
goto _out8;
|
146
|
+
case 8:
|
147
|
+
switch( (*p) ) {
|
148
|
+
case 13: goto st8;
|
149
|
+
case 32: goto st8;
|
150
|
+
case 34: goto tr11;
|
151
|
+
case 45: goto tr11;
|
152
|
+
case 47: goto st19;
|
153
|
+
case 91: goto tr11;
|
154
|
+
case 102: goto tr11;
|
155
|
+
case 110: goto tr11;
|
156
|
+
case 116: goto tr11;
|
157
|
+
case 123: goto tr11;
|
158
|
+
}
|
159
|
+
if ( (*p) > 10 ) {
|
160
|
+
if ( 48 <= (*p) && (*p) <= 57 )
|
161
|
+
goto tr11;
|
162
|
+
} else if ( (*p) >= 9 )
|
163
|
+
goto st8;
|
164
|
+
goto st1;
|
165
|
+
tr11:
|
166
|
+
#line 67 "parser.rl"
|
167
|
+
{
|
168
|
+
VALUE v = Qnil;
|
169
|
+
char *np = JSON_parse_value(json, p, pe, &v);
|
170
|
+
if (np == NULL) {
|
171
|
+
goto _out9;
|
172
|
+
} else {
|
173
|
+
rb_hash_aset(*result, last_name, v);
|
174
|
+
{p = (( np))-1;}
|
175
|
+
}
|
176
|
+
}
|
177
|
+
goto st9;
|
178
|
+
st9:
|
179
|
+
if ( ++p == pe )
|
180
|
+
goto _out9;
|
181
|
+
case 9:
|
182
|
+
#line 183 "parser.c"
|
183
|
+
switch( (*p) ) {
|
184
|
+
case 13: goto st9;
|
185
|
+
case 32: goto st9;
|
186
|
+
case 44: goto st10;
|
187
|
+
case 47: goto st15;
|
188
|
+
case 125: goto tr10;
|
189
|
+
}
|
190
|
+
if ( 9 <= (*p) && (*p) <= 10 )
|
191
|
+
goto st9;
|
192
|
+
goto st1;
|
193
|
+
st10:
|
194
|
+
if ( ++p == pe )
|
195
|
+
goto _out10;
|
196
|
+
case 10:
|
197
|
+
switch( (*p) ) {
|
198
|
+
case 13: goto st10;
|
199
|
+
case 32: goto st10;
|
200
|
+
case 34: goto tr13;
|
201
|
+
case 47: goto st11;
|
202
|
+
}
|
203
|
+
if ( 9 <= (*p) && (*p) <= 10 )
|
204
|
+
goto st10;
|
205
|
+
goto st1;
|
206
|
+
st11:
|
207
|
+
if ( ++p == pe )
|
208
|
+
goto _out11;
|
209
|
+
case 11:
|
210
|
+
switch( (*p) ) {
|
211
|
+
case 42: goto st12;
|
212
|
+
case 47: goto st14;
|
213
|
+
}
|
214
|
+
goto st1;
|
215
|
+
st12:
|
216
|
+
if ( ++p == pe )
|
217
|
+
goto _out12;
|
218
|
+
case 12:
|
219
|
+
if ( (*p) == 42 )
|
220
|
+
goto st13;
|
221
|
+
goto st12;
|
222
|
+
st13:
|
223
|
+
if ( ++p == pe )
|
224
|
+
goto _out13;
|
225
|
+
case 13:
|
226
|
+
switch( (*p) ) {
|
227
|
+
case 42: goto st13;
|
228
|
+
case 47: goto st10;
|
229
|
+
}
|
230
|
+
goto st12;
|
231
|
+
st14:
|
232
|
+
if ( ++p == pe )
|
233
|
+
goto _out14;
|
234
|
+
case 14:
|
235
|
+
if ( (*p) == 10 )
|
236
|
+
goto st10;
|
237
|
+
goto st14;
|
238
|
+
st15:
|
239
|
+
if ( ++p == pe )
|
240
|
+
goto _out15;
|
241
|
+
case 15:
|
242
|
+
switch( (*p) ) {
|
243
|
+
case 42: goto st16;
|
244
|
+
case 47: goto st18;
|
245
|
+
}
|
246
|
+
goto st1;
|
247
|
+
st16:
|
248
|
+
if ( ++p == pe )
|
249
|
+
goto _out16;
|
250
|
+
case 16:
|
251
|
+
if ( (*p) == 42 )
|
252
|
+
goto st17;
|
253
|
+
goto st16;
|
254
|
+
st17:
|
255
|
+
if ( ++p == pe )
|
256
|
+
goto _out17;
|
257
|
+
case 17:
|
258
|
+
switch( (*p) ) {
|
259
|
+
case 42: goto st17;
|
260
|
+
case 47: goto st9;
|
261
|
+
}
|
262
|
+
goto st16;
|
263
|
+
st18:
|
264
|
+
if ( ++p == pe )
|
265
|
+
goto _out18;
|
266
|
+
case 18:
|
267
|
+
if ( (*p) == 10 )
|
268
|
+
goto st9;
|
269
|
+
goto st18;
|
270
|
+
tr10:
|
271
|
+
#line 83 "parser.rl"
|
272
|
+
{ goto _out27; }
|
273
|
+
goto st27;
|
274
|
+
st27:
|
275
|
+
if ( ++p == pe )
|
276
|
+
goto _out27;
|
277
|
+
case 27:
|
278
|
+
#line 279 "parser.c"
|
279
|
+
goto st1;
|
280
|
+
st19:
|
281
|
+
if ( ++p == pe )
|
282
|
+
goto _out19;
|
283
|
+
case 19:
|
284
|
+
switch( (*p) ) {
|
285
|
+
case 42: goto st20;
|
286
|
+
case 47: goto st22;
|
287
|
+
}
|
288
|
+
goto st1;
|
289
|
+
st20:
|
290
|
+
if ( ++p == pe )
|
291
|
+
goto _out20;
|
292
|
+
case 20:
|
293
|
+
if ( (*p) == 42 )
|
294
|
+
goto st21;
|
295
|
+
goto st20;
|
296
|
+
st21:
|
297
|
+
if ( ++p == pe )
|
298
|
+
goto _out21;
|
299
|
+
case 21:
|
300
|
+
switch( (*p) ) {
|
301
|
+
case 42: goto st21;
|
302
|
+
case 47: goto st8;
|
303
|
+
}
|
304
|
+
goto st20;
|
305
|
+
st22:
|
306
|
+
if ( ++p == pe )
|
307
|
+
goto _out22;
|
308
|
+
case 22:
|
309
|
+
if ( (*p) == 10 )
|
310
|
+
goto st8;
|
311
|
+
goto st22;
|
312
|
+
st23:
|
313
|
+
if ( ++p == pe )
|
314
|
+
goto _out23;
|
315
|
+
case 23:
|
316
|
+
switch( (*p) ) {
|
317
|
+
case 42: goto st24;
|
318
|
+
case 47: goto st26;
|
319
|
+
}
|
320
|
+
goto st1;
|
321
|
+
st24:
|
322
|
+
if ( ++p == pe )
|
323
|
+
goto _out24;
|
324
|
+
case 24:
|
325
|
+
if ( (*p) == 42 )
|
326
|
+
goto st25;
|
327
|
+
goto st24;
|
328
|
+
st25:
|
329
|
+
if ( ++p == pe )
|
330
|
+
goto _out25;
|
331
|
+
case 25:
|
332
|
+
switch( (*p) ) {
|
333
|
+
case 42: goto st25;
|
334
|
+
case 47: goto st2;
|
335
|
+
}
|
336
|
+
goto st24;
|
337
|
+
st26:
|
338
|
+
if ( ++p == pe )
|
339
|
+
goto _out26;
|
340
|
+
case 26:
|
341
|
+
if ( (*p) == 10 )
|
342
|
+
goto st2;
|
343
|
+
goto st26;
|
344
|
+
}
|
345
|
+
_out1: cs = 1; goto _out;
|
346
|
+
_out2: cs = 2; goto _out;
|
347
|
+
_out3: cs = 3; goto _out;
|
348
|
+
_out4: cs = 4; goto _out;
|
349
|
+
_out5: cs = 5; goto _out;
|
350
|
+
_out6: cs = 6; goto _out;
|
351
|
+
_out7: cs = 7; goto _out;
|
352
|
+
_out8: cs = 8; goto _out;
|
353
|
+
_out9: cs = 9; goto _out;
|
354
|
+
_out10: cs = 10; goto _out;
|
355
|
+
_out11: cs = 11; goto _out;
|
356
|
+
_out12: cs = 12; goto _out;
|
357
|
+
_out13: cs = 13; goto _out;
|
358
|
+
_out14: cs = 14; goto _out;
|
359
|
+
_out15: cs = 15; goto _out;
|
360
|
+
_out16: cs = 16; goto _out;
|
361
|
+
_out17: cs = 17; goto _out;
|
362
|
+
_out18: cs = 18; goto _out;
|
363
|
+
_out27: cs = 27; goto _out;
|
364
|
+
_out19: cs = 19; goto _out;
|
365
|
+
_out20: cs = 20; goto _out;
|
366
|
+
_out21: cs = 21; goto _out;
|
367
|
+
_out22: cs = 22; goto _out;
|
368
|
+
_out23: cs = 23; goto _out;
|
369
|
+
_out24: cs = 24; goto _out;
|
370
|
+
_out25: cs = 25; goto _out;
|
371
|
+
_out26: cs = 26; goto _out;
|
372
|
+
|
373
|
+
_out: {}
|
374
|
+
}
|
375
|
+
#line 102 "parser.rl"
|
376
|
+
|
377
|
+
if (cs >= JSON_object_first_final) {
|
378
|
+
VALUE klassname = rb_hash_aref(*result, json->create_id);
|
379
|
+
if (!NIL_P(klassname)) {
|
380
|
+
VALUE klass = rb_path2class(StringValueCStr(klassname));
|
381
|
+
if RTEST(rb_funcall(klass, i_json_creatable_p, 0)) {
|
382
|
+
*result = rb_funcall(klass, i_json_create, 1, *result);
|
383
|
+
}
|
384
|
+
}
|
385
|
+
return p + 1;
|
386
|
+
} else {
|
387
|
+
return NULL;
|
388
|
+
}
|
389
|
+
}
|
390
|
+
|
391
|
+
|
392
|
+
#line 393 "parser.c"
|
393
|
+
static const int JSON_value_start = 0;
|
394
|
+
|
395
|
+
static const int JSON_value_first_final = 12;
|
396
|
+
|
397
|
+
static const int JSON_value_error = 1;
|
398
|
+
|
399
|
+
#line 167 "parser.rl"
|
400
|
+
|
401
|
+
|
402
|
+
static char *JSON_parse_value(JSON_Parser *json, char *p, char *pe, VALUE *result)
|
403
|
+
{
|
404
|
+
int cs = EVIL;
|
405
|
+
|
406
|
+
|
407
|
+
#line 408 "parser.c"
|
408
|
+
{
|
409
|
+
cs = JSON_value_start;
|
410
|
+
}
|
411
|
+
#line 174 "parser.rl"
|
412
|
+
|
413
|
+
#line 414 "parser.c"
|
414
|
+
{
|
415
|
+
if ( p == pe )
|
416
|
+
goto _out;
|
417
|
+
switch ( cs )
|
418
|
+
{
|
419
|
+
case 0:
|
420
|
+
switch( (*p) ) {
|
421
|
+
case 34: goto tr9;
|
422
|
+
case 45: goto tr10;
|
423
|
+
case 91: goto tr11;
|
424
|
+
case 102: goto st2;
|
425
|
+
case 110: goto st6;
|
426
|
+
case 116: goto st9;
|
427
|
+
case 123: goto tr15;
|
428
|
+
}
|
429
|
+
if ( 48 <= (*p) && (*p) <= 57 )
|
430
|
+
goto tr10;
|
431
|
+
goto st1;
|
432
|
+
st1:
|
433
|
+
goto _out1;
|
434
|
+
tr5:
|
435
|
+
#line 123 "parser.rl"
|
436
|
+
{
|
437
|
+
*result = Qnil;
|
438
|
+
}
|
439
|
+
goto st12;
|
440
|
+
tr6:
|
441
|
+
#line 126 "parser.rl"
|
442
|
+
{
|
443
|
+
*result = Qfalse;
|
444
|
+
}
|
445
|
+
goto st12;
|
446
|
+
tr7:
|
447
|
+
#line 129 "parser.rl"
|
448
|
+
{
|
449
|
+
*result = Qtrue;
|
450
|
+
}
|
451
|
+
goto st12;
|
452
|
+
tr9:
|
453
|
+
#line 132 "parser.rl"
|
454
|
+
{
|
455
|
+
char *np = JSON_parse_string(json, p, pe, result);
|
456
|
+
if (np == NULL) goto _out12; else {p = (( np))-1;}
|
457
|
+
}
|
458
|
+
goto st12;
|
459
|
+
tr10:
|
460
|
+
#line 137 "parser.rl"
|
461
|
+
{
|
462
|
+
char *np;
|
463
|
+
np = JSON_parse_float(json, p, pe, result);
|
464
|
+
if (np != NULL) {p = (( np))-1;}
|
465
|
+
np = JSON_parse_integer(json, p, pe, result);
|
466
|
+
if (np != NULL) {p = (( np))-1;}
|
467
|
+
goto _out12;
|
468
|
+
}
|
469
|
+
goto st12;
|
470
|
+
tr11:
|
471
|
+
#line 146 "parser.rl"
|
472
|
+
{
|
473
|
+
char *np = JSON_parse_array(json, p, pe, result);
|
474
|
+
if (np == NULL) goto _out12; else {p = (( np))-1;}
|
475
|
+
}
|
476
|
+
goto st12;
|
477
|
+
tr15:
|
478
|
+
#line 151 "parser.rl"
|
479
|
+
{
|
480
|
+
char *np = JSON_parse_object(json, p, pe, result);
|
481
|
+
if (np == NULL) goto _out12; else {p = (( np))-1;}
|
482
|
+
}
|
483
|
+
goto st12;
|
484
|
+
st12:
|
485
|
+
if ( ++p == pe )
|
486
|
+
goto _out12;
|
487
|
+
case 12:
|
488
|
+
#line 156 "parser.rl"
|
489
|
+
{ goto _out12; }
|
490
|
+
#line 491 "parser.c"
|
491
|
+
goto st1;
|
492
|
+
st2:
|
493
|
+
if ( ++p == pe )
|
494
|
+
goto _out2;
|
495
|
+
case 2:
|
496
|
+
if ( (*p) == 97 )
|
497
|
+
goto st3;
|
498
|
+
goto st1;
|
499
|
+
st3:
|
500
|
+
if ( ++p == pe )
|
501
|
+
goto _out3;
|
502
|
+
case 3:
|
503
|
+
if ( (*p) == 108 )
|
504
|
+
goto st4;
|
505
|
+
goto st1;
|
506
|
+
st4:
|
507
|
+
if ( ++p == pe )
|
508
|
+
goto _out4;
|
509
|
+
case 4:
|
510
|
+
if ( (*p) == 115 )
|
511
|
+
goto st5;
|
512
|
+
goto st1;
|
513
|
+
st5:
|
514
|
+
if ( ++p == pe )
|
515
|
+
goto _out5;
|
516
|
+
case 5:
|
517
|
+
if ( (*p) == 101 )
|
518
|
+
goto tr6;
|
519
|
+
goto st1;
|
520
|
+
st6:
|
521
|
+
if ( ++p == pe )
|
522
|
+
goto _out6;
|
523
|
+
case 6:
|
524
|
+
if ( (*p) == 117 )
|
525
|
+
goto st7;
|
526
|
+
goto st1;
|
527
|
+
st7:
|
528
|
+
if ( ++p == pe )
|
529
|
+
goto _out7;
|
530
|
+
case 7:
|
531
|
+
if ( (*p) == 108 )
|
532
|
+
goto st8;
|
533
|
+
goto st1;
|
534
|
+
st8:
|
535
|
+
if ( ++p == pe )
|
536
|
+
goto _out8;
|
537
|
+
case 8:
|
538
|
+
if ( (*p) == 108 )
|
539
|
+
goto tr5;
|
540
|
+
goto st1;
|
541
|
+
st9:
|
542
|
+
if ( ++p == pe )
|
543
|
+
goto _out9;
|
544
|
+
case 9:
|
545
|
+
if ( (*p) == 114 )
|
546
|
+
goto st10;
|
547
|
+
goto st1;
|
548
|
+
st10:
|
549
|
+
if ( ++p == pe )
|
550
|
+
goto _out10;
|
551
|
+
case 10:
|
552
|
+
if ( (*p) == 117 )
|
553
|
+
goto st11;
|
554
|
+
goto st1;
|
555
|
+
st11:
|
556
|
+
if ( ++p == pe )
|
557
|
+
goto _out11;
|
558
|
+
case 11:
|
559
|
+
if ( (*p) == 101 )
|
560
|
+
goto tr7;
|
561
|
+
goto st1;
|
562
|
+
}
|
563
|
+
_out1: cs = 1; goto _out;
|
564
|
+
_out12: cs = 12; goto _out;
|
565
|
+
_out2: cs = 2; goto _out;
|
566
|
+
_out3: cs = 3; goto _out;
|
567
|
+
_out4: cs = 4; goto _out;
|
568
|
+
_out5: cs = 5; goto _out;
|
569
|
+
_out6: cs = 6; goto _out;
|
570
|
+
_out7: cs = 7; goto _out;
|
571
|
+
_out8: cs = 8; goto _out;
|
572
|
+
_out9: cs = 9; goto _out;
|
573
|
+
_out10: cs = 10; goto _out;
|
574
|
+
_out11: cs = 11; goto _out;
|
575
|
+
|
576
|
+
_out: {}
|
577
|
+
}
|
578
|
+
#line 175 "parser.rl"
|
579
|
+
|
580
|
+
if (cs >= JSON_value_first_final) {
|
581
|
+
return p;
|
582
|
+
} else {
|
583
|
+
return NULL;
|
584
|
+
}
|
585
|
+
}
|
586
|
+
|
587
|
+
|
588
|
+
#line 589 "parser.c"
|
589
|
+
static const int JSON_integer_start = 0;
|
590
|
+
|
591
|
+
static const int JSON_integer_first_final = 5;
|
592
|
+
|
593
|
+
static const int JSON_integer_error = 1;
|
594
|
+
|
595
|
+
#line 191 "parser.rl"
|
596
|
+
|
597
|
+
|
598
|
+
static char *JSON_parse_integer(JSON_Parser *json, char *p, char *pe, VALUE *result)
|
599
|
+
{
|
600
|
+
int cs = EVIL;
|
601
|
+
|
602
|
+
|
603
|
+
#line 604 "parser.c"
|
604
|
+
{
|
605
|
+
cs = JSON_integer_start;
|
606
|
+
}
|
607
|
+
#line 198 "parser.rl"
|
608
|
+
json->memo = p;
|
609
|
+
|
610
|
+
#line 611 "parser.c"
|
611
|
+
{
|
612
|
+
if ( p == pe )
|
613
|
+
goto _out;
|
614
|
+
switch ( cs )
|
615
|
+
{
|
616
|
+
case 0:
|
617
|
+
switch( (*p) ) {
|
618
|
+
case 45: goto st2;
|
619
|
+
case 48: goto st3;
|
620
|
+
}
|
621
|
+
if ( 49 <= (*p) && (*p) <= 57 )
|
622
|
+
goto st4;
|
623
|
+
goto st1;
|
624
|
+
st1:
|
625
|
+
goto _out1;
|
626
|
+
st2:
|
627
|
+
if ( ++p == pe )
|
628
|
+
goto _out2;
|
629
|
+
case 2:
|
630
|
+
if ( (*p) == 48 )
|
631
|
+
goto st3;
|
632
|
+
if ( 49 <= (*p) && (*p) <= 57 )
|
633
|
+
goto st4;
|
634
|
+
goto st1;
|
635
|
+
st3:
|
636
|
+
if ( ++p == pe )
|
637
|
+
goto _out3;
|
638
|
+
case 3:
|
639
|
+
if ( 48 <= (*p) && (*p) <= 57 )
|
640
|
+
goto st1;
|
641
|
+
goto tr4;
|
642
|
+
tr4:
|
643
|
+
#line 188 "parser.rl"
|
644
|
+
{ goto _out5; }
|
645
|
+
goto st5;
|
646
|
+
st5:
|
647
|
+
if ( ++p == pe )
|
648
|
+
goto _out5;
|
649
|
+
case 5:
|
650
|
+
#line 651 "parser.c"
|
651
|
+
goto st1;
|
652
|
+
st4:
|
653
|
+
if ( ++p == pe )
|
654
|
+
goto _out4;
|
655
|
+
case 4:
|
656
|
+
if ( 48 <= (*p) && (*p) <= 57 )
|
657
|
+
goto st4;
|
658
|
+
goto tr4;
|
659
|
+
}
|
660
|
+
_out1: cs = 1; goto _out;
|
661
|
+
_out2: cs = 2; goto _out;
|
662
|
+
_out3: cs = 3; goto _out;
|
663
|
+
_out5: cs = 5; goto _out;
|
664
|
+
_out4: cs = 4; goto _out;
|
665
|
+
|
666
|
+
_out: {}
|
667
|
+
}
|
668
|
+
#line 200 "parser.rl"
|
669
|
+
|
670
|
+
if (cs >= JSON_integer_first_final) {
|
671
|
+
long len = p - json->memo;
|
672
|
+
*result = rb_Integer(rb_str_new(json->memo, len));
|
673
|
+
return p + 1;
|
674
|
+
} else {
|
675
|
+
return NULL;
|
676
|
+
}
|
677
|
+
}
|
678
|
+
|
679
|
+
|
680
|
+
#line 681 "parser.c"
|
681
|
+
static const int JSON_float_start = 0;
|
682
|
+
|
683
|
+
static const int JSON_float_first_final = 10;
|
684
|
+
|
685
|
+
static const int JSON_float_error = 1;
|
686
|
+
|
687
|
+
#line 222 "parser.rl"
|
688
|
+
|
689
|
+
|
690
|
+
static char *JSON_parse_float(JSON_Parser *json, char *p, char *pe, VALUE *result)
|
691
|
+
{
|
692
|
+
int cs = EVIL;
|
693
|
+
|
694
|
+
|
695
|
+
#line 696 "parser.c"
|
696
|
+
{
|
697
|
+
cs = JSON_float_start;
|
698
|
+
}
|
699
|
+
#line 229 "parser.rl"
|
700
|
+
json->memo = p;
|
701
|
+
|
702
|
+
#line 703 "parser.c"
|
703
|
+
{
|
704
|
+
if ( p == pe )
|
705
|
+
goto _out;
|
706
|
+
switch ( cs )
|
707
|
+
{
|
708
|
+
case 0:
|
709
|
+
switch( (*p) ) {
|
710
|
+
case 45: goto st2;
|
711
|
+
case 48: goto st3;
|
712
|
+
}
|
713
|
+
if ( 49 <= (*p) && (*p) <= 57 )
|
714
|
+
goto st9;
|
715
|
+
goto st1;
|
716
|
+
st1:
|
717
|
+
goto _out1;
|
718
|
+
st2:
|
719
|
+
if ( ++p == pe )
|
720
|
+
goto _out2;
|
721
|
+
case 2:
|
722
|
+
if ( (*p) == 48 )
|
723
|
+
goto st3;
|
724
|
+
if ( 49 <= (*p) && (*p) <= 57 )
|
725
|
+
goto st9;
|
726
|
+
goto st1;
|
727
|
+
st3:
|
728
|
+
if ( ++p == pe )
|
729
|
+
goto _out3;
|
730
|
+
case 3:
|
731
|
+
if ( (*p) == 46 )
|
732
|
+
goto st4;
|
733
|
+
goto st1;
|
734
|
+
st4:
|
735
|
+
if ( ++p == pe )
|
736
|
+
goto _out4;
|
737
|
+
case 4:
|
738
|
+
if ( 48 <= (*p) && (*p) <= 57 )
|
739
|
+
goto st5;
|
740
|
+
goto st1;
|
741
|
+
st5:
|
742
|
+
if ( ++p == pe )
|
743
|
+
goto _out5;
|
744
|
+
case 5:
|
745
|
+
switch( (*p) ) {
|
746
|
+
case 69: goto st6;
|
747
|
+
case 101: goto st6;
|
748
|
+
}
|
749
|
+
if ( (*p) > 46 ) {
|
750
|
+
if ( 48 <= (*p) && (*p) <= 57 )
|
751
|
+
goto st5;
|
752
|
+
} else if ( (*p) >= 45 )
|
753
|
+
goto st1;
|
754
|
+
goto tr8;
|
755
|
+
tr8:
|
756
|
+
#line 216 "parser.rl"
|
757
|
+
{ goto _out10; }
|
758
|
+
goto st10;
|
759
|
+
st10:
|
760
|
+
if ( ++p == pe )
|
761
|
+
goto _out10;
|
762
|
+
case 10:
|
763
|
+
#line 764 "parser.c"
|
764
|
+
goto st1;
|
765
|
+
st6:
|
766
|
+
if ( ++p == pe )
|
767
|
+
goto _out6;
|
768
|
+
case 6:
|
769
|
+
switch( (*p) ) {
|
770
|
+
case 43: goto st7;
|
771
|
+
case 45: goto st7;
|
772
|
+
}
|
773
|
+
if ( 48 <= (*p) && (*p) <= 57 )
|
774
|
+
goto st8;
|
775
|
+
goto st1;
|
776
|
+
st7:
|
777
|
+
if ( ++p == pe )
|
778
|
+
goto _out7;
|
779
|
+
case 7:
|
780
|
+
if ( 48 <= (*p) && (*p) <= 57 )
|
781
|
+
goto st8;
|
782
|
+
goto st1;
|
783
|
+
st8:
|
784
|
+
if ( ++p == pe )
|
785
|
+
goto _out8;
|
786
|
+
case 8:
|
787
|
+
switch( (*p) ) {
|
788
|
+
case 69: goto st1;
|
789
|
+
case 101: goto st1;
|
790
|
+
}
|
791
|
+
if ( (*p) > 46 ) {
|
792
|
+
if ( 48 <= (*p) && (*p) <= 57 )
|
793
|
+
goto st8;
|
794
|
+
} else if ( (*p) >= 45 )
|
795
|
+
goto st1;
|
796
|
+
goto tr8;
|
797
|
+
st9:
|
798
|
+
if ( ++p == pe )
|
799
|
+
goto _out9;
|
800
|
+
case 9:
|
801
|
+
switch( (*p) ) {
|
802
|
+
case 46: goto st4;
|
803
|
+
case 69: goto st6;
|
804
|
+
case 101: goto st6;
|
805
|
+
}
|
806
|
+
if ( 48 <= (*p) && (*p) <= 57 )
|
807
|
+
goto st9;
|
808
|
+
goto st1;
|
809
|
+
}
|
810
|
+
_out1: cs = 1; goto _out;
|
811
|
+
_out2: cs = 2; goto _out;
|
812
|
+
_out3: cs = 3; goto _out;
|
813
|
+
_out4: cs = 4; goto _out;
|
814
|
+
_out5: cs = 5; goto _out;
|
815
|
+
_out10: cs = 10; goto _out;
|
816
|
+
_out6: cs = 6; goto _out;
|
817
|
+
_out7: cs = 7; goto _out;
|
818
|
+
_out8: cs = 8; goto _out;
|
819
|
+
_out9: cs = 9; goto _out;
|
820
|
+
|
821
|
+
_out: {}
|
822
|
+
}
|
823
|
+
#line 231 "parser.rl"
|
824
|
+
|
825
|
+
if (cs >= JSON_float_first_final) {
|
826
|
+
long len = p - json->memo;
|
827
|
+
*result = rb_Float(rb_str_new(json->memo, len));
|
828
|
+
return p + 1;
|
829
|
+
} else {
|
830
|
+
return NULL;
|
831
|
+
}
|
832
|
+
}
|
833
|
+
|
834
|
+
|
835
|
+
|
836
|
+
#line 837 "parser.c"
|
837
|
+
static const int JSON_array_start = 0;
|
838
|
+
|
839
|
+
static const int JSON_array_first_final = 17;
|
840
|
+
|
841
|
+
static const int JSON_array_error = 1;
|
842
|
+
|
843
|
+
#line 267 "parser.rl"
|
844
|
+
|
845
|
+
|
846
|
+
static char *JSON_parse_array(JSON_Parser *json, char *p, char *pe, VALUE *result)
|
847
|
+
{
|
848
|
+
int cs = EVIL;
|
849
|
+
*result = rb_ary_new();
|
850
|
+
|
851
|
+
|
852
|
+
#line 853 "parser.c"
|
853
|
+
{
|
854
|
+
cs = JSON_array_start;
|
855
|
+
}
|
856
|
+
#line 275 "parser.rl"
|
857
|
+
|
858
|
+
#line 859 "parser.c"
|
859
|
+
{
|
860
|
+
if ( p == pe )
|
861
|
+
goto _out;
|
862
|
+
switch ( cs )
|
863
|
+
{
|
864
|
+
case 0:
|
865
|
+
if ( (*p) == 91 )
|
866
|
+
goto st2;
|
867
|
+
goto st1;
|
868
|
+
st1:
|
869
|
+
goto _out1;
|
870
|
+
st2:
|
871
|
+
if ( ++p == pe )
|
872
|
+
goto _out2;
|
873
|
+
case 2:
|
874
|
+
switch( (*p) ) {
|
875
|
+
case 13: goto st2;
|
876
|
+
case 32: goto st2;
|
877
|
+
case 34: goto tr8;
|
878
|
+
case 45: goto tr8;
|
879
|
+
case 47: goto st13;
|
880
|
+
case 91: goto tr8;
|
881
|
+
case 93: goto tr7;
|
882
|
+
case 102: goto tr8;
|
883
|
+
case 110: goto tr8;
|
884
|
+
case 116: goto tr8;
|
885
|
+
case 123: goto tr8;
|
886
|
+
}
|
887
|
+
if ( (*p) > 10 ) {
|
888
|
+
if ( 48 <= (*p) && (*p) <= 57 )
|
889
|
+
goto tr8;
|
890
|
+
} else if ( (*p) >= 9 )
|
891
|
+
goto st2;
|
892
|
+
goto st1;
|
893
|
+
tr8:
|
894
|
+
#line 248 "parser.rl"
|
895
|
+
{
|
896
|
+
VALUE v = Qnil;
|
897
|
+
char *np = JSON_parse_value(json, p, pe, &v);
|
898
|
+
if (np == NULL) {
|
899
|
+
goto _out3;
|
900
|
+
} else {
|
901
|
+
rb_ary_push(*result, v);
|
902
|
+
{p = (( np))-1;}
|
903
|
+
}
|
904
|
+
}
|
905
|
+
goto st3;
|
906
|
+
st3:
|
907
|
+
if ( ++p == pe )
|
908
|
+
goto _out3;
|
909
|
+
case 3:
|
910
|
+
#line 911 "parser.c"
|
911
|
+
switch( (*p) ) {
|
912
|
+
case 13: goto st3;
|
913
|
+
case 32: goto st3;
|
914
|
+
case 44: goto st4;
|
915
|
+
case 47: goto st9;
|
916
|
+
case 93: goto tr7;
|
917
|
+
}
|
918
|
+
if ( 9 <= (*p) && (*p) <= 10 )
|
919
|
+
goto st3;
|
920
|
+
goto st1;
|
921
|
+
st4:
|
922
|
+
if ( ++p == pe )
|
923
|
+
goto _out4;
|
924
|
+
case 4:
|
925
|
+
switch( (*p) ) {
|
926
|
+
case 13: goto st4;
|
927
|
+
case 32: goto st4;
|
928
|
+
case 34: goto tr8;
|
929
|
+
case 45: goto tr8;
|
930
|
+
case 47: goto st5;
|
931
|
+
case 91: goto tr8;
|
932
|
+
case 102: goto tr8;
|
933
|
+
case 110: goto tr8;
|
934
|
+
case 116: goto tr8;
|
935
|
+
case 123: goto tr8;
|
936
|
+
}
|
937
|
+
if ( (*p) > 10 ) {
|
938
|
+
if ( 48 <= (*p) && (*p) <= 57 )
|
939
|
+
goto tr8;
|
940
|
+
} else if ( (*p) >= 9 )
|
941
|
+
goto st4;
|
942
|
+
goto st1;
|
943
|
+
st5:
|
944
|
+
if ( ++p == pe )
|
945
|
+
goto _out5;
|
946
|
+
case 5:
|
947
|
+
switch( (*p) ) {
|
948
|
+
case 42: goto st6;
|
949
|
+
case 47: goto st8;
|
950
|
+
}
|
951
|
+
goto st1;
|
952
|
+
st6:
|
953
|
+
if ( ++p == pe )
|
954
|
+
goto _out6;
|
955
|
+
case 6:
|
956
|
+
if ( (*p) == 42 )
|
957
|
+
goto st7;
|
958
|
+
goto st6;
|
959
|
+
st7:
|
960
|
+
if ( ++p == pe )
|
961
|
+
goto _out7;
|
962
|
+
case 7:
|
963
|
+
switch( (*p) ) {
|
964
|
+
case 42: goto st7;
|
965
|
+
case 47: goto st4;
|
966
|
+
}
|
967
|
+
goto st6;
|
968
|
+
st8:
|
969
|
+
if ( ++p == pe )
|
970
|
+
goto _out8;
|
971
|
+
case 8:
|
972
|
+
if ( (*p) == 10 )
|
973
|
+
goto st4;
|
974
|
+
goto st8;
|
975
|
+
st9:
|
976
|
+
if ( ++p == pe )
|
977
|
+
goto _out9;
|
978
|
+
case 9:
|
979
|
+
switch( (*p) ) {
|
980
|
+
case 42: goto st10;
|
981
|
+
case 47: goto st12;
|
982
|
+
}
|
983
|
+
goto st1;
|
984
|
+
st10:
|
985
|
+
if ( ++p == pe )
|
986
|
+
goto _out10;
|
987
|
+
case 10:
|
988
|
+
if ( (*p) == 42 )
|
989
|
+
goto st11;
|
990
|
+
goto st10;
|
991
|
+
st11:
|
992
|
+
if ( ++p == pe )
|
993
|
+
goto _out11;
|
994
|
+
case 11:
|
995
|
+
switch( (*p) ) {
|
996
|
+
case 42: goto st11;
|
997
|
+
case 47: goto st3;
|
998
|
+
}
|
999
|
+
goto st10;
|
1000
|
+
st12:
|
1001
|
+
if ( ++p == pe )
|
1002
|
+
goto _out12;
|
1003
|
+
case 12:
|
1004
|
+
if ( (*p) == 10 )
|
1005
|
+
goto st3;
|
1006
|
+
goto st12;
|
1007
|
+
tr7:
|
1008
|
+
#line 259 "parser.rl"
|
1009
|
+
{ goto _out17; }
|
1010
|
+
goto st17;
|
1011
|
+
st17:
|
1012
|
+
if ( ++p == pe )
|
1013
|
+
goto _out17;
|
1014
|
+
case 17:
|
1015
|
+
#line 1016 "parser.c"
|
1016
|
+
goto st1;
|
1017
|
+
st13:
|
1018
|
+
if ( ++p == pe )
|
1019
|
+
goto _out13;
|
1020
|
+
case 13:
|
1021
|
+
switch( (*p) ) {
|
1022
|
+
case 42: goto st14;
|
1023
|
+
case 47: goto st16;
|
1024
|
+
}
|
1025
|
+
goto st1;
|
1026
|
+
st14:
|
1027
|
+
if ( ++p == pe )
|
1028
|
+
goto _out14;
|
1029
|
+
case 14:
|
1030
|
+
if ( (*p) == 42 )
|
1031
|
+
goto st15;
|
1032
|
+
goto st14;
|
1033
|
+
st15:
|
1034
|
+
if ( ++p == pe )
|
1035
|
+
goto _out15;
|
1036
|
+
case 15:
|
1037
|
+
switch( (*p) ) {
|
1038
|
+
case 42: goto st15;
|
1039
|
+
case 47: goto st2;
|
1040
|
+
}
|
1041
|
+
goto st14;
|
1042
|
+
st16:
|
1043
|
+
if ( ++p == pe )
|
1044
|
+
goto _out16;
|
1045
|
+
case 16:
|
1046
|
+
if ( (*p) == 10 )
|
1047
|
+
goto st2;
|
1048
|
+
goto st16;
|
1049
|
+
}
|
1050
|
+
_out1: cs = 1; goto _out;
|
1051
|
+
_out2: cs = 2; goto _out;
|
1052
|
+
_out3: cs = 3; goto _out;
|
1053
|
+
_out4: cs = 4; goto _out;
|
1054
|
+
_out5: cs = 5; goto _out;
|
1055
|
+
_out6: cs = 6; goto _out;
|
1056
|
+
_out7: cs = 7; goto _out;
|
1057
|
+
_out8: cs = 8; goto _out;
|
1058
|
+
_out9: cs = 9; goto _out;
|
1059
|
+
_out10: cs = 10; goto _out;
|
1060
|
+
_out11: cs = 11; goto _out;
|
1061
|
+
_out12: cs = 12; goto _out;
|
1062
|
+
_out17: cs = 17; goto _out;
|
1063
|
+
_out13: cs = 13; goto _out;
|
1064
|
+
_out14: cs = 14; goto _out;
|
1065
|
+
_out15: cs = 15; goto _out;
|
1066
|
+
_out16: cs = 16; goto _out;
|
1067
|
+
|
1068
|
+
_out: {}
|
1069
|
+
}
|
1070
|
+
#line 276 "parser.rl"
|
1071
|
+
|
1072
|
+
if(cs >= JSON_array_first_final) {
|
1073
|
+
return p + 1;
|
1074
|
+
} else {
|
1075
|
+
rb_raise(eParserError, "unexpected token at '%s'", p);
|
1076
|
+
}
|
1077
|
+
}
|
1078
|
+
|
1079
|
+
static VALUE json_string_escape(char *p, char *pe)
|
1080
|
+
{
|
1081
|
+
VALUE result = rb_str_buf_new(pe - p + 1);
|
1082
|
+
|
1083
|
+
while (p < pe) {
|
1084
|
+
if (*p == '\\') {
|
1085
|
+
p++;
|
1086
|
+
if (p >= pe) return Qnil; /* raise an exception later, \ at end */
|
1087
|
+
switch (*p) {
|
1088
|
+
case '"':
|
1089
|
+
case '\\':
|
1090
|
+
rb_str_buf_cat(result, p, 1);
|
1091
|
+
p++;
|
1092
|
+
break;
|
1093
|
+
case 'b':
|
1094
|
+
rb_str_buf_cat2(result, "\b");
|
1095
|
+
p++;
|
1096
|
+
break;
|
1097
|
+
case 'f':
|
1098
|
+
rb_str_buf_cat2(result, "\f");
|
1099
|
+
p++;
|
1100
|
+
break;
|
1101
|
+
case 'n':
|
1102
|
+
rb_str_buf_cat2(result, "\n");
|
1103
|
+
p++;
|
1104
|
+
break;
|
1105
|
+
case 'r':
|
1106
|
+
rb_str_buf_cat2(result, "\r");
|
1107
|
+
p++;
|
1108
|
+
break;
|
1109
|
+
case 't':
|
1110
|
+
rb_str_buf_cat2(result, "\t");
|
1111
|
+
p++;
|
1112
|
+
break;
|
1113
|
+
case 'u':
|
1114
|
+
if (p > pe - 4) {
|
1115
|
+
return Qnil;
|
1116
|
+
} else {
|
1117
|
+
p = JSON_convert_UTF16_to_UTF8(result, p, pe, strictConversion);
|
1118
|
+
}
|
1119
|
+
break;
|
1120
|
+
}
|
1121
|
+
} else {
|
1122
|
+
char *q = p;
|
1123
|
+
while (*q != '\\' && q < pe) q++;
|
1124
|
+
rb_str_buf_cat(result, p, q - p);
|
1125
|
+
p = q;
|
1126
|
+
}
|
1127
|
+
}
|
1128
|
+
return result;
|
1129
|
+
}
|
1130
|
+
|
1131
|
+
|
1132
|
+
#line 1133 "parser.c"
|
1133
|
+
static const int JSON_string_start = 0;
|
1134
|
+
|
1135
|
+
static const int JSON_string_first_final = 8;
|
1136
|
+
|
1137
|
+
static const int JSON_string_error = 1;
|
1138
|
+
|
1139
|
+
#line 350 "parser.rl"
|
1140
|
+
|
1141
|
+
|
1142
|
+
static char *JSON_parse_string(JSON_Parser *json, char *p, char *pe, VALUE *result)
|
1143
|
+
{
|
1144
|
+
int cs = EVIL;
|
1145
|
+
|
1146
|
+
*result = rb_str_new("", 0);
|
1147
|
+
|
1148
|
+
#line 1149 "parser.c"
|
1149
|
+
{
|
1150
|
+
cs = JSON_string_start;
|
1151
|
+
}
|
1152
|
+
#line 358 "parser.rl"
|
1153
|
+
json->memo = p;
|
1154
|
+
|
1155
|
+
#line 1156 "parser.c"
|
1156
|
+
{
|
1157
|
+
if ( p == pe )
|
1158
|
+
goto _out;
|
1159
|
+
switch ( cs )
|
1160
|
+
{
|
1161
|
+
case 0:
|
1162
|
+
if ( (*p) == 34 )
|
1163
|
+
goto st2;
|
1164
|
+
goto st1;
|
1165
|
+
st1:
|
1166
|
+
goto _out1;
|
1167
|
+
st2:
|
1168
|
+
if ( ++p == pe )
|
1169
|
+
goto _out2;
|
1170
|
+
case 2:
|
1171
|
+
switch( (*p) ) {
|
1172
|
+
case 34: goto tr4;
|
1173
|
+
case 92: goto st3;
|
1174
|
+
}
|
1175
|
+
if ( 0 <= (*p) && (*p) <= 31 )
|
1176
|
+
goto st1;
|
1177
|
+
goto st2;
|
1178
|
+
tr4:
|
1179
|
+
#line 342 "parser.rl"
|
1180
|
+
{
|
1181
|
+
*result = json_string_escape(json->memo + 1, p);
|
1182
|
+
if (NIL_P(*result)) goto _out8; else {p = (( p + 1))-1;}
|
1183
|
+
}
|
1184
|
+
#line 347 "parser.rl"
|
1185
|
+
{ goto _out8; }
|
1186
|
+
goto st8;
|
1187
|
+
st8:
|
1188
|
+
if ( ++p == pe )
|
1189
|
+
goto _out8;
|
1190
|
+
case 8:
|
1191
|
+
#line 1192 "parser.c"
|
1192
|
+
goto st1;
|
1193
|
+
st3:
|
1194
|
+
if ( ++p == pe )
|
1195
|
+
goto _out3;
|
1196
|
+
case 3:
|
1197
|
+
switch( (*p) ) {
|
1198
|
+
case 34: goto st2;
|
1199
|
+
case 47: goto st2;
|
1200
|
+
case 92: goto st2;
|
1201
|
+
case 98: goto st2;
|
1202
|
+
case 102: goto st2;
|
1203
|
+
case 110: goto st2;
|
1204
|
+
case 114: goto st2;
|
1205
|
+
case 116: goto st2;
|
1206
|
+
case 117: goto st4;
|
1207
|
+
}
|
1208
|
+
goto st1;
|
1209
|
+
st4:
|
1210
|
+
if ( ++p == pe )
|
1211
|
+
goto _out4;
|
1212
|
+
case 4:
|
1213
|
+
if ( (*p) < 65 ) {
|
1214
|
+
if ( 48 <= (*p) && (*p) <= 57 )
|
1215
|
+
goto st5;
|
1216
|
+
} else if ( (*p) > 70 ) {
|
1217
|
+
if ( 97 <= (*p) && (*p) <= 102 )
|
1218
|
+
goto st5;
|
1219
|
+
} else
|
1220
|
+
goto st5;
|
1221
|
+
goto st1;
|
1222
|
+
st5:
|
1223
|
+
if ( ++p == pe )
|
1224
|
+
goto _out5;
|
1225
|
+
case 5:
|
1226
|
+
if ( (*p) < 65 ) {
|
1227
|
+
if ( 48 <= (*p) && (*p) <= 57 )
|
1228
|
+
goto st6;
|
1229
|
+
} else if ( (*p) > 70 ) {
|
1230
|
+
if ( 97 <= (*p) && (*p) <= 102 )
|
1231
|
+
goto st6;
|
1232
|
+
} else
|
1233
|
+
goto st6;
|
1234
|
+
goto st1;
|
1235
|
+
st6:
|
1236
|
+
if ( ++p == pe )
|
1237
|
+
goto _out6;
|
1238
|
+
case 6:
|
1239
|
+
if ( (*p) < 65 ) {
|
1240
|
+
if ( 48 <= (*p) && (*p) <= 57 )
|
1241
|
+
goto st7;
|
1242
|
+
} else if ( (*p) > 70 ) {
|
1243
|
+
if ( 97 <= (*p) && (*p) <= 102 )
|
1244
|
+
goto st7;
|
1245
|
+
} else
|
1246
|
+
goto st7;
|
1247
|
+
goto st1;
|
1248
|
+
st7:
|
1249
|
+
if ( ++p == pe )
|
1250
|
+
goto _out7;
|
1251
|
+
case 7:
|
1252
|
+
if ( (*p) < 65 ) {
|
1253
|
+
if ( 48 <= (*p) && (*p) <= 57 )
|
1254
|
+
goto st2;
|
1255
|
+
} else if ( (*p) > 70 ) {
|
1256
|
+
if ( 97 <= (*p) && (*p) <= 102 )
|
1257
|
+
goto st2;
|
1258
|
+
} else
|
1259
|
+
goto st2;
|
1260
|
+
goto st1;
|
1261
|
+
}
|
1262
|
+
_out1: cs = 1; goto _out;
|
1263
|
+
_out2: cs = 2; goto _out;
|
1264
|
+
_out8: cs = 8; goto _out;
|
1265
|
+
_out3: cs = 3; goto _out;
|
1266
|
+
_out4: cs = 4; goto _out;
|
1267
|
+
_out5: cs = 5; goto _out;
|
1268
|
+
_out6: cs = 6; goto _out;
|
1269
|
+
_out7: cs = 7; goto _out;
|
1270
|
+
|
1271
|
+
_out: {}
|
1272
|
+
}
|
1273
|
+
#line 360 "parser.rl"
|
1274
|
+
|
1275
|
+
if (cs >= JSON_string_first_final) {
|
1276
|
+
return p + 1;
|
1277
|
+
} else {
|
1278
|
+
return NULL;
|
1279
|
+
}
|
1280
|
+
}
|
1281
|
+
|
1282
|
+
|
1283
|
+
|
1284
|
+
#line 1285 "parser.c"
|
1285
|
+
static const int JSON_start = 0;
|
1286
|
+
|
1287
|
+
static const int JSON_first_final = 10;
|
1288
|
+
|
1289
|
+
static const int JSON_error = 1;
|
1290
|
+
|
1291
|
+
#line 390 "parser.rl"
|
1292
|
+
|
1293
|
+
|
1294
|
+
/*
|
1295
|
+
* Document-class: JSON::Ext::Parser
|
1296
|
+
*
|
1297
|
+
* This is the JSON parser implemented as a C extension. It can be configured
|
1298
|
+
* to be used by setting
|
1299
|
+
*
|
1300
|
+
* JSON.parser = JSON::Ext::Parser
|
1301
|
+
*
|
1302
|
+
* with the method parser= in JSON.
|
1303
|
+
*
|
1304
|
+
*/
|
1305
|
+
|
1306
|
+
/*
|
1307
|
+
* call-seq: new(source)
|
1308
|
+
*
|
1309
|
+
* Creates a new JSON::Ext::Parser instance for the string _source_.
|
1310
|
+
*/
|
1311
|
+
static VALUE cParser_initialize(VALUE self, VALUE source)
|
1312
|
+
{
|
1313
|
+
char *ptr;
|
1314
|
+
long len;
|
1315
|
+
GET_STRUCT;
|
1316
|
+
source = StringValue(source);
|
1317
|
+
ptr = RSTRING(source)->ptr;
|
1318
|
+
len = RSTRING(source)->len;
|
1319
|
+
if (len < 2) {
|
1320
|
+
rb_raise(eParserError, "A JSON text must at least contain two octets!");
|
1321
|
+
}
|
1322
|
+
/*
|
1323
|
+
Convert these?
|
1324
|
+
if (len >= 4 && ptr[0] == 0 && ptr[1] == 0 && ptr[2] == 0) {
|
1325
|
+
rb_raise(eParserError, "Only UTF8 octet streams are supported atm!");
|
1326
|
+
} else if (len >= 4 && ptr[0] == 0 && ptr[2] == 0) {
|
1327
|
+
rb_raise(eParserError, "Only UTF8 octet streams are supported atm!");
|
1328
|
+
} else if (len >= 4 && ptr[1] == 0 && ptr[2] == 0 && ptr[3] == 0) {
|
1329
|
+
rb_raise(eParserError, "Only UTF8 octet streams are supported atm!");
|
1330
|
+
} else if (len >= 4 && ptr[1] == 0 && ptr[3] == 0) {
|
1331
|
+
rb_raise(eParserError, "Only UTF8 octet streams are supported atm!");
|
1332
|
+
}
|
1333
|
+
*/
|
1334
|
+
json->len = len;
|
1335
|
+
json->source = ptr;
|
1336
|
+
json->Vsource = source;
|
1337
|
+
json->create_id = rb_funcall(mJSON, i_create_id, 0);
|
1338
|
+
return self;
|
1339
|
+
}
|
1340
|
+
|
1341
|
+
/*
|
1342
|
+
* call-seq: parse()
|
1343
|
+
*
|
1344
|
+
* Parses the current JSON text _source_ and returns the complete data
|
1345
|
+
* structure as a result.
|
1346
|
+
*/
|
1347
|
+
static VALUE cParser_parse(VALUE self)
|
1348
|
+
{
|
1349
|
+
GET_STRUCT;
|
1350
|
+
char *p, *pe;
|
1351
|
+
int cs = EVIL;
|
1352
|
+
VALUE result = Qnil;
|
1353
|
+
|
1354
|
+
|
1355
|
+
#line 1356 "parser.c"
|
1356
|
+
{
|
1357
|
+
cs = JSON_start;
|
1358
|
+
}
|
1359
|
+
#line 453 "parser.rl"
|
1360
|
+
p = json->source;
|
1361
|
+
pe = p + json->len;
|
1362
|
+
|
1363
|
+
#line 1364 "parser.c"
|
1364
|
+
{
|
1365
|
+
if ( p == pe )
|
1366
|
+
goto _out;
|
1367
|
+
switch ( cs )
|
1368
|
+
{
|
1369
|
+
st0:
|
1370
|
+
if ( ++p == pe )
|
1371
|
+
goto _out0;
|
1372
|
+
case 0:
|
1373
|
+
switch( (*p) ) {
|
1374
|
+
case 13: goto st0;
|
1375
|
+
case 32: goto st0;
|
1376
|
+
case 47: goto st2;
|
1377
|
+
case 91: goto tr7;
|
1378
|
+
case 123: goto tr8;
|
1379
|
+
}
|
1380
|
+
if ( 9 <= (*p) && (*p) <= 10 )
|
1381
|
+
goto st0;
|
1382
|
+
goto st1;
|
1383
|
+
st1:
|
1384
|
+
goto _out1;
|
1385
|
+
st2:
|
1386
|
+
if ( ++p == pe )
|
1387
|
+
goto _out2;
|
1388
|
+
case 2:
|
1389
|
+
switch( (*p) ) {
|
1390
|
+
case 42: goto st3;
|
1391
|
+
case 47: goto st5;
|
1392
|
+
}
|
1393
|
+
goto st1;
|
1394
|
+
st3:
|
1395
|
+
if ( ++p == pe )
|
1396
|
+
goto _out3;
|
1397
|
+
case 3:
|
1398
|
+
if ( (*p) == 42 )
|
1399
|
+
goto st4;
|
1400
|
+
goto st3;
|
1401
|
+
st4:
|
1402
|
+
if ( ++p == pe )
|
1403
|
+
goto _out4;
|
1404
|
+
case 4:
|
1405
|
+
switch( (*p) ) {
|
1406
|
+
case 42: goto st4;
|
1407
|
+
case 47: goto st0;
|
1408
|
+
}
|
1409
|
+
goto st3;
|
1410
|
+
st5:
|
1411
|
+
if ( ++p == pe )
|
1412
|
+
goto _out5;
|
1413
|
+
case 5:
|
1414
|
+
if ( (*p) == 10 )
|
1415
|
+
goto st0;
|
1416
|
+
goto st5;
|
1417
|
+
tr7:
|
1418
|
+
#line 381 "parser.rl"
|
1419
|
+
{
|
1420
|
+
char *np = JSON_parse_array(json, p, pe, &result);
|
1421
|
+
if (np == NULL) goto _out10; else {p = (( np))-1;}
|
1422
|
+
}
|
1423
|
+
goto st10;
|
1424
|
+
tr8:
|
1425
|
+
#line 376 "parser.rl"
|
1426
|
+
{
|
1427
|
+
char *np = JSON_parse_object(json, p, pe, &result);
|
1428
|
+
if (np == NULL) goto _out10; else {p = (( np))-1;}
|
1429
|
+
}
|
1430
|
+
goto st10;
|
1431
|
+
st10:
|
1432
|
+
if ( ++p == pe )
|
1433
|
+
goto _out10;
|
1434
|
+
case 10:
|
1435
|
+
#line 1436 "parser.c"
|
1436
|
+
switch( (*p) ) {
|
1437
|
+
case 13: goto st10;
|
1438
|
+
case 32: goto st10;
|
1439
|
+
case 47: goto st6;
|
1440
|
+
}
|
1441
|
+
if ( 9 <= (*p) && (*p) <= 10 )
|
1442
|
+
goto st10;
|
1443
|
+
goto st1;
|
1444
|
+
st6:
|
1445
|
+
if ( ++p == pe )
|
1446
|
+
goto _out6;
|
1447
|
+
case 6:
|
1448
|
+
switch( (*p) ) {
|
1449
|
+
case 42: goto st7;
|
1450
|
+
case 47: goto st9;
|
1451
|
+
}
|
1452
|
+
goto st1;
|
1453
|
+
st7:
|
1454
|
+
if ( ++p == pe )
|
1455
|
+
goto _out7;
|
1456
|
+
case 7:
|
1457
|
+
if ( (*p) == 42 )
|
1458
|
+
goto st8;
|
1459
|
+
goto st7;
|
1460
|
+
st8:
|
1461
|
+
if ( ++p == pe )
|
1462
|
+
goto _out8;
|
1463
|
+
case 8:
|
1464
|
+
switch( (*p) ) {
|
1465
|
+
case 42: goto st8;
|
1466
|
+
case 47: goto st10;
|
1467
|
+
}
|
1468
|
+
goto st7;
|
1469
|
+
st9:
|
1470
|
+
if ( ++p == pe )
|
1471
|
+
goto _out9;
|
1472
|
+
case 9:
|
1473
|
+
if ( (*p) == 10 )
|
1474
|
+
goto st10;
|
1475
|
+
goto st9;
|
1476
|
+
}
|
1477
|
+
_out0: cs = 0; goto _out;
|
1478
|
+
_out1: cs = 1; goto _out;
|
1479
|
+
_out2: cs = 2; goto _out;
|
1480
|
+
_out3: cs = 3; goto _out;
|
1481
|
+
_out4: cs = 4; goto _out;
|
1482
|
+
_out5: cs = 5; goto _out;
|
1483
|
+
_out10: cs = 10; goto _out;
|
1484
|
+
_out6: cs = 6; goto _out;
|
1485
|
+
_out7: cs = 7; goto _out;
|
1486
|
+
_out8: cs = 8; goto _out;
|
1487
|
+
_out9: cs = 9; goto _out;
|
1488
|
+
|
1489
|
+
_out: {}
|
1490
|
+
}
|
1491
|
+
#line 456 "parser.rl"
|
1492
|
+
|
1493
|
+
if (cs >= JSON_first_final && p == pe) {
|
1494
|
+
return result;
|
1495
|
+
} else {
|
1496
|
+
rb_raise(eParserError, "unexpected token at '%s'", p);
|
1497
|
+
}
|
1498
|
+
}
|
1499
|
+
|
1500
|
+
static JSON_Parser *JSON_allocate()
|
1501
|
+
{
|
1502
|
+
JSON_Parser *json = ALLOC(JSON_Parser);
|
1503
|
+
MEMZERO(json, JSON_Parser, 1);
|
1504
|
+
return json;
|
1505
|
+
}
|
1506
|
+
|
1507
|
+
static void JSON_mark(JSON_Parser *json)
|
1508
|
+
{
|
1509
|
+
rb_gc_mark_maybe(json->Vsource);
|
1510
|
+
rb_gc_mark_maybe(json->create_id);
|
1511
|
+
}
|
1512
|
+
|
1513
|
+
static void JSON_free(JSON_Parser *json)
|
1514
|
+
{
|
1515
|
+
free(json);
|
1516
|
+
}
|
1517
|
+
|
1518
|
+
static VALUE cJSON_parser_s_allocate(VALUE klass)
|
1519
|
+
{
|
1520
|
+
JSON_Parser *json = JSON_allocate();
|
1521
|
+
return Data_Wrap_Struct(klass, JSON_mark, JSON_free, json);
|
1522
|
+
}
|
1523
|
+
|
1524
|
+
/*
|
1525
|
+
* call-seq: source()
|
1526
|
+
*
|
1527
|
+
* Returns a copy of the current _source_ string, that was used to construct
|
1528
|
+
* this Parser.
|
1529
|
+
*/
|
1530
|
+
static VALUE cParser_source(VALUE self)
|
1531
|
+
{
|
1532
|
+
GET_STRUCT;
|
1533
|
+
return rb_str_dup(json->Vsource);
|
1534
|
+
}
|
1535
|
+
|
1536
|
+
void Init_parser()
|
1537
|
+
{
|
1538
|
+
mJSON = rb_define_module("JSON");
|
1539
|
+
mExt = rb_define_module_under(mJSON, "Ext");
|
1540
|
+
cParser = rb_define_class_under(mExt, "Parser", rb_cObject);
|
1541
|
+
eParserError = rb_path2class("JSON::ParserError");
|
1542
|
+
rb_define_alloc_func(cParser, cJSON_parser_s_allocate);
|
1543
|
+
rb_define_method(cParser, "initialize", cParser_initialize, 1);
|
1544
|
+
rb_define_method(cParser, "parse", cParser_parse, 0);
|
1545
|
+
rb_define_method(cParser, "source", cParser_source, 0);
|
1546
|
+
|
1547
|
+
i_json_creatable_p = rb_intern("json_creatable?");
|
1548
|
+
i_json_create = rb_intern("json_create");
|
1549
|
+
i_create_id = rb_intern("create_id");
|
1550
|
+
i_chr = rb_intern("chr");
|
1551
|
+
}
|