On Sun, 22 Oct 2000, Yukihiro Matsumoto wrote:

> Hi,
> 
> In message "[ruby-talk:5731] MD5 Marshaling"
>     on 00/10/21, Robert Feldt <feldt / ce.chalmers.se> writes:
> 
> |I needed marshaling on MD5 objects so made a small (and
> |simplistic!) patch. Works for me and may be useful for others. Patch and
> |very small test below.
> 
> Thank you, but 2 points:
> 
>   * marshal output should be platform independent; so we need more
>     work.
> 
>   * you sent the reversed diff. ;-)
> 
This gives larger dump and is slower and can be optimized but should work
on most platforms (or?):

*** md5init.c.orig	Sun Oct 22 03:11:22 2000
--- md5init.c	Sun Oct 22 03:09:50 2000
***************
*** 99,104 ****
--- 99,158 ----
      return obj;
  }
  
+ static VALUE oMarshal;
+ static VALUE idDump;
+ static VALUE idLoad;
+ 
+ static VALUE
+ md5_dump(self, aDepth)
+      VALUE self;
+      VALUE aDepth;
+ {
+     MD5_CTX *md5_context;
+     VALUE ary = rb_ary_new();
+     int i;
+ 
+     // Get context
+     Data_Get_Struct(self, MD5_CTX, md5_context);
+ 
+     // Make array from data in context
+     for(i = 0; i<4; i++)
+       rb_ary_push(ary, UINT2NUM(md5_context->state[i]));
+     for(i = 0; i<2; i++)
+       rb_ary_push(ary, UINT2NUM(md5_context->count[i]));
+     for(i = 0; i<64; i++)
+       rb_ary_push(ary, UINT2NUM(md5_context->buffer[i]));
+ 
+     // ...and return dump of array
+     return rb_funcall(oMarshal, idDump, 1, ary);
+ }
+ 
+ static VALUE
+ md5_load(klass, aString)
+      VALUE klass;
+      VALUE aString;
+ {
+     VALUE obj, ary;
+     MD5_CTX *md5;
+     int i, cnt = 0;
+ 
+     // Wrap up a context
+     obj = Data_Make_Struct(klass, MD5_CTX, 0, free, md5);
+ 
+     // Load ary from string
+     ary = rb_funcall(oMarshal, idLoad, 1, aString);
+ 
+     // Setup context from values in ary
+     for(i = 0; i<4; i++)
+       md5->state[i] = NUM2UINT(rb_ary_entry(ary, cnt++));
+     for(i = 0; i<2; i++)
+       md5->count[i] = NUM2UINT(rb_ary_entry(ary, cnt++));
+     for(i = 0; i<64; i++)
+       md5->buffer[i] = (unsigned char)NUM2UINT(rb_ary_entry(ary,
cnt++));
+ 
+     return obj;
+ }
+ 
  void
  Init_md5()
  {
***************
*** 111,114 ****
--- 165,174 ----
      rb_define_method(cMD5, "digest", md5_digest, 0);
      rb_define_method(cMD5, "hexdigest", md5_hexdigest, 0);
      rb_define_method(cMD5, "clone",  md5_clone, 0);
+ 
+     oMarshal = rb_const_get(rb_cObject, rb_intern("Marshal"));
+     idDump = rb_intern("dump");
+     idLoad = rb_intern("load");
+     rb_define_method(cMD5, "_dump", md5_dump, 1);
+     rb_define_singleton_method(cMD5, "_load", md5_load, 1);
  }

Regards,

Robert