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.

Files changed (74) hide show
  1. data/CHANGES +6 -1
  2. data/README +49 -7
  3. data/Rakefile +216 -52
  4. data/TODO +1 -0
  5. data/VERSION +1 -1
  6. data/benchmarks/benchmark.txt +133 -0
  7. data/benchmarks/benchmark_generator.rb +44 -0
  8. data/benchmarks/benchmark_parser.rb +22 -0
  9. data/benchmarks/benchmark_rails.rb +26 -0
  10. data/data/example.json +1 -0
  11. data/data/index.html +37 -0
  12. data/data/prototype.js +2515 -0
  13. data/ext/json/ext/generator/Makefile +149 -0
  14. data/ext/json/ext/generator/extconf.rb +9 -0
  15. data/ext/json/ext/generator/generator.c +729 -0
  16. data/ext/json/ext/generator/unicode.c +184 -0
  17. data/ext/json/ext/generator/unicode.h +40 -0
  18. data/ext/json/ext/parser/Makefile +149 -0
  19. data/ext/json/ext/parser/extconf.rb +9 -0
  20. data/ext/json/ext/parser/parser.c +1551 -0
  21. data/ext/json/ext/parser/parser.rl +515 -0
  22. data/ext/json/ext/parser/unicode.c +156 -0
  23. data/ext/json/ext/parser/unicode.h +44 -0
  24. data/install.rb +13 -8
  25. data/lib/json.rb +101 -614
  26. data/lib/json/common.rb +184 -0
  27. data/lib/json/editor.rb +19 -10
  28. data/lib/json/ext.rb +13 -0
  29. data/lib/json/pure.rb +75 -0
  30. data/lib/json/pure/generator.rb +321 -0
  31. data/lib/json/pure/parser.rb +210 -0
  32. data/lib/json/version.rb +8 -0
  33. data/tests/fixtures/fail1.json +1 -0
  34. data/tests/fixtures/fail10.json +1 -0
  35. data/tests/fixtures/fail11.json +1 -0
  36. data/tests/fixtures/fail12.json +1 -0
  37. data/tests/fixtures/fail13.json +1 -0
  38. data/tests/fixtures/fail14.json +1 -0
  39. data/tests/fixtures/fail15.json +1 -0
  40. data/tests/fixtures/fail16.json +1 -0
  41. data/tests/fixtures/fail17.json +1 -0
  42. data/tests/fixtures/fail19.json +1 -0
  43. data/tests/fixtures/fail2.json +1 -0
  44. data/tests/fixtures/fail20.json +1 -0
  45. data/tests/fixtures/fail21.json +1 -0
  46. data/tests/fixtures/fail22.json +1 -0
  47. data/tests/fixtures/fail23.json +1 -0
  48. data/tests/fixtures/fail24.json +1 -0
  49. data/tests/fixtures/fail25.json +1 -0
  50. data/tests/fixtures/fail26.json +1 -0
  51. data/tests/fixtures/fail27.json +2 -0
  52. data/tests/fixtures/fail28.json +2 -0
  53. data/tests/fixtures/fail3.json +1 -0
  54. data/tests/fixtures/fail4.json +1 -0
  55. data/tests/fixtures/fail5.json +1 -0
  56. data/tests/fixtures/fail6.json +1 -0
  57. data/tests/fixtures/fail7.json +1 -0
  58. data/tests/fixtures/fail8.json +1 -0
  59. data/tests/fixtures/fail9.json +1 -0
  60. data/tests/fixtures/pass1.json +56 -0
  61. data/tests/fixtures/pass18.json +1 -0
  62. data/tests/fixtures/pass2.json +1 -0
  63. data/tests/fixtures/pass3.json +6 -0
  64. data/tests/runner.rb +8 -2
  65. data/tests/test_json.rb +102 -154
  66. data/tests/test_json_addition.rb +94 -0
  67. data/tests/test_json_fixtures.rb +30 -0
  68. data/tests/test_json_generate.rb +81 -0
  69. data/tests/test_json_unicode.rb +55 -0
  70. data/tools/fuzz.rb +133 -0
  71. data/tools/server.rb +62 -0
  72. metadata +87 -10
  73. data/bla.json.tmp +0 -0
  74. 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,9 @@
1
+ require 'mkmf'
2
+ require 'rbconfig'
3
+
4
+ if CONFIG['CC'] =~ /gcc/
5
+ #CONFIG['CC'] += ' -Wall -ggdb'
6
+ CONFIG['CC'] += ' -Wall'
7
+ end
8
+
9
+ create_makefile 'parser'
@@ -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
+ }