/* Called by the marshalling mechanism to store a permanent copy of a Dtable. _limit_ is simply ignored. */ VALUE dtable_dump(VALUE ary, VALUE limit) { int i; /* for STORE_UNSIGNED */ long rows, cols; long x, y; double ** data = Dtable_Ptr(ary, &cols, &rows); double * col; long target_len = 1 /* first signature byte */ + 8 /* 2 * length */ + cols * rows * 8 ; unsigned u_len; VALUE str = rb_str_new2(""); rb_str_resize(str,target_len); /* This seems to do the trick */ /* \begin{playing with ruby's internals} */ unsigned char * ptr = (unsigned char *) RSTRING_PTR(str); /* signature byte */ (*ptr++) = DTABLE_DUMP_VERSION; u_len = (unsigned) rows; /* limits to 4 billions rows */ STORE_UNSIGNED(u_len, ptr); /* destroys u_len */ u_len = (unsigned) cols; /* limits to 4 billions columns */ STORE_UNSIGNED(u_len, ptr); /* destroys u_len */ for(x = 0; x < rows; x++) { col = data[x]; for(y = 0; y < cols; y++) { store_double(*(col++), ptr); ptr += 8; } } /* RSTRING_LEN(str) = target_len;*/ return str; /* \end{playing with ruby's internals} */ }