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