new (JSON::Ext::Parser)

    /*
     * call-seq: new(source, opts => {})
     *
     * Creates a new JSON::Ext::Parser instance for the string _source_.
     *
     * Creates a new JSON::Ext::Parser instance for the string _source_.
     *
     * It will be configured by the _opts_ hash. _opts_ can have the following
     * keys:
     *
     * _opts_ can have the following keys:
     * * *max_nesting*: The maximum depth of nesting allowed in the parsed data
     *   structures. Disable depth checking with :max_nesting => false|nil|0, it
     *   defaults to 19.
     * * *allow_nan*: If set to true, allow NaN, Infinity and -Infinity in
     *   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.
     */
    static VALUE cParser_initialize(int argc, VALUE *argv, VALUE self)
    {
        char *ptr;
        long len;
        VALUE source, opts;
        GET_STRUCT;
        rb_scan_args(argc, argv, "11", &source, &opts);
        source = StringValue(source);
        ptr = RSTRING_PTR(source);
        len = RSTRING_LEN(source);
        if (len < 2) {
            rb_raise(eParserError, "A JSON text must at least contain two octets!");
        }
        if (!NIL_P(opts)) {
            opts = rb_convert_type(opts, T_HASH, "Hash", "to_hash");
            if (NIL_P(opts)) {
                rb_raise(rb_eArgError, "opts needs to be like a hash");
            } else {
                VALUE tmp = ID2SYM(i_max_nesting);
                if (st_lookup(RHASH(opts)->tbl, tmp, 0)) {
                    VALUE max_nesting = rb_hash_aref(opts, tmp);
                    if (RTEST(max_nesting)) {
                        Check_Type(max_nesting, T_FIXNUM);
                        json->max_nesting = FIX2INT(max_nesting);
                    } else {
                        json->max_nesting = 0;
                    }
                } else {
                    json->max_nesting = 19;
                }
                tmp = ID2SYM(i_allow_nan);
                if (st_lookup(RHASH(opts)->tbl, tmp, 0)) {
                    VALUE allow_nan = rb_hash_aref(opts, tmp);
                    json->allow_nan = RTEST(allow_nan) ? 1 : 0;
                } else {
                    json->allow_nan = 0;
                }
                tmp = ID2SYM(i_create_additions);
                if (st_lookup(RHASH(opts)->tbl, tmp, 0)) {
                    VALUE create_additions = rb_hash_aref(opts, tmp);
                    if (RTEST(create_additions)) {
                        json->create_id = rb_funcall(mJSON, i_create_id, 0);
                    } else {
                        json->create_id = Qnil;
                    }
                } else {
                    json->create_id = rb_funcall(mJSON, i_create_id, 0);
                }
            }
        } else {
            json->max_nesting = 19;
            json->allow_nan = 0;
            json->create_id = rb_funcall(mJSON, i_create_id, 0);
        }
        json->current_nesting = 0;
        /*
           Convert these?
        if (len >= 4 &&  ptr[0] == 0 && ptr[1] == 0 && ptr[2] == 0) {
            rb_raise(eParserError, "Only UTF8 octet streams are supported atm!");
        } else if (len >= 4 && ptr[0] == 0 && ptr[2] == 0) {
            rb_raise(eParserError, "Only UTF8 octet streams are supported atm!");
        } else if (len >= 4 && ptr[1] == 0 && ptr[2] == 0 && ptr[3] == 0) {
            rb_raise(eParserError, "Only UTF8 octet streams are supported atm!");
        } else if (len >= 4 && ptr[1] == 0 && ptr[3] == 0) {
            rb_raise(eParserError, "Only UTF8 octet streams are supported atm!");
        }
        */
        json->len = len;
        json->source = ptr;
        json->Vsource = source;
        return self;
    }