benschwarz-smoke 0.4.2 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (245) hide show
  1. data/Rakefile +47 -0
  2. data/VERSION.yml +2 -2
  3. data/lib/core_ext/string.rb +6 -0
  4. data/lib/smoke/cache.rb +38 -23
  5. data/lib/smoke/request.rb +4 -8
  6. data/lib/smoke.rb +7 -2
  7. data/rdoc/classes/Smoke/Origin.html +340 -0
  8. data/rdoc/classes/Smoke/Source/Data.html +126 -0
  9. data/rdoc/classes/Smoke/Source/Feed.html +117 -0
  10. data/rdoc/classes/Smoke/Source/YQL.html +223 -0
  11. data/rdoc/classes/Smoke.html +260 -0
  12. data/rdoc/created.rid +1 -0
  13. data/rdoc/files/README_markdown.html +180 -0
  14. data/rdoc/files/lib/core_ext/hash_rb.html +49 -0
  15. data/rdoc/files/lib/smoke/origin_rb.html +49 -0
  16. data/rdoc/files/lib/smoke/request_rb.html +49 -0
  17. data/rdoc/files/lib/smoke/source/data_rb.html +49 -0
  18. data/rdoc/files/lib/smoke/source/feed_rb.html +49 -0
  19. data/rdoc/files/lib/smoke/source/join_rb.html +49 -0
  20. data/rdoc/files/lib/smoke/source/yql_rb.html +49 -0
  21. data/rdoc/files/lib/smoke_rb.html +65 -0
  22. data/rdoc/fr_class_index.html +21 -0
  23. data/rdoc/fr_file_index.html +28 -0
  24. data/rdoc/fr_method_index.html +4459 -0
  25. data/rdoc/index.html +15 -0
  26. data/rdoc/rdoc-style.css +319 -0
  27. data/spec/smoke/cache_spec.rb +28 -6
  28. data/vendor/crack/History +15 -0
  29. data/vendor/crack/LICENSE +20 -0
  30. data/vendor/crack/README.rdoc +42 -0
  31. data/vendor/crack/Rakefile +49 -0
  32. data/vendor/crack/VERSION.yml +4 -0
  33. data/vendor/crack/crack.gemspec +61 -0
  34. data/vendor/crack/lib/crack/core_extensions.rb +128 -0
  35. data/vendor/crack/lib/crack/json.rb +68 -0
  36. data/vendor/crack/lib/crack/xml.rb +214 -0
  37. data/vendor/crack/lib/crack.rb +7 -0
  38. data/vendor/crack/test/crack_test.rb +4 -0
  39. data/vendor/crack/test/data/twittersearch-firefox.json +1 -0
  40. data/vendor/crack/test/data/twittersearch-ie.json +1 -0
  41. data/vendor/crack/test/hash_test.rb +56 -0
  42. data/vendor/crack/test/json_test.rb +66 -0
  43. data/vendor/crack/test/string_test.rb +31 -0
  44. data/vendor/crack/test/test_helper.rb +12 -0
  45. data/vendor/crack/test/xml_test.rb +489 -0
  46. data/vendor/dependencies/README.markdown +113 -0
  47. data/vendor/dependencies/Rakefile +5 -0
  48. data/vendor/dependencies/bin/dep +83 -0
  49. data/vendor/dependencies/dependencies.gemspec +15 -0
  50. data/vendor/dependencies/dependencies.gemspec.erb +27 -0
  51. data/vendor/dependencies/lib/dependencies/dep.rb +99 -0
  52. data/vendor/dependencies/lib/dependencies.rb +5 -0
  53. data/vendor/dependencies/test/dependencies_test.rb +228 -0
  54. data/vendor/dependencies/test/foobaz-0.3.gem +0 -0
  55. data/vendor/fakeweb/CHANGELOG +163 -0
  56. data/vendor/fakeweb/LICENSE.txt +281 -0
  57. data/vendor/fakeweb/README.rdoc +193 -0
  58. data/vendor/fakeweb/Rakefile +76 -0
  59. data/vendor/fakeweb/fakeweb.gemspec +21 -0
  60. data/vendor/fakeweb/lib/fake_web/ext/net_http.rb +71 -0
  61. data/vendor/fakeweb/lib/fake_web/registry.rb +103 -0
  62. data/vendor/fakeweb/lib/fake_web/responder.rb +113 -0
  63. data/vendor/fakeweb/lib/fake_web/response.rb +10 -0
  64. data/vendor/fakeweb/lib/fake_web/stub_socket.rb +15 -0
  65. data/vendor/fakeweb/lib/fake_web/utility.rb +22 -0
  66. data/vendor/fakeweb/lib/fake_web.rb +172 -0
  67. data/vendor/fakeweb/lib/fakeweb.rb +2 -0
  68. data/vendor/fakeweb/test/fixtures/google_response_from_curl +12 -0
  69. data/vendor/fakeweb/test/fixtures/google_response_with_transfer_encoding +17 -0
  70. data/vendor/fakeweb/test/fixtures/google_response_without_transfer_encoding +11 -0
  71. data/vendor/fakeweb/test/fixtures/test_example.txt +1 -0
  72. data/vendor/fakeweb/test/fixtures/test_txt_file +3 -0
  73. data/vendor/fakeweb/test/test_allow_net_connect.rb +85 -0
  74. data/vendor/fakeweb/test/test_deprecations.rb +54 -0
  75. data/vendor/fakeweb/test/test_fake_authentication.rb +92 -0
  76. data/vendor/fakeweb/test/test_fake_web.rb +535 -0
  77. data/vendor/fakeweb/test/test_fake_web_open_uri.rb +58 -0
  78. data/vendor/fakeweb/test/test_helper.rb +74 -0
  79. data/vendor/fakeweb/test/test_missing_open_uri.rb +25 -0
  80. data/vendor/fakeweb/test/test_precedence.rb +51 -0
  81. data/vendor/fakeweb/test/test_query_string.rb +45 -0
  82. data/vendor/fakeweb/test/test_regexes.rb +103 -0
  83. data/vendor/fakeweb/test/test_response_headers.rb +73 -0
  84. data/vendor/fakeweb/test/test_trailing_slashes.rb +53 -0
  85. data/vendor/fakeweb/test/test_utility.rb +70 -0
  86. data/vendor/json-1.1.3/CHANGES +93 -0
  87. data/vendor/json-1.1.3/GPL +340 -0
  88. data/vendor/json-1.1.3/README +78 -0
  89. data/vendor/json-1.1.3/RUBY +58 -0
  90. data/vendor/json-1.1.3/Rakefile +309 -0
  91. data/vendor/json-1.1.3/TODO +1 -0
  92. data/vendor/json-1.1.3/VERSION +1 -0
  93. data/vendor/json-1.1.3/benchmarks/benchmark.txt +133 -0
  94. data/vendor/json-1.1.3/benchmarks/benchmark_generator.rb +48 -0
  95. data/vendor/json-1.1.3/benchmarks/benchmark_parser.rb +26 -0
  96. data/vendor/json-1.1.3/benchmarks/benchmark_rails.rb +26 -0
  97. data/vendor/json-1.1.3/bin/edit_json.rb +10 -0
  98. data/vendor/json-1.1.3/bin/prettify_json.rb +76 -0
  99. data/vendor/json-1.1.3/data/example.json +1 -0
  100. data/vendor/json-1.1.3/data/index.html +38 -0
  101. data/vendor/json-1.1.3/data/prototype.js +4184 -0
  102. data/vendor/json-1.1.3/ext/json/ext/generator/extconf.rb +9 -0
  103. data/vendor/json-1.1.3/ext/json/ext/generator/generator.c +875 -0
  104. data/vendor/json-1.1.3/ext/json/ext/generator/unicode.c +182 -0
  105. data/vendor/json-1.1.3/ext/json/ext/generator/unicode.h +53 -0
  106. data/vendor/json-1.1.3/ext/json/ext/parser/extconf.rb +9 -0
  107. data/vendor/json-1.1.3/ext/json/ext/parser/parser.c +1758 -0
  108. data/vendor/json-1.1.3/ext/json/ext/parser/parser.rl +638 -0
  109. data/vendor/json-1.1.3/ext/json/ext/parser/unicode.c +154 -0
  110. data/vendor/json-1.1.3/ext/json/ext/parser/unicode.h +58 -0
  111. data/vendor/json-1.1.3/install.rb +26 -0
  112. data/vendor/json-1.1.3/lib/json/Array.xpm +21 -0
  113. data/vendor/json-1.1.3/lib/json/FalseClass.xpm +21 -0
  114. data/vendor/json-1.1.3/lib/json/Hash.xpm +21 -0
  115. data/vendor/json-1.1.3/lib/json/Key.xpm +73 -0
  116. data/vendor/json-1.1.3/lib/json/NilClass.xpm +21 -0
  117. data/vendor/json-1.1.3/lib/json/Numeric.xpm +28 -0
  118. data/vendor/json-1.1.3/lib/json/String.xpm +96 -0
  119. data/vendor/json-1.1.3/lib/json/TrueClass.xpm +21 -0
  120. data/vendor/json-1.1.3/lib/json/add/core.rb +135 -0
  121. data/vendor/json-1.1.3/lib/json/add/rails.rb +58 -0
  122. data/vendor/json-1.1.3/lib/json/common.rb +354 -0
  123. data/vendor/json-1.1.3/lib/json/editor.rb +1362 -0
  124. data/vendor/json-1.1.3/lib/json/ext.rb +13 -0
  125. data/vendor/json-1.1.3/lib/json/json.xpm +1499 -0
  126. data/vendor/json-1.1.3/lib/json/pure/generator.rb +394 -0
  127. data/vendor/json-1.1.3/lib/json/pure/parser.rb +259 -0
  128. data/vendor/json-1.1.3/lib/json/pure.rb +75 -0
  129. data/vendor/json-1.1.3/lib/json/version.rb +9 -0
  130. data/vendor/json-1.1.3/lib/json.rb +235 -0
  131. data/vendor/json-1.1.3/tests/fixtures/fail1.json +1 -0
  132. data/vendor/json-1.1.3/tests/fixtures/fail10.json +1 -0
  133. data/vendor/json-1.1.3/tests/fixtures/fail11.json +1 -0
  134. data/vendor/json-1.1.3/tests/fixtures/fail12.json +1 -0
  135. data/vendor/json-1.1.3/tests/fixtures/fail13.json +1 -0
  136. data/vendor/json-1.1.3/tests/fixtures/fail14.json +1 -0
  137. data/vendor/json-1.1.3/tests/fixtures/fail18.json +1 -0
  138. data/vendor/json-1.1.3/tests/fixtures/fail19.json +1 -0
  139. data/vendor/json-1.1.3/tests/fixtures/fail2.json +1 -0
  140. data/vendor/json-1.1.3/tests/fixtures/fail20.json +1 -0
  141. data/vendor/json-1.1.3/tests/fixtures/fail21.json +1 -0
  142. data/vendor/json-1.1.3/tests/fixtures/fail22.json +1 -0
  143. data/vendor/json-1.1.3/tests/fixtures/fail23.json +1 -0
  144. data/vendor/json-1.1.3/tests/fixtures/fail24.json +1 -0
  145. data/vendor/json-1.1.3/tests/fixtures/fail25.json +1 -0
  146. data/vendor/json-1.1.3/tests/fixtures/fail27.json +2 -0
  147. data/vendor/json-1.1.3/tests/fixtures/fail28.json +2 -0
  148. data/vendor/json-1.1.3/tests/fixtures/fail3.json +1 -0
  149. data/vendor/json-1.1.3/tests/fixtures/fail4.json +1 -0
  150. data/vendor/json-1.1.3/tests/fixtures/fail5.json +1 -0
  151. data/vendor/json-1.1.3/tests/fixtures/fail6.json +1 -0
  152. data/vendor/json-1.1.3/tests/fixtures/fail7.json +1 -0
  153. data/vendor/json-1.1.3/tests/fixtures/fail8.json +1 -0
  154. data/vendor/json-1.1.3/tests/fixtures/fail9.json +1 -0
  155. data/vendor/json-1.1.3/tests/fixtures/pass1.json +56 -0
  156. data/vendor/json-1.1.3/tests/fixtures/pass15.json +1 -0
  157. data/vendor/json-1.1.3/tests/fixtures/pass16.json +1 -0
  158. data/vendor/json-1.1.3/tests/fixtures/pass17.json +1 -0
  159. data/vendor/json-1.1.3/tests/fixtures/pass2.json +1 -0
  160. data/vendor/json-1.1.3/tests/fixtures/pass26.json +1 -0
  161. data/vendor/json-1.1.3/tests/fixtures/pass3.json +6 -0
  162. data/vendor/json-1.1.3/tests/runner.rb +25 -0
  163. data/vendor/json-1.1.3/tests/test_json.rb +293 -0
  164. data/vendor/json-1.1.3/tests/test_json_addition.rb +161 -0
  165. data/vendor/json-1.1.3/tests/test_json_fixtures.rb +30 -0
  166. data/vendor/json-1.1.3/tests/test_json_generate.rb +100 -0
  167. data/vendor/json-1.1.3/tests/test_json_rails.rb +118 -0
  168. data/vendor/json-1.1.3/tests/test_json_unicode.rb +61 -0
  169. data/vendor/json-1.1.3/tools/fuzz.rb +140 -0
  170. data/vendor/json-1.1.3/tools/server.rb +62 -0
  171. data/vendor/moneta/LICENSE +20 -0
  172. data/vendor/moneta/README +51 -0
  173. data/vendor/moneta/Rakefile +60 -0
  174. data/vendor/moneta/TODO +4 -0
  175. data/vendor/moneta/benchmarks/various.rb +234 -0
  176. data/vendor/moneta/lib/moneta/basic_file.rb +111 -0
  177. data/vendor/moneta/lib/moneta/berkeley.rb +53 -0
  178. data/vendor/moneta/lib/moneta/couch.rb +63 -0
  179. data/vendor/moneta/lib/moneta/datamapper.rb +117 -0
  180. data/vendor/moneta/lib/moneta/file.rb +91 -0
  181. data/vendor/moneta/lib/moneta/lmc.rb +52 -0
  182. data/vendor/moneta/lib/moneta/memcache.rb +53 -0
  183. data/vendor/moneta/lib/moneta/memory.rb +11 -0
  184. data/vendor/moneta/lib/moneta/mongodb.rb +58 -0
  185. data/vendor/moneta/lib/moneta/redis.rb +49 -0
  186. data/vendor/moneta/lib/moneta/rufus.rb +41 -0
  187. data/vendor/moneta/lib/moneta/s3.rb +162 -0
  188. data/vendor/moneta/lib/moneta/sdbm.rb +33 -0
  189. data/vendor/moneta/lib/moneta/tyrant.rb +58 -0
  190. data/vendor/moneta/lib/moneta/xattr.rb +58 -0
  191. data/vendor/moneta/lib/moneta.rb +76 -0
  192. data/vendor/moneta/moneta.gemspec +32 -0
  193. data/vendor/moneta/script/destroy +14 -0
  194. data/vendor/moneta/script/generate +14 -0
  195. data/vendor/moneta/spec/moneta_basic_file_spec.rb +50 -0
  196. data/vendor/moneta/spec/moneta_berkeley_spec.rb +20 -0
  197. data/vendor/moneta/spec/moneta_couch_spec.rb +22 -0
  198. data/vendor/moneta/spec/moneta_datamapper_spec.rb +79 -0
  199. data/vendor/moneta/spec/moneta_file_spec.rb +21 -0
  200. data/vendor/moneta/spec/moneta_lmc_spec.rb +24 -0
  201. data/vendor/moneta/spec/moneta_memcache_spec.rb +16 -0
  202. data/vendor/moneta/spec/moneta_memory_spec.rb +12 -0
  203. data/vendor/moneta/spec/moneta_mongodb_spec.rb +16 -0
  204. data/vendor/moneta/spec/moneta_redis_spec.rb +16 -0
  205. data/vendor/moneta/spec/moneta_rufus_spec.rb +15 -0
  206. data/vendor/moneta/spec/moneta_s3_spec.rb +19 -0
  207. data/vendor/moneta/spec/moneta_sdbm_spec.rb +21 -0
  208. data/vendor/moneta/spec/moneta_tyrant_spec.rb +15 -0
  209. data/vendor/moneta/spec/moneta_xattr_spec.rb +21 -0
  210. data/vendor/moneta/spec/shared.rb +122 -0
  211. data/vendor/moneta/spec/spec_helper.rb +7 -0
  212. data/vendor/rest-client/README.rdoc +151 -0
  213. data/vendor/rest-client/Rakefile +58 -0
  214. data/vendor/rest-client/VERSION +1 -0
  215. data/vendor/rest-client/bin/restclient +87 -0
  216. data/vendor/rest-client/lib/rest_client.rb +2 -0
  217. data/vendor/rest-client/lib/restclient/exceptions.rb +88 -0
  218. data/vendor/rest-client/lib/restclient/mixin/response.rb +43 -0
  219. data/vendor/rest-client/lib/restclient/raw_response.rb +30 -0
  220. data/vendor/rest-client/lib/restclient/request.rb +238 -0
  221. data/vendor/rest-client/lib/restclient/resource.rb +146 -0
  222. data/vendor/rest-client/lib/restclient/response.rb +20 -0
  223. data/vendor/rest-client/lib/restclient.rb +99 -0
  224. data/vendor/rest-client/rest-client.gemspec +66 -0
  225. data/vendor/rest-client/spec/base.rb +4 -0
  226. data/vendor/rest-client/spec/exceptions_spec.rb +65 -0
  227. data/vendor/rest-client/spec/mixin/response_spec.rb +46 -0
  228. data/vendor/rest-client/spec/raw_response_spec.rb +17 -0
  229. data/vendor/rest-client/spec/request_spec.rb +476 -0
  230. data/vendor/rest-client/spec/resource_spec.rb +75 -0
  231. data/vendor/rest-client/spec/response_spec.rb +16 -0
  232. data/vendor/rest-client/spec/restclient_spec.rb +53 -0
  233. data/vendor/simple-rss/LICENSE +429 -0
  234. data/vendor/simple-rss/README +43 -0
  235. data/vendor/simple-rss/Rakefile +212 -0
  236. data/vendor/simple-rss/install.rb +40 -0
  237. data/vendor/simple-rss/lib/simple-rss.rb +150 -0
  238. data/vendor/simple-rss/simple-rss.gemspec +12 -0
  239. data/vendor/simple-rss/test/base/base_test.rb +51 -0
  240. data/vendor/simple-rss/test/data/atom.xml +45 -0
  241. data/vendor/simple-rss/test/data/not-rss.xml +8 -0
  242. data/vendor/simple-rss/test/data/rss09.rdf +79 -0
  243. data/vendor/simple-rss/test/data/rss20.xml +818 -0
  244. data/vendor/simple-rss/test/test_helper.rb +4 -0
  245. metadata +314 -40
