/* * call-seq: * dump( obj [, anIO] , limit=--1 ) => anIO * * Serializes obj and all descendent objects. If anIO is * specified, the serialized data will be written to it, otherwise the * data will be returned as a String. If limit is specified, the * traversal of subobjects will be limited to that depth. If limit is * negative, no checking of depth will be performed. * * class Klass * def initialize(str) * @str = str * end * def sayHello * @str * end * end * * (produces no output) * * o = Klass.new("hello\n") * data = Marshal.dump(o) * obj = Marshal.load(data) * obj.sayHello #=> "hello\n" */ static VALUE marshal_dump(argc, argv) int argc; VALUE* argv; { VALUE obj, port, a1, a2; int limit = -1; struct dump_arg arg; struct dump_call_arg c_arg; port = Qnil; rb_scan_args(argc, argv, "12", &obj, &a1, &a2); if (argc == 3) { if (!NIL_P(a2)) limit = NUM2INT(a2); if (NIL_P(a1)) goto type_error; port = a1; } else if (argc == 2) { if (FIXNUM_P(a1)) limit = FIX2INT(a1); else if (NIL_P(a1)) goto type_error; else port = a1; } arg.dest = 0; arg.symbols = st_init_numtable(); arg.data = st_init_numtable(); arg.taint = Qfalse; arg.str = rb_str_buf_new(0); RBASIC(arg.str)->klass = 0; arg.wrapper = Data_Wrap_Struct(rb_cData, mark_dump_arg, 0, &arg); if (!NIL_P(port)) { if (!rb_respond_to(port, s_write)) { type_error: rb_raise(rb_eTypeError, "instance of IO needed"); } arg.dest = port; if (rb_respond_to(port, s_binmode)) { rb_funcall2(port, s_binmode, 0, 0); check_dump_arg(&arg, s_binmode); } } else { port = arg.str; } c_arg.obj = obj; c_arg.arg = &arg; c_arg.limit = limit; w_byte(MARSHAL_MAJOR, &arg); w_byte(MARSHAL_MINOR, &arg); rb_ensure(dump, (VALUE)&c_arg, dump_ensure, (VALUE)&arg); RBASIC(arg.str)->klass = rb_cString; return port; }