ext/json/ext/parser/parser.rl in json_pure-1.1.4 vs ext/json/ext/parser/parser.rl in json_pure-1.1.5
- old
+ new
@@ -25,11 +25,11 @@
static VALUE mJSON, mExt, cParser, eParserError, eNestingError;
static VALUE CNaN, CInfinity, CMinusInfinity;
static ID i_json_creatable_p, i_json_create, i_create_id, i_create_additions,
- i_chr, i_max_nesting, i_allow_nan;
+ i_chr, i_max_nesting, i_allow_nan, i_object_class, i_array_class;
#define MinusInfinity "-Infinity"
typedef struct JSON_ParserStruct {
VALUE Vsource;
@@ -38,10 +38,12 @@
char *memo;
VALUE create_id;
int max_nesting;
int current_nesting;
int allow_nan;
+ VALUE object_class;
+ VALUE array_class;
} JSON_Parser;
static char *JSON_parse_object(JSON_Parser *json, char *p, char *pe, VALUE *result);
static char *JSON_parse_array(JSON_Parser *json, char *p, char *pe, VALUE *result);
static char *JSON_parse_value(JSON_Parser *json, char *p, char *pe, VALUE *result);
@@ -116,16 +118,17 @@
static char *JSON_parse_object(JSON_Parser *json, char *p, char *pe, VALUE *result)
{
int cs = EVIL;
VALUE last_name = Qnil;
+ VALUE object_class = json->object_class;
if (json->max_nesting && json->current_nesting > json->max_nesting) {
rb_raise(eNestingError, "nesting of %d is to deep", json->current_nesting);
}
- *result = rb_hash_new();
+ *result = NIL_P(object_class) ? rb_hash_new() : rb_class_new_instance(0, 0, object_class);
%% write init;
%% write exec;
if (cs >= JSON_object_first_final) {
@@ -328,15 +331,16 @@
}%%
static char *JSON_parse_array(JSON_Parser *json, char *p, char *pe, VALUE *result)
{
int cs = EVIL;
+ VALUE array_class = json->array_class;
if (json->max_nesting && json->current_nesting > json->max_nesting) {
rb_raise(eNestingError, "nesting of %d is to deep", json->current_nesting);
}
- *result = rb_ary_new();
+ *result = NIL_P(array_class) ? rb_ary_new() : rb_class_new_instance(0, 0, array_class);
%% write init;
%% write exec;
if(cs >= JSON_array_first_final) {
@@ -498,10 +502,12 @@
* defiance of RFC 4627 to be parsed by the Parser. This option defaults to
* false.
* * *create_additions*: If set to false, the Parser doesn't create
* additions even if a matchin class and create_id was found. This option
* defaults to true.
+ * * *object_class*: Defaults to Hash
+ * * *array_class*: Defaults to Array
*/
static VALUE cParser_initialize(int argc, VALUE *argv, VALUE self)
{
char *ptr;
long len;
@@ -547,15 +553,29 @@
json->create_id = Qnil;
}
} else {
json->create_id = rb_funcall(mJSON, i_create_id, 0);
}
+ tmp = ID2SYM(i_object_class);
+ if (st_lookup(RHASH_TBL(opts), tmp, 0)) {
+ json->object_class = rb_hash_aref(opts, tmp);
+ } else {
+ json->object_class = Qnil;
+ }
+ tmp = ID2SYM(i_array_class);
+ if (st_lookup(RHASH_TBL(opts), tmp, 0)) {
+ json->array_class = rb_hash_aref(opts, tmp);
+ } else {
+ json->array_class = Qnil;
+ }
}
} else {
json->max_nesting = 19;
json->allow_nan = 0;
json->create_id = rb_funcall(mJSON, i_create_id, 0);
+ json->object_class = Qnil;
+ json->array_class = Qnil;
}
json->current_nesting = 0;
/*
Convert these?
if (len >= 4 && ptr[0] == 0 && ptr[1] == 0 && ptr[2] == 0) {
@@ -608,10 +628,12 @@
static void JSON_mark(JSON_Parser *json)
{
rb_gc_mark_maybe(json->Vsource);
rb_gc_mark_maybe(json->create_id);
+ rb_gc_mark_maybe(json->object_class);
+ rb_gc_mark_maybe(json->array_class);
}
static void JSON_free(JSON_Parser *json)
{
ruby_xfree(json);
@@ -657,6 +679,8 @@
i_create_id = rb_intern("create_id");
i_create_additions = rb_intern("create_additions");
i_chr = rb_intern("chr");
i_max_nesting = rb_intern("max_nesting");
i_allow_nan = rb_intern("allow_nan");
+ i_object_class = rb_intern("object_class");
+ i_array_class = rb_intern("array_class");
}