summaryrefslogtreecommitdiff
path: root/ext/json/ext/parser/parser.rl
diff options
context:
space:
mode:
Diffstat (limited to 'ext/json/ext/parser/parser.rl')
-rw-r--r--ext/json/ext/parser/parser.rl34
1 files changed, 29 insertions, 5 deletions
diff --git a/ext/json/ext/parser/parser.rl b/ext/json/ext/parser/parser.rl
index ca1876a7fc..384ab9f42f 100644
--- a/ext/json/ext/parser/parser.rl
+++ b/ext/json/ext/parser/parser.rl
@@ -27,7 +27,7 @@ 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"
@@ -40,6 +40,8 @@ typedef struct JSON_ParserStruct {
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);
@@ -118,12 +120,13 @@ static char *JSON_parse_object(JSON_Parser *json, char *p, char *pe, VALUE *resu
{
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);
+ rb_raise(eNestingError, "nesting of %d is too 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;
@@ -330,11 +333,12 @@ static char *JSON_parse_float(JSON_Parser *json, char *p, char *pe, VALUE *resul
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);
+ rb_raise(eNestingError, "nesting of %d is too 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;
@@ -500,6 +504,8 @@ static char *JSON_parse_string(JSON_Parser *json, char *p, char *pe, VALUE *resu
* * *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)
{
@@ -549,11 +555,25 @@ static VALUE cParser_initialize(int argc, VALUE *argv, VALUE self)
} 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;
/*
@@ -610,6 +630,8 @@ 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)
@@ -659,4 +681,6 @@ void Init_parser()
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");
}