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); }
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; } // TODO create an instance if io is set for thread safety? //VALUE self = Unpacker_alloc(cMessagePack_Unpacker); //UNPACKER(self, uk); msgpack_unpacker_reset(s_unpacker); msgpack_buffer_reset_io(UNPACKER_BUFFER_(s_unpacker)); if(io != Qnil) { MessagePack_Buffer_initialize(UNPACKER_BUFFER_(s_unpacker), io, Qnil); } if(src != Qnil) { /* prefer reference than copying; see MessagePack_Unpacker_module_init */ msgpack_buffer_append_string(UNPACKER_BUFFER_(s_unpacker), src); } int r = msgpack_unpacker_read(s_unpacker, 0); if(r < 0) { raise_unpacker_error(r); } /* raise if extra bytes follow */ if(msgpack_buffer_top_readable_size(UNPACKER_BUFFER_(s_unpacker)) > 0) { rb_raise(eMalformedFormatError, "extra bytes follow after a deserialized object"); } return msgpack_unpacker_get_last_object(s_unpacker); }
static VALUE Unpacker_feed(VALUE self, VALUE data) { UNPACKER(self, uk); StringValue(data); msgpack_buffer_append_string(UNPACKER_BUFFER_(uk), data); return self; }
static VALUE Unpacker_alloc(VALUE klass) { msgpack_unpacker_t* uk = ALLOC_N(msgpack_unpacker_t, 1); msgpack_unpacker_init(uk); VALUE self = Data_Wrap_Struct(klass, msgpack_unpacker_mark, Unpacker_free, uk); uk->buffer_ref = MessagePack_Buffer_wrap(UNPACKER_BUFFER_(uk), self); return self; }
VALUE MessagePack_unpack(int argc, VALUE* argv) { VALUE src; VALUE self; if (argc < 0 || argc > 2) { rb_raise(rb_eArgError, "wrong number of arguments (%d for 1..2)", argc); } src = argv[0]; if(rb_type(src) == T_STRING) { self = MessagePack_Factory_unpacker(argc - 1, argv + 1, cMessagePack_DefaultFactory); UNPACKER(self, uk); msgpack_buffer_append_string(UNPACKER_BUFFER_(uk), src); } else { self = MessagePack_Factory_unpacker(argc, argv, cMessagePack_DefaultFactory); } UNPACKER(self, uk); /* prefer reference than copying; see MessagePack_Unpacker_module_init */ msgpack_buffer_set_write_reference_threshold(UNPACKER_BUFFER_(uk), 0); int r = msgpack_unpacker_read(uk, 0); if(r < 0) { raise_unpacker_error(r); } /* raise if extra bytes follow */ size_t extra = msgpack_buffer_top_readable_size(UNPACKER_BUFFER_(uk)); if(extra > 0) { rb_raise(eMalformedFormatError, "%zd extra bytes after the deserialized object", extra); } #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); }
static VALUE Unpacker_each(VALUE self) { UNPACKER(self, uk); #ifdef RETURN_ENUMERATOR RETURN_ENUMERATOR(self, 0, 0); #endif if(msgpack_buffer_has_io(UNPACKER_BUFFER_(uk))) { return Unpacker_each_impl(self); } else { /* rescue EOFError only if io is set */ return rb_rescue2(Unpacker_each_impl, self, Unpacker_rescue_EOFError, self, rb_eEOFError, NULL); } }
VALUE MessagePack_Unpacker_initialize(int argc, VALUE* argv, VALUE self) { VALUE io = Qnil; VALUE options = Qnil; if(argc == 0 || (argc == 1 && argv[0] == Qnil)) { /* Qnil */ } else if(argc == 1) { VALUE v = argv[0]; if(rb_type(v) == T_HASH) { options = v; if(rb_type(options) != T_HASH) { rb_raise(rb_eArgError, "expected Hash but found %s.", rb_obj_classname(options)); } } else { io = v; } } else if(argc == 2) { io = argv[0]; options = argv[1]; if(rb_type(options) != T_HASH) { rb_raise(rb_eArgError, "expected Hash but found %s.", rb_obj_classname(options)); } } else { rb_raise(rb_eArgError, "wrong number of arguments (%d for 0..2)", argc); } UNPACKER(self, uk); MessagePack_Buffer_set_options(UNPACKER_BUFFER_(uk), io, options); if(options != Qnil) { VALUE v; v = rb_hash_aref(options, ID2SYM(rb_intern("symbolize_keys"))); msgpack_unpacker_set_symbolized_keys(uk, RTEST(v)); v = rb_hash_aref(options, ID2SYM(rb_intern("allow_unknown_ext"))); msgpack_unpacker_set_allow_unknown_ext(uk, RTEST(v)); } return self; }
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); }
static VALUE Unpacker_initialize(int argc, VALUE* argv, VALUE self) { VALUE io = Qnil; VALUE options = Qnil; if(argc == 0 || (argc == 1 && argv[0] == Qnil)) { /* Qnil */ } else if(argc == 1) { VALUE v = argv[0]; if(rb_type(v) == T_HASH) { options = v; } else { io = v; } } else if(argc == 2) { io = argv[0]; options = argv[1]; if(rb_type(options) != T_HASH) { rb_raise(rb_eArgError, "expected Hash but found %s.", rb_obj_classname(io)); } } else { rb_raise(rb_eArgError, "wrong number of arguments (%d for 0..1)", argc); } UNPACKER(self, uk); if(io != Qnil || options != Qnil) { MessagePack_Buffer_initialize(UNPACKER_BUFFER_(uk), io, options); } // TODO options return self; }