81 |
81 |
|
82 |
82 |
static ID s_dump, s_load, s_mdump, s_mload;
|
83 |
83 |
static ID s_dump_data, s_load_data, s_alloc, s_call;
|
84 |
|
static ID s_getbyte, s_read, s_write, s_binmode;
|
|
84 |
static ID s_getbyte, s_read, s_readpartial, s_write, s_binmode;
|
85 |
85 |
|
86 |
86 |
typedef struct {
|
87 |
87 |
VALUE newclass;
|
... | ... | |
958 |
958 |
|
959 |
959 |
struct load_arg {
|
960 |
960 |
VALUE src;
|
|
961 |
char *buf;
|
|
962 |
long buflen;
|
961 |
963 |
long offset;
|
|
964 |
int partial;
|
962 |
965 |
st_table *symbols;
|
963 |
966 |
st_table *data;
|
964 |
967 |
VALUE proc;
|
... | ... | |
1030 |
1033 |
c = (unsigned char)RSTRING_PTR(arg->src)[arg->offset++];
|
1031 |
1034 |
}
|
1032 |
1035 |
else {
|
|
1036 |
too_short:
|
1033 |
1037 |
rb_raise(rb_eArgError, "marshal data too short");
|
1034 |
1038 |
}
|
1035 |
1039 |
}
|
1036 |
1040 |
else {
|
1037 |
|
VALUE src = arg->src;
|
1038 |
|
VALUE v = rb_funcall2(src, s_getbyte, 0, 0);
|
1039 |
|
check_load_arg(arg, s_getbyte);
|
1040 |
|
if (NIL_P(v)) rb_eof_error();
|
1041 |
|
c = (unsigned char)NUM2CHR(v);
|
|
1041 |
if (arg->buflen == 0) {
|
|
1042 |
VALUE str, n = LONG2NUM(BUFSIZ);
|
|
1043 |
|
|
1044 |
if (arg->partial)
|
|
1045 |
str = rb_funcall2(arg->src, s_readpartial, 1, &n);
|
|
1046 |
else
|
|
1047 |
str = rb_funcall2(arg->src, s_read, 1, &n);
|
|
1048 |
|
|
1049 |
check_load_arg(arg, s_read);
|
|
1050 |
if (NIL_P(str)) goto too_short;
|
|
1051 |
StringValue(str);
|
|
1052 |
arg->infection |= (int)FL_TEST(str, MARSHAL_INFECTION);
|
|
1053 |
memcpy(arg->buf, RSTRING_PTR(str), RSTRING_LEN(str));
|
|
1054 |
arg->offset = 0;
|
|
1055 |
arg->buflen = RSTRING_LEN(str);
|
|
1056 |
}
|
|
1057 |
c = (unsigned char)arg->buf[arg->offset++];
|
|
1058 |
arg->buflen--;
|
1042 |
1059 |
}
|
1043 |
1060 |
return c;
|
1044 |
1061 |
}
|
... | ... | |
1091 |
1108 |
return x;
|
1092 |
1109 |
}
|
1093 |
1110 |
|
|
1111 |
static VALUE
|
|
1112 |
r_bytes1(long len, struct load_arg *arg)
|
|
1113 |
{
|
|
1114 |
VALUE str, n = LONG2NUM(len);
|
|
1115 |
|
|
1116 |
str = rb_funcall2(arg->src, s_read, 1, &n);
|
|
1117 |
check_load_arg(arg, s_read);
|
|
1118 |
|
|
1119 |
if (NIL_P(str)) {
|
|
1120 |
too_short:
|
|
1121 |
rb_raise(rb_eArgError, "marshal data too short");
|
|
1122 |
}
|
|
1123 |
StringValue(str);
|
|
1124 |
if (RSTRING_LEN(str) < len) goto too_short;
|
|
1125 |
|
|
1126 |
arg->infection |= (int)FL_TEST(str, MARSHAL_INFECTION);
|
|
1127 |
|
|
1128 |
return str;
|
|
1129 |
}
|
|
1130 |
|
|
1131 |
static VALUE
|
|
1132 |
r_bytes1_partial(long len, struct load_arg *arg)
|
|
1133 |
{
|
|
1134 |
long buflen = arg->buflen;
|
|
1135 |
long tmp_len, need = len - buflen;
|
|
1136 |
VALUE n = LONG2NUM(need > BUFSIZ ? need : BUFSIZ);
|
|
1137 |
VALUE str, tmp;
|
|
1138 |
const char *tmp_ptr;
|
|
1139 |
|
|
1140 |
tmp = rb_funcall2(arg->src, s_readpartial, 1, &n);
|
|
1141 |
|
|
1142 |
check_load_arg(arg, s_read);
|
|
1143 |
if (NIL_P(tmp)) {
|
|
1144 |
too_short:
|
|
1145 |
rb_raise(rb_eArgError, "marshal data too short");
|
|
1146 |
}
|
|
1147 |
StringValue(tmp);
|
|
1148 |
|
|
1149 |
tmp_ptr = RSTRING_PTR(tmp);
|
|
1150 |
tmp_len = RSTRING_LEN(tmp);
|
|
1151 |
|
|
1152 |
if (tmp_len < need) {
|
|
1153 |
VALUE fill;
|
|
1154 |
|
|
1155 |
/* retry */
|
|
1156 |
n = LONG2NUM(need-tmp_len);
|
|
1157 |
fill = rb_funcall2(arg->src, s_read, 1, &n);
|
|
1158 |
|
|
1159 |
if (NIL_P(fill)) goto too_short;
|
|
1160 |
StringValue(fill);
|
|
1161 |
if (RSTRING_LEN(fill) < need-tmp_len) goto too_short;
|
|
1162 |
|
|
1163 |
rb_str_concat(tmp, fill);
|
|
1164 |
tmp_len = RSTRING_LEN(tmp);
|
|
1165 |
}
|
|
1166 |
|
|
1167 |
arg->infection |= (int)FL_TEST(tmp, MARSHAL_INFECTION);
|
|
1168 |
str = rb_str_new(arg->buf+arg->offset, buflen);
|
|
1169 |
rb_str_cat(str, tmp_ptr, need);
|
|
1170 |
if (tmp_len-need > 0)
|
|
1171 |
memcpy(arg->buf, tmp_ptr+need, tmp_len-need);
|
|
1172 |
|
|
1173 |
arg->offset = 0;
|
|
1174 |
arg->buflen = tmp_len - need;
|
|
1175 |
|
|
1176 |
return str;
|
|
1177 |
}
|
|
1178 |
|
1094 |
1179 |
#define r_bytes(arg) r_bytes0(r_long(arg), (arg))
|
1095 |
1180 |
|
1096 |
1181 |
static VALUE
|
... | ... | |
1105 |
1190 |
arg->offset += len;
|
1106 |
1191 |
}
|
1107 |
1192 |
else {
|
1108 |
|
too_short:
|
1109 |
1193 |
rb_raise(rb_eArgError, "marshal data too short");
|
1110 |
1194 |
}
|
1111 |
1195 |
}
|
1112 |
1196 |
else {
|
1113 |
|
VALUE src = arg->src;
|
1114 |
|
VALUE n = LONG2NUM(len);
|
1115 |
|
str = rb_funcall2(src, s_read, 1, &n);
|
1116 |
|
check_load_arg(arg, s_read);
|
1117 |
|
if (NIL_P(str)) goto too_short;
|
1118 |
|
StringValue(str);
|
1119 |
|
if (RSTRING_LEN(str) != len) goto too_short;
|
1120 |
|
arg->infection |= (int)FL_TEST(str, MARSHAL_INFECTION);
|
|
1197 |
if (len <= arg->buflen) {
|
|
1198 |
str = rb_str_new(arg->buf+arg->offset, len);
|
|
1199 |
arg->offset += len;
|
|
1200 |
arg->buflen -= len;
|
|
1201 |
}
|
|
1202 |
else {
|
|
1203 |
if (arg->partial)
|
|
1204 |
str = r_bytes1_partial(len, arg);
|
|
1205 |
else
|
|
1206 |
str = r_bytes1(len, arg);
|
|
1207 |
}
|
1121 |
1208 |
}
|
1122 |
1209 |
return str;
|
1123 |
1210 |
}
|
... | ... | |
1784 |
1871 |
arg->data = st_init_numtable();
|
1785 |
1872 |
arg->compat_tbl = st_init_numtable();
|
1786 |
1873 |
arg->proc = 0;
|
|
1874 |
arg->partial = 0;
|
|
1875 |
|
|
1876 |
if(NIL_P(v)) {
|
|
1877 |
if (rb_respond_to(port, s_readpartial)) arg->partial = 1;
|
|
1878 |
arg->buf = xmalloc(BUFSIZ);
|
|
1879 |
}
|
1787 |
1880 |
|
1788 |
1881 |
major = r_byte(arg);
|
1789 |
1882 |
minor = r_byte(arg);
|
... | ... | |
1921 |
2014 |
s_call = rb_intern("call");
|
1922 |
2015 |
s_getbyte = rb_intern("getbyte");
|
1923 |
2016 |
s_read = rb_intern("read");
|
|
2017 |
s_readpartial = rb_intern("readpartial");
|
1924 |
2018 |
s_write = rb_intern("write");
|
1925 |
2019 |
s_binmode = rb_intern("binmode");
|
1926 |
2020 |
|