mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
* marshal.c (w_byten): added; write n bytes from s to arg.
* marshal.c (dump): flush buffered data. * marshal.c (marshal_dump, r_byte, r_bytes0, marshal_load): unify marshaling I/O. [ruby-talk:53368] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@2967 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
55068f94f2
commit
020caa3fc8
2 changed files with 84 additions and 30 deletions
|
@ -1,3 +1,12 @@
|
||||||
|
Thu Oct 17 19:17:56 2002 Nobuyoshi Nakada <nobu.nokada@softhome.net>
|
||||||
|
|
||||||
|
* marshal.c (w_byten): added; write n bytes from s to arg.
|
||||||
|
|
||||||
|
* marshal.c (dump): flush buffered data.
|
||||||
|
|
||||||
|
* marshal.c (marshal_dump, r_byte, r_bytes0, marshal_load): unify
|
||||||
|
marshaling I/O. [ruby-talk:53368]
|
||||||
|
|
||||||
Thu Oct 17 12:58:24 2002 Minero Aoki <aamine@loveruby.net>
|
Thu Oct 17 12:58:24 2002 Minero Aoki <aamine@loveruby.net>
|
||||||
|
|
||||||
* lib/fileutils.rb: stat.blksize might become 0/nil.
|
* lib/fileutils.rb: stat.blksize might become 0/nil.
|
||||||
|
|
105
marshal.c
105
marshal.c
|
@ -76,11 +76,12 @@ shortlen(len, ds)
|
||||||
|
|
||||||
static ID s_dump, s_load;
|
static ID s_dump, s_load;
|
||||||
static ID s_dump_data, s_load_data, s_alloc;
|
static ID s_dump_data, s_load_data, s_alloc;
|
||||||
|
static ID s_getc, s_read, s_write;
|
||||||
|
|
||||||
struct dump_arg {
|
struct dump_arg {
|
||||||
VALUE obj;
|
VALUE obj;
|
||||||
FILE *fp;
|
FILE *fp;
|
||||||
VALUE str;
|
VALUE str, dest;
|
||||||
st_table *symbol;
|
st_table *symbol;
|
||||||
st_table *data;
|
st_table *data;
|
||||||
int taint;
|
int taint;
|
||||||
|
@ -94,13 +95,32 @@ struct dump_call_arg {
|
||||||
|
|
||||||
static void w_long _((long, struct dump_arg*));
|
static void w_long _((long, struct dump_arg*));
|
||||||
|
|
||||||
|
static void
|
||||||
|
w_byten(s, n, arg)
|
||||||
|
char *s;
|
||||||
|
int n;
|
||||||
|
struct dump_arg *arg;
|
||||||
|
{
|
||||||
|
if (arg->fp) {
|
||||||
|
fwrite(s, 1, n, arg->fp);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
VALUE buf = arg->str;
|
||||||
|
rb_str_buf_cat(buf, s, n);
|
||||||
|
if (arg->dest && RSTRING(buf)->len >= BUFSIZ) {
|
||||||
|
if (arg->taint) OBJ_TAINT(buf);
|
||||||
|
rb_io_write(arg->dest, buf);
|
||||||
|
rb_str_resize(buf, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
w_byte(c, arg)
|
w_byte(c, arg)
|
||||||
char c;
|
char c;
|
||||||
struct dump_arg *arg;
|
struct dump_arg *arg;
|
||||||
{
|
{
|
||||||
if (arg->fp) putc(c, arg->fp);
|
w_byten(&c, 1, arg);
|
||||||
else rb_str_buf_cat(arg->str, &c, 1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -110,12 +130,7 @@ w_bytes(s, n, arg)
|
||||||
struct dump_arg *arg;
|
struct dump_arg *arg;
|
||||||
{
|
{
|
||||||
w_long(n, arg);
|
w_long(n, arg);
|
||||||
if (arg->fp) {
|
w_byten(s, n, arg);
|
||||||
fwrite(s, 1, n, arg->fp);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
rb_str_buf_cat(arg->str, s, n);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -551,6 +566,10 @@ dump(arg)
|
||||||
struct dump_call_arg *arg;
|
struct dump_call_arg *arg;
|
||||||
{
|
{
|
||||||
w_object(arg->obj, arg->arg, arg->limit);
|
w_object(arg->obj, arg->arg, arg->limit);
|
||||||
|
if (arg->arg->dest) {
|
||||||
|
rb_io_write(arg->arg->dest, arg->arg->str);
|
||||||
|
rb_str_resize(arg->arg->str, 0);
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -586,6 +605,7 @@ marshal_dump(argc, argv)
|
||||||
if (FIXNUM_P(a1)) limit = FIX2INT(a1);
|
if (FIXNUM_P(a1)) limit = FIX2INT(a1);
|
||||||
else port = a1;
|
else port = a1;
|
||||||
}
|
}
|
||||||
|
arg.dest = 0;
|
||||||
if (port) {
|
if (port) {
|
||||||
if (rb_obj_is_kind_of(port, rb_cIO)) {
|
if (rb_obj_is_kind_of(port, rb_cIO)) {
|
||||||
OpenFile *fptr;
|
OpenFile *fptr;
|
||||||
|
@ -595,6 +615,11 @@ marshal_dump(argc, argv)
|
||||||
rb_io_check_writable(fptr);
|
rb_io_check_writable(fptr);
|
||||||
arg.fp = (fptr->f2) ? fptr->f2 : fptr->f;
|
arg.fp = (fptr->f2) ? fptr->f2 : fptr->f;
|
||||||
}
|
}
|
||||||
|
else if (rb_respond_to(port, s_write)) {
|
||||||
|
arg.fp = 0;
|
||||||
|
arg.str = rb_str_buf_new(0);
|
||||||
|
arg.dest = port;
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
rb_raise(rb_eTypeError, "instance of IO needed");
|
rb_raise(rb_eTypeError, "instance of IO needed");
|
||||||
}
|
}
|
||||||
|
@ -641,6 +666,12 @@ r_byte(arg)
|
||||||
c = rb_getc(arg->fp);
|
c = rb_getc(arg->fp);
|
||||||
if (c == EOF) rb_eof_error();
|
if (c == EOF) rb_eof_error();
|
||||||
}
|
}
|
||||||
|
else if (!arg->end) {
|
||||||
|
VALUE src = (VALUE)arg->ptr;
|
||||||
|
VALUE v = rb_funcall2(src, s_getc, 0, 0);
|
||||||
|
if (NIL_P(v)) rb_eof_error();
|
||||||
|
c = (unsigned char)FIX2INT(v);
|
||||||
|
}
|
||||||
else if (arg->ptr < arg->end) {
|
else if (arg->ptr < arg->end) {
|
||||||
c = *(unsigned char*)arg->ptr++;
|
c = *(unsigned char*)arg->ptr++;
|
||||||
}
|
}
|
||||||
|
@ -650,18 +681,6 @@ r_byte(arg)
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
|
|
||||||
static unsigned short
|
|
||||||
r_short(arg)
|
|
||||||
struct load_arg *arg;
|
|
||||||
{
|
|
||||||
unsigned short x;
|
|
||||||
|
|
||||||
x = r_byte(arg);
|
|
||||||
x |= r_byte(arg)<<8;
|
|
||||||
|
|
||||||
return x;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
long_toobig(size)
|
long_toobig(size)
|
||||||
int size;
|
int size;
|
||||||
|
@ -728,6 +747,15 @@ r_bytes0(len, arg)
|
||||||
rb_raise(rb_eArgError, "marshal data too short");
|
rb_raise(rb_eArgError, "marshal data too short");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (!arg->end) {
|
||||||
|
VALUE src = (VALUE)arg->ptr;
|
||||||
|
VALUE n = LONG2NUM(len);
|
||||||
|
str = rb_funcall2(src, s_read, 1, &n);
|
||||||
|
if (NIL_P(str)) goto too_short;
|
||||||
|
Check_Type(str, T_STRING);
|
||||||
|
if (RSTRING(str)->len != len) goto too_short;
|
||||||
|
if (OBJ_TAINTED(str)) arg->taint = Qtrue;
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
if (arg->ptr + len > arg->end) {
|
if (arg->ptr + len > arg->end) {
|
||||||
goto too_short;
|
goto too_short;
|
||||||
|
@ -933,34 +961,41 @@ r_object0(arg, proc)
|
||||||
{
|
{
|
||||||
long len;
|
long len;
|
||||||
BDIGIT *digits;
|
BDIGIT *digits;
|
||||||
|
VALUE data;
|
||||||
|
|
||||||
NEWOBJ(big, struct RBignum);
|
NEWOBJ(big, struct RBignum);
|
||||||
OBJSETUP(big, rb_cBignum, T_BIGNUM);
|
OBJSETUP(big, rb_cBignum, T_BIGNUM);
|
||||||
big->sign = (r_byte(arg) == '+');
|
big->sign = (r_byte(arg) == '+');
|
||||||
len = r_long(arg);
|
len = r_long(arg);
|
||||||
|
data = r_bytes0(len * 2, arg);
|
||||||
#if SIZEOF_BDIGITS == SIZEOF_SHORT
|
#if SIZEOF_BDIGITS == SIZEOF_SHORT
|
||||||
big->len = len;
|
big->len = len;
|
||||||
#else
|
#else
|
||||||
big->len = (len + 1) * 2 / sizeof(BDIGIT);
|
big->len = (len + 1) * 2 / sizeof(BDIGIT);
|
||||||
#endif
|
#endif
|
||||||
big->digits = digits = ALLOC_N(BDIGIT, big->len);
|
big->digits = digits = ALLOC_N(BDIGIT, big->len);
|
||||||
while (len > 0) {
|
MEMCPY(digits, RSTRING(data)->ptr, char, len * 2);
|
||||||
#if SIZEOF_BDIGITS > SIZEOF_SHORT
|
#if SIZEOF_BDIGITS > SIZEOF_SHORT
|
||||||
|
MEMZERO((char *)digits + len * 2, char,
|
||||||
|
big->len * sizeof(BDIGIT) - len * 2);
|
||||||
|
#endif
|
||||||
|
len = big->len;
|
||||||
|
while (len > 0) {
|
||||||
|
unsigned char *p = (unsigned char *)digits;
|
||||||
BDIGIT num = 0;
|
BDIGIT num = 0;
|
||||||
|
#if SIZEOF_BDIGITS > SIZEOF_SHORT
|
||||||
int shift = 0;
|
int shift = 0;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i=0; i<SIZEOF_BDIGITS; i+=2) {
|
for (i=0; i<SIZEOF_BDIGITS; i++) {
|
||||||
int j = r_short(arg);
|
num |= (int)p[i] << shift;
|
||||||
num |= j << shift;
|
shift += 8;
|
||||||
shift += BITSPERSHORT;
|
|
||||||
if (--len == 0) break;
|
|
||||||
}
|
}
|
||||||
*digits++ = num;
|
|
||||||
#else
|
#else
|
||||||
*digits++ = r_short(arg);
|
num = p[0] | (p[1] << 8);
|
||||||
len--;
|
|
||||||
#endif
|
#endif
|
||||||
|
*digits++ = num;
|
||||||
|
len--;
|
||||||
}
|
}
|
||||||
v = rb_big_norm((VALUE)big);
|
v = rb_big_norm((VALUE)big);
|
||||||
r_regist(v, arg);
|
r_regist(v, arg);
|
||||||
|
@ -1189,6 +1224,12 @@ marshal_load(argc, argv)
|
||||||
arg.ptr = RSTRING(port)->ptr;
|
arg.ptr = RSTRING(port)->ptr;
|
||||||
arg.end = arg.ptr + RSTRING(port)->len;
|
arg.end = arg.ptr + RSTRING(port)->len;
|
||||||
}
|
}
|
||||||
|
else if (rb_respond_to(port, s_getc) && rb_respond_to(port, s_read)) {
|
||||||
|
arg.taint = Qfalse;
|
||||||
|
arg.fp = 0;
|
||||||
|
arg.ptr = (char *)port;
|
||||||
|
arg.end = 0;
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
rb_raise(rb_eTypeError, "instance of IO needed");
|
rb_raise(rb_eTypeError, "instance of IO needed");
|
||||||
}
|
}
|
||||||
|
@ -1225,6 +1266,10 @@ Init_marshal()
|
||||||
s_dump_data = rb_intern("_dump_data");
|
s_dump_data = rb_intern("_dump_data");
|
||||||
s_load_data = rb_intern("_load_data");
|
s_load_data = rb_intern("_load_data");
|
||||||
s_alloc = rb_intern("_alloc");
|
s_alloc = rb_intern("_alloc");
|
||||||
|
s_getc = rb_intern("getc");
|
||||||
|
s_read = rb_intern("read");
|
||||||
|
s_write = rb_intern("write");
|
||||||
|
|
||||||
rb_define_module_function(rb_mMarshal, "dump", marshal_dump, -1);
|
rb_define_module_function(rb_mMarshal, "dump", marshal_dump, -1);
|
||||||
rb_define_module_function(rb_mMarshal, "load", marshal_load, -1);
|
rb_define_module_function(rb_mMarshal, "load", marshal_load, -1);
|
||||||
rb_define_module_function(rb_mMarshal, "restore", marshal_load, -1);
|
rb_define_module_function(rb_mMarshal, "restore", marshal_load, -1);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue