class YAJI::Parser

Constants

READ_BUFFER_SIZE

Public Class Methods

new(p1 = v1, p2 = v2) click to toggle source
static VALUE rb_yaji_parser_new(int argc, VALUE *argv, VALUE klass)
{
        yaji_parser* p;
        VALUE opts, obj;

        obj = Data_Make_Struct(klass, yaji_parser, rb_yaji_parser_mark, rb_yaji_parser_free, p);
        p->handle = NULL;
        p->config.allowComments = 1;
        p->config.checkUTF8 = 1;
        p->symbolize_keys = 0;
        p->with_path = 0;
        p->filter = Qnil;
        p->rbufsize = Qnil;
        p->input = Qnil;
        p->parser_cb = Qnil;
        p->on_object_cb = Qnil;

        rb_scan_args(argc, argv, "02", &p->input, &opts);
        if (NIL_P(opts) && TYPE(p->input) == T_HASH) {
                opts = p->input;
                p->input = Qnil;
        }
        if (!NIL_P(p->input)) {
                if (TYPE(p->input) == T_STRING) {
                        p->input = rb_class_new_instance(1, &p->input, c_stringio);
                } else if (rb_respond_to(p->input, id_perform) && rb_respond_to(p->input, id_on_body)) {
                        rb_block_call(p->input, id_on_body, 0, NULL, rb_yaji_parser_parse_chunk, obj);
                } else if (!rb_respond_to(p->input, id_read)) {
                        rb_raise(c_parse_error, "input must be a String or IO or "
                                 "something responding to #perform and #on_body e.g. Curl::Easy");
                }
        }
        if (!NIL_P(opts)) {
                Check_Type(opts, T_HASH);
                if (rb_hash_aref(opts, sym_allow_comments) == Qfalse) {
                        p->config.allowComments = 0;
                }
                if (rb_hash_aref(opts, sym_check_utf8) == Qfalse) {
                        p->config.checkUTF8 = 0;
                }
                if (rb_hash_aref(opts, sym_symbolize_keys) == Qtrue) {
                        p->symbolize_keys = 1;
                }
                p->rbufsize = rb_hash_aref(opts, sym_read_buffer_size);
                if (rb_hash_aref(opts, sym_with_path) == Qtrue) {
                        p->with_path = 1;
                }
                p->filter = rb_hash_aref(opts, sym_filter);
        }
        if (NIL_P(p->rbufsize)) {
                p->rbufsize = INT2FIX(READ_BUFSIZE);
        } else {
                Check_Type(p->rbufsize, T_FIXNUM);
        }
        p->object_stack = rb_ary_new();
        p->path = rb_ary_new();
        rb_ary_push(p->path, rb_str_new("", 0));
        p->path_str = rb_str_new("", 0);
        p->handle = yajl_alloc(&yaji_callbacks, &p->config, NULL, (void *)obj);
        rb_obj_call_init(obj, 0, 0);
        return obj;
}

Public Instance Methods

<<(p1)
Alias for: write
each(p1 = v1, p2 = v2, &block) click to toggle source
static VALUE rb_yaji_parser_each(int argc, VALUE* argv, VALUE self)
{
        VALUE filter, proc, options;
        yaji_parser* p = (yaji_parser*) DATA_PTR(self);

        if (NIL_P(p->input)) {
                rb_raise(rb_eArgError, "input object required to use #each method");
        }
        RETURN_ENUMERATOR(self, argc, argv);
        rb_scan_args(argc, argv, "02&", &filter, &options, &proc);
        p->effective_proc = proc;
        p->object_stack = rb_ary_new();
        if (NIL_P(filter)) {
                p->effective_filter = p->filter;
        } else {
                p->effective_filter = filter;
        }
        p->effective_with_path = p->with_path ? Qtrue : Qfalse;
        if (options != Qnil) {
                VALUE arg;
                Check_Type(options, T_HASH);
                arg = rb_hash_aref(options, sym_with_path);
                if (!NIL_P(arg)) {
                        p->effective_with_path = arg;
                }
        }
        rb_block_call(self, id_parse, 0, NULL, rb_yaji_each_iter, self);
        return Qnil;
}
on_object() click to toggle source
static VALUE rb_yaji_parser_on_object(VALUE self)
{
        yaji_parser *p = DATA_PTR(self);

        if (rb_block_given_p()) {
                p->on_object_cb = rb_block_proc();
        }
        return p->on_object_cb;
}
parse(&block) click to toggle source
static VALUE rb_yaji_parser_parse(int argc, VALUE* argv, VALUE self)
{
        yajl_status rc;
        yaji_parser* p = (yaji_parser*) DATA_PTR(self);
        int i;

        if (NIL_P(p->input)) {
                rb_raise(rb_eArgError, "input object required to use #parse method");
        }
        rb_scan_args(argc, argv, "00&", &p->parser_cb);
        RETURN_ENUMERATOR(self, argc, argv);

        p->chunk = Qnil;

        if (rb_respond_to(p->input, id_perform)) {
                rb_funcall(p->input, id_perform, 0);
        } else {
                p->chunk = rb_str_new(NULL, 0);
                while (rb_funcall(p->input, id_read, 2, p->rbufsize, p->chunk) != Qnil) {
                        rb_yaji_parser_parse_chunk(p->chunk, self);
                }
        }

        p->events = rb_ary_new();
        rc = yajl_parse_complete(p->handle);

        if (rc == yajl_status_error ||
                        (rc == yajl_status_insufficient_data && p->chunk != Qnil &&
                         RSTRING_LEN(rb_funcall(p->chunk, id_strip, 0)) != 0)) {
                RERAISE_PARSER_ERROR(p);
        }
        for (i=0; i<RARRAY_LEN(p->events); i++) {
                rb_funcall(p->parser_cb, id_call, 1, RARRAY_PTR(p->events)[i]);
        }

        return Qnil;
}
write(p1) click to toggle source
static VALUE rb_yaji_parser_write(VALUE self, VALUE val)
{
        yaji_parser* p = (yaji_parser*) DATA_PTR(self);

        if (NIL_P(p->on_object_cb)) {
                rb_raise(rb_eArgError, "#on_object callback required");
        }
        if (!NIL_P(val)) {
                Check_Type(val, T_STRING);
        }
        return rb_yaji_parser_parse_chunk(val, self);
}
Also aliased as: <<