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"); }