@@ -0,0 +1,638 @@
1
+ #include "ruby.h"
2
+ #include "re.h"
3
+ #include "st.h"
4
+ #include "unicode.h"
5
+
6
+ #define EVIL 0x666
7
+
8
+ static VALUE mJSON, mExt, cParser, eParserError, eNestingError;
9
+ static VALUE CNaN, CInfinity, CMinusInfinity;
10
+
11
+ static ID i_json_creatable_p, i_json_create, i_create_id, i_create_additions,
12
+ i_chr, i_max_nesting, i_allow_nan;
13
+
14
+ #define MinusInfinity "-Infinity"
15
+
16
+ typedef struct JSON_ParserStruct {
17
+ VALUE Vsource;
18
+ char *source;
19
+ long len;
20
+ char *memo;
21
+ VALUE create_id;
22
+ int max_nesting;
23
+ int current_nesting;
24
+ int allow_nan;
25
+ } JSON_Parser;
26
+
27
+ static char *JSON_parse_object(JSON_Parser *json, char *p, char *pe, VALUE *result);
28
+ static char *JSON_parse_array(JSON_Parser *json, char *p, char *pe, VALUE *result);
29
+ static char *JSON_parse_value(JSON_Parser *json, char *p, char *pe, VALUE *result);
30
+ static char *JSON_parse_string(JSON_Parser *json, char *p, char *pe, VALUE *result);
31
+ static char *JSON_parse_integer(JSON_Parser *json, char *p, char *pe, VALUE *result);
32
+ static char *JSON_parse_float(JSON_Parser *json, char *p, char *pe, VALUE *result);
33
+
34
+ #define GET_STRUCT \
35
+ JSON_Parser *json; \
36
+ Data_Get_Struct(self, JSON_Parser, json);
37
+
38
+ %%{
39
+ machine JSON_common;
40
+
41
+ cr = '\n';
42
+ cr_neg = [^\n];
43
+ ws = [ \t\r\n];
44
+ c_comment = '/*' ( any* - (any* '*/' any* ) ) '*/';
45
+ cpp_comment = '//' cr_neg* cr;
46
+ comment = c_comment | cpp_comment;
47
+ ignore = ws | comment;
48
+ name_separator = ':';
49
+ value_separator = ',';
50
+ Vnull = 'null';
51
+ Vfalse = 'false';
52
+ Vtrue = 'true';
53
+ VNaN = 'NaN';
54
+ VInfinity = 'Infinity';
55
+ VMinusInfinity = '-Infinity';
56
+ begin_value = [nft"\-[{NI] | digit;
57
+ begin_object = '{';
58
+ end_object = '}';
59
+ begin_array = '[';
60
+ end_array = ']';
61
+ begin_string = '"';
62
+ begin_name = begin_string;
63
+ begin_number = digit | '-';
64
+ }%%
65
+
66
+ %%{
67
+ machine JSON_object;
68
+ include JSON_common;
69
+
70
+ write data;
71
+
72
+ action parse_value {
73
+ VALUE v = Qnil;
74
+ char *np = JSON_parse_value(json, fpc, pe, &v);
75
+ if (np == NULL) {
76
+ fhold; fbreak;
77
+ } else {
78
+ rb_hash_aset(*result, last_name, v);
79
+ fexec np;
80
+ }
81
+ }
82
+
83
+ action parse_name {
84
+ char *np = JSON_parse_string(json, fpc, pe, &last_name);
85
+ if (np == NULL) { fhold; fbreak; } else fexec np;
86
+ }
87
+
88
+ action exit { fhold; fbreak; }
89
+
90
+ a_pair = ignore* begin_name >parse_name
91
+ ignore* name_separator ignore*
92
+ begin_value >parse_value;
93
+
94
+ main := begin_object
95
+ (a_pair (ignore* value_separator a_pair)*)?
96
+ ignore* end_object @exit;
97
+ }%%
98
+
99
+ static char *JSON_parse_object(JSON_Parser *json, char *p, char *pe, VALUE *result)
100
+ {
101
+ int cs = EVIL;
102
+ VALUE last_name = Qnil;
103
+
104
+ if (json->max_nesting && json->current_nesting > json->max_nesting) {
105
+ rb_raise(eNestingError, "nesting of %d is to deep", json->current_nesting);
106
+ }
107
+
108
+ *result = rb_hash_new();
109
+
110
+ %% write init;
111
+ %% write exec;
112
+
113
+ if (cs >= JSON_object_first_final) {
114
+ if (RTEST(json->create_id)) {
115
+ VALUE klassname = rb_hash_aref(*result, json->create_id);
116
+ if (!NIL_P(klassname)) {
117
+ VALUE klass = rb_path2class(StringValueCStr(klassname));
118
+ if RTEST(rb_funcall(klass, i_json_creatable_p, 0)) {
119
+ *result = rb_funcall(klass, i_json_create, 1, *result);
120
+ }
121
+ }
122
+ }
123
+ return p + 1;
124
+ } else {
125
+ return NULL;
126
+ }
127
+ }
128
+
129
+ %%{
130
+ machine JSON_value;
131
+ include JSON_common;
132
+
133
+ write data;
134
+
135
+ action parse_null {
136
+ *result = Qnil;
137
+ }
138
+ action parse_false {
139
+ *result = Qfalse;
140
+ }
141
+ action parse_true {
142
+ *result = Qtrue;
143
+ }
144
+ action parse_nan {
145
+ if (json->allow_nan) {
146
+ *result = CNaN;
147
+ } else {
148
+ rb_raise(eParserError, "%u: unexpected token at '%s'", __LINE__, p - 2);
149
+ }
150
+ }
151
+ action parse_infinity {
152
+ if (json->allow_nan) {
153
+ *result = CInfinity;
154
+ } else {
155
+ rb_raise(eParserError, "%u: unexpected token at '%s'", __LINE__, p - 8);
156
+ }
157
+ }
158
+ action parse_string {
159
+ char *np = JSON_parse_string(json, fpc, pe, result);
160
+ if (np == NULL) { fhold; fbreak; } else fexec np;
161
+ }
162
+
163
+ action parse_number {
164
+ char *np;
165
+ if(pe > fpc + 9 && !strncmp(MinusInfinity, fpc, 9)) {
166
+ if (json->allow_nan) {
167
+ *result = CMinusInfinity;
168
+ fexec p + 10;
169
+ fhold; fbreak;
170
+ } else {
171
+ rb_raise(eParserError, "%u: unexpected token at '%s'", __LINE__, p);
172
+ }
173
+ }
174
+ np = JSON_parse_float(json, fpc, pe, result);
175
+ if (np != NULL) fexec np;
176
+ np = JSON_parse_integer(json, fpc, pe, result);
177
+ if (np != NULL) fexec np;
178
+ fhold; fbreak;
179
+ }
180
+
181
+ action parse_array {
182
+ char *np;
183
+ json->current_nesting++;
184
+ np = JSON_parse_array(json, fpc, pe, result);
185
+ json->current_nesting--;
186
+ if (np == NULL) { fhold; fbreak; } else fexec np;
187
+ }
188
+
189
+ action parse_object {
190
+ char *np;
191
+ json->current_nesting++;
192
+ np = JSON_parse_object(json, fpc, pe, result);
193
+ json->current_nesting--;
194
+ if (np == NULL) { fhold; fbreak; } else fexec np;
195
+ }
196
+
197
+ action exit { fhold; fbreak; }
198
+
199
+ main := (
200
+ Vnull @parse_null |
201
+ Vfalse @parse_false |
202
+ Vtrue @parse_true |
203
+ VNaN @parse_nan |
204
+ VInfinity @parse_infinity |
205
+ begin_number >parse_number |
206
+ begin_string >parse_string |
207
+ begin_array >parse_array |
208
+ begin_object >parse_object
209
+ ) %*exit;
210
+ }%%
211
+
212
+ static char *JSON_parse_value(JSON_Parser *json, char *p, char *pe, VALUE *result)
213
+ {
214
+ int cs = EVIL;
215
+
216
+ %% write init;
217
+ %% write exec;
218
+
219
+ if (cs >= JSON_value_first_final) {
220
+ return p;
221
+ } else {
222
+ return NULL;
223
+ }
224
+ }
225
+
226
+ %%{
227
+ machine JSON_integer;
228
+
229
+ write data;
230
+
231
+ action exit { fhold; fbreak; }
232
+
233
+ main := '-'? ('0' | [1-9][0-9]*) (^[0-9] @exit);
234
+ }%%
235
+
236
+ static char *JSON_parse_integer(JSON_Parser *json, char *p, char *pe, VALUE *result)
237
+ {
238
+ int cs = EVIL;
239
+
240
+ %% write init;
241
+ json->memo = p;
242
+ %% write exec;
243
+
244
+ if (cs >= JSON_integer_first_final) {
245
+ long len = p - json->memo;
246
+ *result = rb_Integer(rb_str_new(json->memo, len));
247
+ return p + 1;
248
+ } else {
249
+ return NULL;
250
+ }
251
+ }
252
+
253
+ %%{
254
+ machine JSON_float;
255
+ include JSON_common;
256
+
257
+ write data;
258
+
259
+ action exit { fhold; fbreak; }
260
+
261
+ main := '-'? (
262
+ (('0' | [1-9][0-9]*) '.' [0-9]+ ([Ee] [+\-]?[0-9]+)?)
263
+ | (('0' | [1-9][0-9]*) ([Ee] [+\-]?[0-9]+))
264
+ ) (^[0-9Ee.\-] @exit );
265
+ }%%
266
+
267
+ static char *JSON_parse_float(JSON_Parser *json, char *p, char *pe, VALUE *result)
268
+ {
269
+ int cs = EVIL;
270
+
271
+ %% write init;
272
+ json->memo = p;
273
+ %% write exec;
274
+
275
+ if (cs >= JSON_float_first_final) {
276
+ long len = p - json->memo;
277
+ *result = rb_Float(rb_str_new(json->memo, len));
278
+ return p + 1;
279
+ } else {
280
+ return NULL;
281
+ }
282
+ }
283
+
284
+
285
+ %%{
286
+ machine JSON_array;
287
+ include JSON_common;
288
+
289
+ write data;
290
+
291
+ action parse_value {
292
+ VALUE v = Qnil;
293
+ char *np = JSON_parse_value(json, fpc, pe, &v);
294
+ if (np == NULL) {
295
+ fhold; fbreak;
296
+ } else {
297
+ rb_ary_push(*result, v);
298
+ fexec np;
299
+ }
300
+ }
301
+
302
+ action exit { fhold; fbreak; }
303
+
304
+ next_element = value_separator ignore* begin_value >parse_value;
305
+
306
+ main := begin_array ignore*
307
+ ((begin_value >parse_value ignore*)
308
+ (ignore* next_element ignore*)*)?
309
+ end_array @exit;
310
+ }%%
311
+
312
+ static char *JSON_parse_array(JSON_Parser *json, char *p, char *pe, VALUE *result)
313
+ {
314
+ int cs = EVIL;
315
+
316
+ if (json->max_nesting && json->current_nesting > json->max_nesting) {
317
+ rb_raise(eNestingError, "nesting of %d is to deep", json->current_nesting);
318
+ }
319
+ *result = rb_ary_new();
320
+
321
+ %% write init;
322
+ %% write exec;
323
+
324
+ if(cs >= JSON_array_first_final) {
325
+ return p + 1;
326
+ } else {
327
+ rb_raise(eParserError, "%u: unexpected token at '%s'", __LINE__, p);
328
+ }
329
+ }
330
+
331
+ static VALUE json_string_unescape(char *p, char *pe)
332
+ {
333
+ VALUE result = rb_str_buf_new(pe - p + 1);
334
+
335
+ while (p < pe) {
336
+ if (*p == '\\') {
337
+ p++;
338
+ if (p >= pe) return Qnil; /* raise an exception later, \ at end */
339
+ switch (*p) {
340
+ case '"':
341
+ case '\\':
342
+ rb_str_buf_cat(result, p, 1);
343
+ p++;
344
+ break;
345
+ case 'b':
346
+ rb_str_buf_cat2(result, "\b");
347
+ p++;
348
+ break;
349
+ case 'f':
350
+ rb_str_buf_cat2(result, "\f");
351
+ p++;
352
+ break;
353
+ case 'n':
354
+ rb_str_buf_cat2(result, "\n");
355
+ p++;
356
+ break;
357
+ case 'r':
358
+ rb_str_buf_cat2(result, "\r");
359
+ p++;
360
+ break;
361
+ case 't':
362
+ rb_str_buf_cat2(result, "\t");
363
+ p++;
364
+ break;
365
+ case 'u':
366
+ if (p > pe - 4) {
367
+ return Qnil;
368
+ } else {
369
+ p = JSON_convert_UTF16_to_UTF8(result, p, pe, strictConversion);
370
+ }
371
+ break;
372
+ default:
373
+ rb_str_buf_cat(result, p, 1);
374
+ p++;
375
+ break;
376
+ }
377
+ } else {
378
+ char *q = p;
379
+ while (*q != '\\' && q < pe) q++;
380
+ rb_str_buf_cat(result, p, q - p);
381
+ p = q;
382
+ }
383
+ }
384
+ return result;
385
+ }
386
+
387
+ %%{
388
+ machine JSON_string;
389
+ include JSON_common;
390
+
391
+ write data;
392
+
393
+ action parse_string {
394
+ *result = json_string_unescape(json->memo + 1, p);
395
+ if (NIL_P(*result)) { fhold; fbreak; } else fexec p + 1;
396
+ }
397
+
398
+ action exit { fhold; fbreak; }
399
+
400
+ main := '"' ((^(["\\] | 0..0x1f) | '\\'["\\/bfnrt] | '\\u'[0-9a-fA-F]{4} | '\\'^(["\\/bfnrtu]|0..0x1f))* %parse_string) '"' @exit;
401
+ }%%
402
+
403
+ static char *JSON_parse_string(JSON_Parser *json, char *p, char *pe, VALUE *result)
404
+ {
405
+ int cs = EVIL;
406
+
407
+ *result = rb_str_new("", 0);
408
+ %% write init;
409
+ json->memo = p;
410
+ %% write exec;
411
+
412
+ if (cs >= JSON_string_first_final) {
413
+ return p + 1;
414
+ } else {
415
+ return NULL;
416
+ }
417
+ }
418
+
419
+
420
+ %%{
421
+ machine JSON;
422
+
423
+ write data;
424
+
425
+ include JSON_common;
426
+
427
+ action parse_object {
428
+ char *np;
429
+ json->current_nesting = 1;
430
+ np = JSON_parse_object(json, fpc, pe, &result);
431
+ if (np == NULL) { fhold; fbreak; } else fexec np;
432
+ }
433
+
434
+ action parse_array {
435
+ char *np;
436
+ json->current_nesting = 1;
437
+ np = JSON_parse_array(json, fpc, pe, &result);
438
+ if (np == NULL) { fhold; fbreak; } else fexec np;
439
+ }
440
+
441
+ main := ignore* (
442
+ begin_object >parse_object |
443
+ begin_array >parse_array
444
+ ) ignore*;
445
+ }%%
446
+
447
+ /*
448
+ * Document-class: JSON::Ext::Parser
449
+ *
450
+ * This is the JSON parser implemented as a C extension. It can be configured
451
+ * to be used by setting
452
+ *
453
+ * JSON.parser = JSON::Ext::Parser
454
+ *
455
+ * with the method parser= in JSON.
456
+ *
457
+ */
458
+
459
+ /*
460
+ * call-seq: new(source, opts => {})
461
+ *
462
+ * Creates a new JSON::Ext::Parser instance for the string _source_.
463
+ *
464
+ * Creates a new JSON::Ext::Parser instance for the string _source_.
465
+ *
466
+ * It will be configured by the _opts_ hash. _opts_ can have the following
467
+ * keys:
468
+ *
469
+ * _opts_ can have the following keys:
470
+ * * *max_nesting*: The maximum depth of nesting allowed in the parsed data
471
+ * structures. Disable depth checking with :max_nesting => false|nil|0, it
472
+ * defaults to 19.
473
+ * * *allow_nan*: If set to true, allow NaN, Infinity and -Infinity in
474
+ * defiance of RFC 4627 to be parsed by the Parser. This option defaults to
475
+ * false.
476
+ * * *create_additions*: If set to false, the Parser doesn't create
477
+ * additions even if a matchin class and create_id was found. This option
478
+ * defaults to true.
479
+ */
480
+ static VALUE cParser_initialize(int argc, VALUE *argv, VALUE self)
481
+ {
482
+ char *ptr;
483
+ long len;
484
+ VALUE source, opts;
485
+ GET_STRUCT;
486
+ rb_scan_args(argc, argv, "11", &source, &opts);
487
+ source = StringValue(source);
488
+ ptr = RSTRING_PTR(source);
489
+ len = RSTRING_LEN(source);
490
+ if (len < 2) {
491
+ rb_raise(eParserError, "A JSON text must at least contain two octets!");
492
+ }
493
+ if (!NIL_P(opts)) {
494
+ opts = rb_convert_type(opts, T_HASH, "Hash", "to_hash");
495
+ if (NIL_P(opts)) {
496
+ rb_raise(rb_eArgError, "opts needs to be like a hash");
497
+ } else {
498
+ VALUE tmp = ID2SYM(i_max_nesting);
499
+ if (st_lookup(RHASH(opts)->tbl, tmp, 0)) {
500
+ VALUE max_nesting = rb_hash_aref(opts, tmp);
501
+ if (RTEST(max_nesting)) {
502
+ Check_Type(max_nesting, T_FIXNUM);
503
+ json->max_nesting = FIX2INT(max_nesting);
504
+ } else {
505
+ json->max_nesting = 0;
506
+ }
507
+ } else {
508
+ json->max_nesting = 19;
509
+ }
510
+ tmp = ID2SYM(i_allow_nan);
511
+ if (st_lookup(RHASH(opts)->tbl, tmp, 0)) {
512
+ VALUE allow_nan = rb_hash_aref(opts, tmp);
513
+ json->allow_nan = RTEST(allow_nan) ? 1 : 0;
514
+ } else {
515
+ json->allow_nan = 0;
516
+ }
517
+ tmp = ID2SYM(i_create_additions);
518
+ if (st_lookup(RHASH(opts)->tbl, tmp, 0)) {
519
+ VALUE create_additions = rb_hash_aref(opts, tmp);
520
+ if (RTEST(create_additions)) {
521
+ json->create_id = rb_funcall(mJSON, i_create_id, 0);
522
+ } else {
523
+ json->create_id = Qnil;
524
+ }
525
+ } else {
526
+ json->create_id = rb_funcall(mJSON, i_create_id, 0);
527
+ }
528
+ }
529
+ } else {
530
+ json->max_nesting = 19;
531
+ json->allow_nan = 0;
532
+ json->create_id = rb_funcall(mJSON, i_create_id, 0);
533
+ }
534
+ json->current_nesting = 0;
535
+ /*
536
+ Convert these?
537
+ if (len >= 4 && ptr[0] == 0 && ptr[1] == 0 && ptr[2] == 0) {
538
+ rb_raise(eParserError, "Only UTF8 octet streams are supported atm!");
539
+ } else if (len >= 4 && ptr[0] == 0 && ptr[2] == 0) {
540
+ rb_raise(eParserError, "Only UTF8 octet streams are supported atm!");
541
+ } else if (len >= 4 && ptr[1] == 0 && ptr[2] == 0 && ptr[3] == 0) {
542
+ rb_raise(eParserError, "Only UTF8 octet streams are supported atm!");
543
+ } else if (len >= 4 && ptr[1] == 0 && ptr[3] == 0) {
544
+ rb_raise(eParserError, "Only UTF8 octet streams are supported atm!");
545
+ }
546
+ */
547
+ json->len = len;
548
+ json->source = ptr;
549
+ json->Vsource = source;
550
+ return self;
551
+ }
552
+
553
+ /*
554
+ * call-seq: parse()
555
+ *
556
+ * Parses the current JSON text _source_ and returns the complete data
557
+ * structure as a result.
558
+ */
559
+ static VALUE cParser_parse(VALUE self)
560
+ {
561
+ char *p, *pe;
562
+ int cs = EVIL;
563
+ VALUE result = Qnil;
564
+ GET_STRUCT;
565
+
566
+ %% write init;
567
+ p = json->source;
568
+ pe = p + json->len;
569
+ %% write exec;
570
+
571
+ if (cs >= JSON_first_final && p == pe) {
572
+ return result;
573
+ } else {
574
+ rb_raise(eParserError, "%u: unexpected token at '%s'", __LINE__, p);
575
+ }
576
+ }
577
+
578
+ inline static JSON_Parser *JSON_allocate()
579
+ {
580
+ JSON_Parser *json = ALLOC(JSON_Parser);
581
+ MEMZERO(json, JSON_Parser, 1);
582
+ return json;
583
+ }
584
+
585
+ static void JSON_mark(JSON_Parser *json)
586
+ {
587
+ rb_gc_mark_maybe(json->Vsource);
588
+ rb_gc_mark_maybe(json->create_id);
589
+ }
590
+
591
+ static void JSON_free(JSON_Parser *json)
592
+ {
593
+ free(json);
594
+ }
595
+
596
+ static VALUE cJSON_parser_s_allocate(VALUE klass)
597
+ {
598
+ JSON_Parser *json = JSON_allocate();
599
+ return Data_Wrap_Struct(klass, JSON_mark, JSON_free, json);
600
+ }
601
+
602
+ /*
603
+ * call-seq: source()
604
+ *
605
+ * Returns a copy of the current _source_ string, that was used to construct
606
+ * this Parser.
607
+ */
608
+ static VALUE cParser_source(VALUE self)
609
+ {
610
+ GET_STRUCT;
611
+ return rb_str_dup(json->Vsource);
612
+ }
613
+
614
+ void Init_parser()
615
+ {
616
+ rb_require("json/common");
617
+ mJSON = rb_define_module("JSON");
618
+ mExt = rb_define_module_under(mJSON, "Ext");
619
+ cParser = rb_define_class_under(mExt, "Parser", rb_cObject);
620
+ eParserError = rb_path2class("JSON::ParserError");
621
+ eNestingError = rb_path2class("JSON::NestingError");
622
+ rb_define_alloc_func(cParser, cJSON_parser_s_allocate);
623
+ rb_define_method(cParser, "initialize", cParser_initialize, -1);
624
+ rb_define_method(cParser, "parse", cParser_parse, 0);
625
+ rb_define_method(cParser, "source", cParser_source, 0);
626
+
627
+ CNaN = rb_const_get(mJSON, rb_intern("NaN"));
628
+ CInfinity = rb_const_get(mJSON, rb_intern("Infinity"));
629
+ CMinusInfinity = rb_const_get(mJSON, rb_intern("MinusInfinity"));
630
+
631
+ i_json_creatable_p = rb_intern("json_creatable?");
632
+ i_json_create = rb_intern("json_create");
633
+ i_create_id = rb_intern("create_id");
634
+ i_create_additions = rb_intern("create_additions");
635
+ i_chr = rb_intern("chr");
636
+ i_max_nesting = rb_intern("max_nesting");
637
+ i_allow_nan = rb_intern("allow_nan");
638
+ }