summaryrefslogtreecommitdiff
path: root/marshal.c
diff options
context:
space:
mode:
authormatz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2003-07-29 18:26:55 +0000
committermatz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2003-07-29 18:26:55 +0000
commitfe13785cc699692cefbdf94908fcaa7c99672f0f (patch)
tree5f73958731220fb1eaba3f52421a97d0bb88ce42 /marshal.c
parent7d1de7464b31bdd5b4e61897ef9b37e3e8d5389a (diff)
* marshal.c (w_object): if object responds to 'marshal_dump',
Marshal.dump uses it to dump object. unlike '_dump', marshal_dump returns any kind of object. * marshal.c (r_object0): restore instance by calling 'marshal_load' method. unlike '_load', it's an instance method, to handle cyclic reference. * marshal.c (marshal_load): all objects read from file should be tainted. [ruby-core:01325] * lib/timeout.rb (Timeout::timeout): execute immediately if sec is zero. * ext/socket/socket.c (socks_init): typo fixed. [ruby-talk:77232] * ext/socket/extconf.rb: the default value for --enable-socks is taken from ENV["SOCKS_SERVER"]. [ruby-talk:77232] * ruby.c (proc_options): add -W option. -W0 to shut up all warning messages. [ruby-talk:77227] * error.c (rb_warn): no message will be printed if the value of $VERBOSE is "nil", i.e. perfect silence. * ruby.c (verbose_setter): $VERBOSE value is either true, false, or nil. * io.c (Init_IO): no "read" check for $stdin. in addition some function names has been changed. * regex.c (re_match_exec): incorrect multibyte match. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@4220 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'marshal.c')
-rw-r--r--marshal.c34
1 files changed, 28 insertions, 6 deletions
diff --git a/marshal.c b/marshal.c
index 4718f79209..14adf825c3 100644
--- a/marshal.c
+++ b/marshal.c
@@ -77,7 +77,7 @@ shortlen(len, ds)
#define TYPE_IVAR 'I'
#define TYPE_LINK '@'
-static ID s_dump, s_load;
+static ID s_dump, s_load, s_mdump, s_mload;
static ID s_dump_data, s_load_data, s_alloc;
static ID s_getc, s_read, s_write, s_binmode;
@@ -480,14 +480,20 @@ w_object(obj, arg, limit)
}
st_add_direct(arg->data, obj, arg->data->num_entries);
+ if (rb_respond_to(obj, s_mdump)) {
+ VALUE v;
+
+ v = rb_funcall(obj, s_mdump, 1, INT2NUM(limit));
+ w_class(TYPE_USRMARSHAL, obj, arg);
+ w_object(v, arg, limit);
+ if (ivtbl) w_ivar(ivtbl, &c_arg);
+ return;
+ }
if (rb_respond_to(obj, s_dump)) {
VALUE v;
- w_class(TYPE_USERDEF, obj, arg);
v = rb_funcall(obj, s_dump, 1, INT2NUM(limit));
- if (TYPE(v) != T_STRING) {
- rb_raise(rb_eTypeError, "_dump() must return String");
- }
+ w_class(TYPE_USERDEF, obj, arg);
w_bytes(RSTRING(v)->ptr, RSTRING(v)->len, arg);
if (ivtbl) w_ivar(ivtbl, &c_arg);
return;
@@ -1169,6 +1175,20 @@ r_object0(arg, proc)
}
break;
+ case TYPE_USRMARSHAL:
+ {
+ VALUE klass = path2class(r_unique(arg));
+
+ v = rb_obj_alloc(klass);
+ if (!rb_respond_to(v, s_mload)) {
+ rb_raise(rb_eTypeError, "instance of %s needs to have method `marshal_load'",
+ rb_class2name(klass));
+ }
+ r_regist(v, arg);
+ rb_funcall(v, s_mload, 1, r_object(arg));
+ }
+ break;
+
case TYPE_OBJECT:
{
VALUE klass = path2class(r_unique(arg));
@@ -1296,7 +1316,7 @@ marshal_load(argc, argv)
if (rb_respond_to(port, s_binmode)) {
rb_funcall2(port, s_binmode, 0, 0);
}
- arg.taint = Qfalse;
+ arg.taint = Qtrue;
arg.ptr = (char *)port;
arg.end = 0;
}
@@ -1333,6 +1353,8 @@ Init_marshal()
s_dump = rb_intern("_dump");
s_load = rb_intern("_load");
+ s_mdump = rb_intern("marshal_dump");
+ s_mload = rb_intern("marshal_load");
s_dump_data = rb_intern("_dump_data");
s_load_data = rb_intern("_load_data");
s_alloc = rb_intern("_alloc");