json 1.0.3-mswin32
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 +32 -0
- data/GPL +340 -0
- data/README +77 -0
- data/Rakefile +304 -0
- data/TODO +1 -0
- data/VERSION +1 -0
- 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/bin/edit_json.rb +11 -0
- data/bin/prettify_json.rb +75 -0
- data/data/example.json +1 -0
- data/data/index.html +37 -0
- data/data/prototype.js +2515 -0
- data/ext/json/ext/generator.so +0 -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.so +0 -0
- data/ext/json/ext/parser/extconf.rb +9 -0
- data/ext/json/ext/parser/parser.c +1554 -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 +26 -0
- data/lib/json.rb +205 -0
- data/lib/json/Array.xpm +21 -0
- data/lib/json/FalseClass.xpm +21 -0
- data/lib/json/Hash.xpm +21 -0
- data/lib/json/Key.xpm +73 -0
- data/lib/json/NilClass.xpm +21 -0
- data/lib/json/Numeric.xpm +28 -0
- data/lib/json/String.xpm +96 -0
- data/lib/json/TrueClass.xpm +21 -0
- data/lib/json/common.rb +184 -0
- data/lib/json/editor.rb +1207 -0
- data/lib/json/ext.rb +13 -0
- data/lib/json/json.xpm +1499 -0
- data/lib/json/pure.rb +75 -0
- data/lib/json/pure/generator.rb +321 -0
- data/lib/json/pure/parser.rb +214 -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 +24 -0
- data/tests/test_json.rb +236 -0
- 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 +58 -0
- data/tools/fuzz.rb +131 -0
- data/tools/server.rb +62 -0
- metadata +149 -0
@@ -0,0 +1,515 @@
|
|
1
|
+
/* vim: set cin et sw=4 ts=4: */
|
2
|
+
|
3
|
+
#include "ruby.h"
|
4
|
+
#include "re.h"
|
5
|
+
#include "unicode.h"
|
6
|
+
|
7
|
+
#ifndef swap16
|
8
|
+
#define swap16(x) ((((x)&0xFF)<<8) | (((x)>>8)&0xFF))
|
9
|
+
#endif
|
10
|
+
|
11
|
+
#define EVIL 0x666
|
12
|
+
|
13
|
+
static VALUE mJSON, mExt, cParser, eParserError;
|
14
|
+
|
15
|
+
static ID i_json_creatable_p, i_json_create, i_create_id, i_chr;
|
16
|
+
|
17
|
+
typedef struct JSON_ParserStruct {
|
18
|
+
VALUE Vsource;
|
19
|
+
char *source;
|
20
|
+
long len;
|
21
|
+
char *memo;
|
22
|
+
VALUE create_id;
|
23
|
+
} JSON_Parser;
|
24
|
+
|
25
|
+
static char *JSON_parse_object(JSON_Parser *json, char *p, char *pe, VALUE *result);
|
26
|
+
static char *JSON_parse_array(JSON_Parser *json, char *p, char *pe, VALUE *result);
|
27
|
+
static char *JSON_parse_value(JSON_Parser *json, char *p, char *pe, VALUE *result);
|
28
|
+
static char *JSON_parse_string(JSON_Parser *json, char *p, char *pe, VALUE *result);
|
29
|
+
static char *JSON_parse_integer(JSON_Parser *json, char *p, char *pe, VALUE *result);
|
30
|
+
static char *JSON_parse_float(JSON_Parser *json, char *p, char *pe, VALUE *result);
|
31
|
+
|
32
|
+
#define GET_STRUCT \
|
33
|
+
JSON_Parser *json; \
|
34
|
+
Data_Get_Struct(self, JSON_Parser, json);
|
35
|
+
|
36
|
+
%%{
|
37
|
+
machine JSON_common;
|
38
|
+
|
39
|
+
cr = '\n';
|
40
|
+
cr_neg = [^\n];
|
41
|
+
ws = [ \t\r\n];
|
42
|
+
c_comment = '/*' ( any* - (any* '*/' any* ) ) '*/';
|
43
|
+
cpp_comment = '//' cr_neg* cr;
|
44
|
+
comment = c_comment | cpp_comment;
|
45
|
+
ignore = ws | comment;
|
46
|
+
name_separator = ':';
|
47
|
+
value_separator = ',';
|
48
|
+
Vnull = 'null';
|
49
|
+
Vfalse = 'false';
|
50
|
+
Vtrue = 'true';
|
51
|
+
begin_value = [nft"\-[{] | digit;
|
52
|
+
begin_object = '{';
|
53
|
+
end_object = '}';
|
54
|
+
begin_array = '[';
|
55
|
+
end_array = ']';
|
56
|
+
begin_string = '"';
|
57
|
+
begin_name = begin_string;
|
58
|
+
begin_number = digit | '-';
|
59
|
+
}%%
|
60
|
+
|
61
|
+
%%{
|
62
|
+
machine JSON_object;
|
63
|
+
include JSON_common;
|
64
|
+
|
65
|
+
write data;
|
66
|
+
|
67
|
+
action parse_value {
|
68
|
+
VALUE v = Qnil;
|
69
|
+
char *np = JSON_parse_value(json, fpc, pe, &v);
|
70
|
+
if (np == NULL) {
|
71
|
+
fbreak;
|
72
|
+
} else {
|
73
|
+
rb_hash_aset(*result, last_name, v);
|
74
|
+
fexec np;
|
75
|
+
}
|
76
|
+
}
|
77
|
+
|
78
|
+
action parse_name {
|
79
|
+
char *np = JSON_parse_string(json, fpc, pe, &last_name);
|
80
|
+
if (np == NULL) fbreak; else fexec np;
|
81
|
+
}
|
82
|
+
|
83
|
+
action exit { fbreak; }
|
84
|
+
|
85
|
+
a_pair = ignore* begin_name >parse_name
|
86
|
+
ignore* name_separator ignore*
|
87
|
+
begin_value >parse_value;
|
88
|
+
|
89
|
+
main := begin_object
|
90
|
+
(a_pair (ignore* value_separator a_pair)*)?
|
91
|
+
ignore* end_object @exit;
|
92
|
+
}%%
|
93
|
+
|
94
|
+
static char *JSON_parse_object(JSON_Parser *json, char *p, char *pe, VALUE *result)
|
95
|
+
{
|
96
|
+
int cs = EVIL;
|
97
|
+
VALUE last_name = Qnil;
|
98
|
+
*result = rb_hash_new();
|
99
|
+
|
100
|
+
%% write init;
|
101
|
+
%% write exec;
|
102
|
+
|
103
|
+
if (cs >= JSON_object_first_final) {
|
104
|
+
VALUE klassname = rb_hash_aref(*result, json->create_id);
|
105
|
+
if (!NIL_P(klassname)) {
|
106
|
+
VALUE klass = rb_path2class(StringValueCStr(klassname));
|
107
|
+
if RTEST(rb_funcall(klass, i_json_creatable_p, 0)) {
|
108
|
+
*result = rb_funcall(klass, i_json_create, 1, *result);
|
109
|
+
}
|
110
|
+
}
|
111
|
+
return p + 1;
|
112
|
+
} else {
|
113
|
+
return NULL;
|
114
|
+
}
|
115
|
+
}
|
116
|
+
|
117
|
+
%%{
|
118
|
+
machine JSON_value;
|
119
|
+
include JSON_common;
|
120
|
+
|
121
|
+
write data;
|
122
|
+
|
123
|
+
action parse_null {
|
124
|
+
*result = Qnil;
|
125
|
+
}
|
126
|
+
action parse_false {
|
127
|
+
*result = Qfalse;
|
128
|
+
}
|
129
|
+
action parse_true {
|
130
|
+
*result = Qtrue;
|
131
|
+
}
|
132
|
+
action parse_string {
|
133
|
+
char *np = JSON_parse_string(json, fpc, pe, result);
|
134
|
+
if (np == NULL) fbreak; else fexec np;
|
135
|
+
}
|
136
|
+
|
137
|
+
action parse_number {
|
138
|
+
char *np;
|
139
|
+
np = JSON_parse_float(json, fpc, pe, result);
|
140
|
+
if (np != NULL) fexec np;
|
141
|
+
np = JSON_parse_integer(json, fpc, pe, result);
|
142
|
+
if (np != NULL) fexec np;
|
143
|
+
fbreak;
|
144
|
+
}
|
145
|
+
|
146
|
+
action parse_array {
|
147
|
+
char *np = JSON_parse_array(json, fpc, pe, result);
|
148
|
+
if (np == NULL) fbreak; else fexec np;
|
149
|
+
}
|
150
|
+
|
151
|
+
action parse_object {
|
152
|
+
char *np = JSON_parse_object(json, fpc, pe, result);
|
153
|
+
if (np == NULL) fbreak; else fexec np;
|
154
|
+
}
|
155
|
+
|
156
|
+
action exit { fbreak; }
|
157
|
+
|
158
|
+
main := (
|
159
|
+
Vnull @parse_null |
|
160
|
+
Vfalse @parse_false |
|
161
|
+
Vtrue @parse_true |
|
162
|
+
begin_number >parse_number |
|
163
|
+
begin_string >parse_string |
|
164
|
+
begin_array >parse_array |
|
165
|
+
begin_object >parse_object
|
166
|
+
) %*exit;
|
167
|
+
}%%
|
168
|
+
|
169
|
+
static char *JSON_parse_value(JSON_Parser *json, char *p, char *pe, VALUE *result)
|
170
|
+
{
|
171
|
+
int cs = EVIL;
|
172
|
+
|
173
|
+
%% write init;
|
174
|
+
%% write exec;
|
175
|
+
|
176
|
+
if (cs >= JSON_value_first_final) {
|
177
|
+
return p;
|
178
|
+
} else {
|
179
|
+
return NULL;
|
180
|
+
}
|
181
|
+
}
|
182
|
+
|
183
|
+
%%{
|
184
|
+
machine JSON_integer;
|
185
|
+
|
186
|
+
write data;
|
187
|
+
|
188
|
+
action exit { fbreak; }
|
189
|
+
|
190
|
+
main := '-'? ('0' | [1-9][0-9]*) (^[0-9] @exit);
|
191
|
+
}%%
|
192
|
+
|
193
|
+
static char *JSON_parse_integer(JSON_Parser *json, char *p, char *pe, VALUE *result)
|
194
|
+
{
|
195
|
+
int cs = EVIL;
|
196
|
+
|
197
|
+
%% write init;
|
198
|
+
json->memo = p;
|
199
|
+
%% write exec;
|
200
|
+
|
201
|
+
if (cs >= JSON_integer_first_final) {
|
202
|
+
long len = p - json->memo;
|
203
|
+
*result = rb_Integer(rb_str_new(json->memo, len));
|
204
|
+
return p + 1;
|
205
|
+
} else {
|
206
|
+
return NULL;
|
207
|
+
}
|
208
|
+
}
|
209
|
+
|
210
|
+
%%{
|
211
|
+
machine JSON_float;
|
212
|
+
include JSON_common;
|
213
|
+
|
214
|
+
write data;
|
215
|
+
|
216
|
+
action exit { fbreak; }
|
217
|
+
|
218
|
+
main := '-'? (
|
219
|
+
(('0' | [1-9][0-9]*) '.' [0-9]+ ([Ee] [+\-]?[0-9]+)?)
|
220
|
+
| (('0' | [1-9][0-9]*) ([Ee] [+\-]?[0-9]+))
|
221
|
+
) (^[0-9Ee.\-] @exit );
|
222
|
+
}%%
|
223
|
+
|
224
|
+
static char *JSON_parse_float(JSON_Parser *json, char *p, char *pe, VALUE *result)
|
225
|
+
{
|
226
|
+
int cs = EVIL;
|
227
|
+
|
228
|
+
%% write init;
|
229
|
+
json->memo = p;
|
230
|
+
%% write exec;
|
231
|
+
|
232
|
+
if (cs >= JSON_float_first_final) {
|
233
|
+
long len = p - json->memo;
|
234
|
+
*result = rb_Float(rb_str_new(json->memo, len));
|
235
|
+
return p + 1;
|
236
|
+
} else {
|
237
|
+
return NULL;
|
238
|
+
}
|
239
|
+
}
|
240
|
+
|
241
|
+
|
242
|
+
%%{
|
243
|
+
machine JSON_array;
|
244
|
+
include JSON_common;
|
245
|
+
|
246
|
+
write data;
|
247
|
+
|
248
|
+
action parse_value {
|
249
|
+
VALUE v = Qnil;
|
250
|
+
char *np = JSON_parse_value(json, fpc, pe, &v);
|
251
|
+
if (np == NULL) {
|
252
|
+
fbreak;
|
253
|
+
} else {
|
254
|
+
rb_ary_push(*result, v);
|
255
|
+
fexec np;
|
256
|
+
}
|
257
|
+
}
|
258
|
+
|
259
|
+
action exit { fbreak; }
|
260
|
+
|
261
|
+
next_element = value_separator ignore* begin_value >parse_value;
|
262
|
+
|
263
|
+
main := begin_array ignore*
|
264
|
+
((begin_value >parse_value ignore*)
|
265
|
+
(ignore* next_element ignore*)*)?
|
266
|
+
end_array @exit;
|
267
|
+
}%%
|
268
|
+
|
269
|
+
static char *JSON_parse_array(JSON_Parser *json, char *p, char *pe, VALUE *result)
|
270
|
+
{
|
271
|
+
int cs = EVIL;
|
272
|
+
*result = rb_ary_new();
|
273
|
+
|
274
|
+
%% write init;
|
275
|
+
%% write exec;
|
276
|
+
|
277
|
+
if(cs >= JSON_array_first_final) {
|
278
|
+
return p + 1;
|
279
|
+
} else {
|
280
|
+
rb_raise(eParserError, "unexpected token at '%s'", p);
|
281
|
+
}
|
282
|
+
}
|
283
|
+
|
284
|
+
static VALUE json_string_escape(char *p, char *pe)
|
285
|
+
{
|
286
|
+
VALUE result = rb_str_buf_new(pe - p + 1);
|
287
|
+
|
288
|
+
while (p < pe) {
|
289
|
+
if (*p == '\\') {
|
290
|
+
p++;
|
291
|
+
if (p >= pe) return Qnil; /* raise an exception later, \ at end */
|
292
|
+
switch (*p) {
|
293
|
+
case '"':
|
294
|
+
case '\\':
|
295
|
+
rb_str_buf_cat(result, p, 1);
|
296
|
+
p++;
|
297
|
+
break;
|
298
|
+
case 'b':
|
299
|
+
rb_str_buf_cat2(result, "\b");
|
300
|
+
p++;
|
301
|
+
break;
|
302
|
+
case 'f':
|
303
|
+
rb_str_buf_cat2(result, "\f");
|
304
|
+
p++;
|
305
|
+
break;
|
306
|
+
case 'n':
|
307
|
+
rb_str_buf_cat2(result, "\n");
|
308
|
+
p++;
|
309
|
+
break;
|
310
|
+
case 'r':
|
311
|
+
rb_str_buf_cat2(result, "\r");
|
312
|
+
p++;
|
313
|
+
break;
|
314
|
+
case 't':
|
315
|
+
rb_str_buf_cat2(result, "\t");
|
316
|
+
p++;
|
317
|
+
break;
|
318
|
+
case 'u':
|
319
|
+
if (p > pe - 4) {
|
320
|
+
return Qnil;
|
321
|
+
} else {
|
322
|
+
p = JSON_convert_UTF16_to_UTF8(result, p, pe, strictConversion);
|
323
|
+
}
|
324
|
+
break;
|
325
|
+
}
|
326
|
+
} else {
|
327
|
+
char *q = p;
|
328
|
+
while (*q != '\\' && q < pe) q++;
|
329
|
+
rb_str_buf_cat(result, p, q - p);
|
330
|
+
p = q;
|
331
|
+
}
|
332
|
+
}
|
333
|
+
return result;
|
334
|
+
}
|
335
|
+
|
336
|
+
%%{
|
337
|
+
machine JSON_string;
|
338
|
+
include JSON_common;
|
339
|
+
|
340
|
+
write data;
|
341
|
+
|
342
|
+
action parse_string {
|
343
|
+
*result = json_string_escape(json->memo + 1, p);
|
344
|
+
if (NIL_P(*result)) fbreak; else fexec p + 1;
|
345
|
+
}
|
346
|
+
|
347
|
+
action exit { fbreak; }
|
348
|
+
|
349
|
+
main := '"' ((^(["\\] | 0..0x1f) | '\\'["\\/bfnrt] | '\\u'[0-9a-fA-F]{4})* %parse_string) '"' @exit;
|
350
|
+
}%%
|
351
|
+
|
352
|
+
static char *JSON_parse_string(JSON_Parser *json, char *p, char *pe, VALUE *result)
|
353
|
+
{
|
354
|
+
int cs = EVIL;
|
355
|
+
|
356
|
+
*result = rb_str_new("", 0);
|
357
|
+
%% write init;
|
358
|
+
json->memo = p;
|
359
|
+
%% write exec;
|
360
|
+
|
361
|
+
if (cs >= JSON_string_first_final) {
|
362
|
+
return p + 1;
|
363
|
+
} else {
|
364
|
+
return NULL;
|
365
|
+
}
|
366
|
+
}
|
367
|
+
|
368
|
+
|
369
|
+
%%{
|
370
|
+
machine JSON;
|
371
|
+
|
372
|
+
write data;
|
373
|
+
|
374
|
+
include JSON_common;
|
375
|
+
|
376
|
+
action parse_object {
|
377
|
+
char *np = JSON_parse_object(json, fpc, pe, &result);
|
378
|
+
if (np == NULL) fbreak; else fexec np;
|
379
|
+
}
|
380
|
+
|
381
|
+
action parse_array {
|
382
|
+
char *np = JSON_parse_array(json, fpc, pe, &result);
|
383
|
+
if (np == NULL) fbreak; else fexec np;
|
384
|
+
}
|
385
|
+
|
386
|
+
main := ignore* (
|
387
|
+
begin_object >parse_object |
|
388
|
+
begin_array >parse_array
|
389
|
+
) ignore*;
|
390
|
+
}%%
|
391
|
+
|
392
|
+
/*
|
393
|
+
* Document-class: JSON::Ext::Parser
|
394
|
+
*
|
395
|
+
* This is the JSON parser implemented as a C extension. It can be configured
|
396
|
+
* to be used by setting
|
397
|
+
*
|
398
|
+
* JSON.parser = JSON::Ext::Parser
|
399
|
+
*
|
400
|
+
* with the method parser= in JSON.
|
401
|
+
*
|
402
|
+
*/
|
403
|
+
|
404
|
+
/*
|
405
|
+
* call-seq: new(source)
|
406
|
+
*
|
407
|
+
* Creates a new JSON::Ext::Parser instance for the string _source_.
|
408
|
+
*/
|
409
|
+
static VALUE cParser_initialize(VALUE self, VALUE source)
|
410
|
+
{
|
411
|
+
char *ptr;
|
412
|
+
long len;
|
413
|
+
GET_STRUCT;
|
414
|
+
source = StringValue(source);
|
415
|
+
ptr = RSTRING(source)->ptr;
|
416
|
+
len = RSTRING(source)->len;
|
417
|
+
if (len < 2) {
|
418
|
+
rb_raise(eParserError, "A JSON text must at least contain two octets!");
|
419
|
+
}
|
420
|
+
/*
|
421
|
+
Convert these?
|
422
|
+
if (len >= 4 && ptr[0] == 0 && ptr[1] == 0 && ptr[2] == 0) {
|
423
|
+
rb_raise(eParserError, "Only UTF8 octet streams are supported atm!");
|
424
|
+
} else if (len >= 4 && ptr[0] == 0 && ptr[2] == 0) {
|
425
|
+
rb_raise(eParserError, "Only UTF8 octet streams are supported atm!");
|
426
|
+
} else if (len >= 4 && ptr[1] == 0 && ptr[2] == 0 && ptr[3] == 0) {
|
427
|
+
rb_raise(eParserError, "Only UTF8 octet streams are supported atm!");
|
428
|
+
} else if (len >= 4 && ptr[1] == 0 && ptr[3] == 0) {
|
429
|
+
rb_raise(eParserError, "Only UTF8 octet streams are supported atm!");
|
430
|
+
}
|
431
|
+
*/
|
432
|
+
json->len = len;
|
433
|
+
json->source = ptr;
|
434
|
+
json->Vsource = source;
|
435
|
+
json->create_id = rb_funcall(mJSON, i_create_id, 0);
|
436
|
+
return self;
|
437
|
+
}
|
438
|
+
|
439
|
+
/*
|
440
|
+
* call-seq: parse()
|
441
|
+
*
|
442
|
+
* Parses the current JSON text _source_ and returns the complete data
|
443
|
+
* structure as a result.
|
444
|
+
*/
|
445
|
+
static VALUE cParser_parse(VALUE self)
|
446
|
+
{
|
447
|
+
char *p, *pe;
|
448
|
+
int cs = EVIL;
|
449
|
+
VALUE result = Qnil;
|
450
|
+
GET_STRUCT;
|
451
|
+
|
452
|
+
%% write init;
|
453
|
+
p = json->source;
|
454
|
+
pe = p + json->len;
|
455
|
+
%% write exec;
|
456
|
+
|
457
|
+
if (cs >= JSON_first_final && p == pe) {
|
458
|
+
return result;
|
459
|
+
} else {
|
460
|
+
rb_raise(eParserError, "unexpected token at '%s'", p);
|
461
|
+
}
|
462
|
+
}
|
463
|
+
|
464
|
+
static JSON_Parser *JSON_allocate()
|
465
|
+
{
|
466
|
+
JSON_Parser *json = ALLOC(JSON_Parser);
|
467
|
+
MEMZERO(json, JSON_Parser, 1);
|
468
|
+
return json;
|
469
|
+
}
|
470
|
+
|
471
|
+
static void JSON_mark(JSON_Parser *json)
|
472
|
+
{
|
473
|
+
rb_gc_mark_maybe(json->Vsource);
|
474
|
+
rb_gc_mark_maybe(json->create_id);
|
475
|
+
}
|
476
|
+
|
477
|
+
static void JSON_free(JSON_Parser *json)
|
478
|
+
{
|
479
|
+
free(json);
|
480
|
+
}
|
481
|
+
|
482
|
+
static VALUE cJSON_parser_s_allocate(VALUE klass)
|
483
|
+
{
|
484
|
+
JSON_Parser *json = JSON_allocate();
|
485
|
+
return Data_Wrap_Struct(klass, JSON_mark, JSON_free, json);
|
486
|
+
}
|
487
|
+
|
488
|
+
/*
|
489
|
+
* call-seq: source()
|
490
|
+
*
|
491
|
+
* Returns a copy of the current _source_ string, that was used to construct
|
492
|
+
* this Parser.
|
493
|
+
*/
|
494
|
+
static VALUE cParser_source(VALUE self)
|
495
|
+
{
|
496
|
+
GET_STRUCT;
|
497
|
+
return rb_str_dup(json->Vsource);
|
498
|
+
}
|
499
|
+
|
500
|
+
void Init_parser()
|
501
|
+
{
|
502
|
+
mJSON = rb_define_module("JSON");
|
503
|
+
mExt = rb_define_module_under(mJSON, "Ext");
|
504
|
+
cParser = rb_define_class_under(mExt, "Parser", rb_cObject);
|
505
|
+
eParserError = rb_path2class("JSON::ParserError");
|
506
|
+
rb_define_alloc_func(cParser, cJSON_parser_s_allocate);
|
507
|
+
rb_define_method(cParser, "initialize", cParser_initialize, 1);
|
508
|
+
rb_define_method(cParser, "parse", cParser_parse, 0);
|
509
|
+
rb_define_method(cParser, "source", cParser_source, 0);
|
510
|
+
|
511
|
+
i_json_creatable_p = rb_intern("json_creatable?");
|
512
|
+
i_json_create = rb_intern("json_create");
|
513
|
+
i_create_id = rb_intern("create_id");
|
514
|
+
i_chr = rb_intern("chr");
|
515
|
+
}
|