/*
* call-seq:
* load( source [, proc] ) => obj
* restore( source [, proc] ) => obj
*
* Returns the result of converting the serialized data in source into a
* Ruby object (possibly with associated subordinate objects). source
* may be either an instance of IO or an object that responds to
* to_str. If proc is specified, it will be passed each object as it
* is deserialized.
*/
static VALUE
marshal_load(argc, argv)
int argc;
VALUE *argv;
{
VALUE port, proc;
int major, minor;
VALUE v;
struct load_arg arg;
rb_scan_args(argc, argv, "11", &port, &proc);
v = rb_check_string_type(port);
if (!NIL_P(v)) {
arg.taint = OBJ_TAINTED(port); /* original taintedness */
port = v;
}
else if (rb_respond_to(port, s_getc) && rb_respond_to(port, s_read)) {
if (rb_respond_to(port, s_binmode)) {
rb_funcall2(port, s_binmode, 0, 0);
}
arg.taint = Qtrue;
}
else {
rb_raise(rb_eTypeError, "instance of IO needed");
}
arg.src = port;
arg.offset = 0;
arg.data = 0;
major = r_byte(&arg);
minor = r_byte(&arg);
if (major != MARSHAL_MAJOR || minor > MARSHAL_MINOR) {
rb_raise(rb_eTypeError, "incompatible marshal file format (can't be read)\n\
\tformat version %d.%d required; %d.%d given",
MARSHAL_MAJOR, MARSHAL_MINOR, major, minor);
}
if (RTEST(ruby_verbose) && minor != MARSHAL_MINOR) {
rb_warn("incompatible marshal file format (can be read)\n\
\tformat version %d.%d required; %d.%d given",
MARSHAL_MAJOR, MARSHAL_MINOR, major, minor);
}
arg.symbols = st_init_numtable();
arg.data = rb_hash_new();
RBASIC(arg.data)->klass = 0;
if (NIL_P(proc)) arg.proc = 0;
else arg.proc = proc;
v = rb_ensure(load, (VALUE)&arg, load_ensure, (VALUE)&arg);
RBASIC(arg.data)->klass = rb_cHash;
return v;
}