Example #1
0
VALUE MessagePack_unpack(int argc, VALUE* argv)
{
    VALUE src;

    switch(argc) {
    case 1:
        src = argv[0];
        break;
    default:
        rb_raise(rb_eArgError, "wrong number of arguments (%d for 1)", argc);
    }

    VALUE io = Qnil;
    if(rb_type(src) != T_STRING) {
        io = src;
        src = Qnil;
    }

    VALUE self = Unpacker_alloc(cMessagePack_Unpacker);
    UNPACKER(self, uk);
    //msgpack_unpacker_reset(s_unpacker);
    //msgpack_buffer_reset_io(UNPACKER_BUFFER_(s_unpacker));

    /* prefer reference than copying */
    msgpack_buffer_set_write_reference_threshold(UNPACKER_BUFFER_(uk), 0);

    if(io != Qnil) {
        MessagePack_Buffer_initialize(UNPACKER_BUFFER_(uk), io, Qnil);
    }

    if(src != Qnil) {
        /* prefer reference than copying; see MessagePack_Unpacker_module_init */
        msgpack_buffer_append_string(UNPACKER_BUFFER_(uk), src);
    }

    int r = msgpack_unpacker_read(uk, 0);
    if(r < 0) {
        raise_unpacker_error(r);
    }

    /* raise if extra bytes follow */
    if(msgpack_buffer_top_readable_size(UNPACKER_BUFFER_(uk)) > 0) {
        rb_raise(eMalformedFormatError, "extra bytes follow after a deserialized object");
    }

#ifdef RB_GC_GUARD
    /* This prevents compilers from optimizing out the `self` variable
     * from stack. Otherwise GC free()s it. */
    RB_GC_GUARD(self);
#endif

    return msgpack_unpacker_get_last_object(uk);
}
Example #2
0
void MessagePack_Unpacker_module_init(VALUE mMessagePack)
{
    msgpack_unpacker_static_init();

    cMessagePack_Unpacker = rb_define_class_under(mMessagePack, "Unpacker", rb_cObject);

    eUnpackError = rb_define_class_under(mMessagePack, "UnpackError", rb_eStandardError);

    eMalformedFormatError = rb_define_class_under(mMessagePack, "MalformedFormatError", eUnpackError);

    eStackError = rb_define_class_under(mMessagePack, "StackError", eUnpackError);

    eTypeError = rb_define_class_under(mMessagePack, "TypeError", rb_eStandardError);

    rb_define_alloc_func(cMessagePack_Unpacker, Unpacker_alloc);

    rb_define_method(cMessagePack_Unpacker, "initialize", Unpacker_initialize, -1);
    rb_define_method(cMessagePack_Unpacker, "buffer", Unpacker_buffer, 0);
    rb_define_method(cMessagePack_Unpacker, "read", Unpacker_read, 0);
    rb_define_alias(cMessagePack_Unpacker, "unpack", "read");
    rb_define_method(cMessagePack_Unpacker, "skip", Unpacker_skip, 0);
    rb_define_method(cMessagePack_Unpacker, "skip_nil", Unpacker_skip_nil, 0);
    rb_define_method(cMessagePack_Unpacker, "read_array_header", Unpacker_read_array_header, 0);
    rb_define_method(cMessagePack_Unpacker, "read_map_header", Unpacker_read_map_header, 0);
    //rb_define_method(cMessagePack_Unpacker, "peek_next_type", Unpacker_peek_next_type, 0);  // TODO
    rb_define_method(cMessagePack_Unpacker, "feed", Unpacker_feed, 1);
    rb_define_method(cMessagePack_Unpacker, "each", Unpacker_each, 0);
    rb_define_method(cMessagePack_Unpacker, "feed_each", Unpacker_feed_each, 1);

    s_unpacker_value = Unpacker_alloc(cMessagePack_Unpacker);
    rb_gc_register_address(&s_unpacker_value);
    Data_Get_Struct(s_unpacker_value, msgpack_unpacker_t, s_unpacker);
    /* prefer reference than copying */
    msgpack_buffer_set_write_reference_threshold(UNPACKER_BUFFER_(s_unpacker), 0);

    /* MessagePack.unpack(x) */
    rb_define_module_function(mMessagePack, "load", MessagePack_load_module_method, -1);
    rb_define_module_function(mMessagePack, "unpack", MessagePack_unpack_module_method, -1);
}