* io.c (fill_cbuf): extracted from more_char.
(io_shift_cbuf): fix memmove condition. (read_all): use fill_cbuf directly to avoid ECONV_AFTER_OUTPUT. [ruby-dev:39708] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@25845 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
817f503001
commit
4c6eda226a
@ -1,3 +1,10 @@
|
||||
Wed Nov 18 22:00:13 2009 Tanaka Akira <akr@fsij.org>
|
||||
|
||||
* io.c (fill_cbuf): extracted from more_char.
|
||||
(io_shift_cbuf): fix memmove condition.
|
||||
(read_all): use fill_cbuf directly to avoid ECONV_AFTER_OUTPUT.
|
||||
[ruby-dev:39708]
|
||||
|
||||
Wed Nov 18 18:25:09 2009 Nobuyoshi Nakada <nobu@ruby-lang.org>
|
||||
|
||||
* thread.c (rb_thread_atfork_internal): reinitialize global lock
|
||||
|
66
io.c
66
io.c
@ -1582,17 +1582,22 @@ make_readconv(rb_io_t *fptr, int size)
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
more_char(rb_io_t *fptr)
|
||||
#define MORE_CHAR_CBUF_FULL Qtrue
|
||||
#define MORE_CHAR_FINISHED Qnil
|
||||
static VALUE
|
||||
fill_cbuf(rb_io_t *fptr, int ec_flags)
|
||||
{
|
||||
const unsigned char *ss, *sp, *se;
|
||||
unsigned char *ds, *dp, *de;
|
||||
rb_econv_result_t res;
|
||||
int putbackable;
|
||||
int cbuf_len0;
|
||||
VALUE exc;
|
||||
|
||||
ec_flags |= ECONV_PARTIAL_INPUT;
|
||||
|
||||
if (fptr->cbuf_len == fptr->cbuf_capa)
|
||||
return 0; /* cbuf full */
|
||||
return MORE_CHAR_CBUF_FULL; /* cbuf full */
|
||||
if (fptr->cbuf_len == 0)
|
||||
fptr->cbuf_off = 0;
|
||||
else if (fptr->cbuf_off + fptr->cbuf_len == fptr->cbuf_capa) {
|
||||
@ -1607,7 +1612,7 @@ more_char(rb_io_t *fptr)
|
||||
se = sp + fptr->rbuf_len;
|
||||
ds = dp = (unsigned char *)fptr->cbuf + fptr->cbuf_off + fptr->cbuf_len;
|
||||
de = (unsigned char *)fptr->cbuf + fptr->cbuf_capa;
|
||||
res = rb_econv_convert(fptr->readconv, &sp, se, &dp, de, ECONV_PARTIAL_INPUT|ECONV_AFTER_OUTPUT);
|
||||
res = rb_econv_convert(fptr->readconv, &sp, se, &dp, de, ec_flags);
|
||||
fptr->rbuf_off += (int)(sp - ss);
|
||||
fptr->rbuf_len -= (int)(sp - ss);
|
||||
fptr->cbuf_len += (int)(dp - ds);
|
||||
@ -1619,13 +1624,15 @@ more_char(rb_io_t *fptr)
|
||||
fptr->rbuf_len += putbackable;
|
||||
}
|
||||
|
||||
rb_econv_check_error(fptr->readconv);
|
||||
exc = rb_econv_make_exception(fptr->readconv);
|
||||
if (!NIL_P(exc))
|
||||
return exc;
|
||||
|
||||
if (cbuf_len0 != fptr->cbuf_len)
|
||||
return 0;
|
||||
return MORE_CHAR_CBUF_FULL;
|
||||
|
||||
if (res == econv_finished) {
|
||||
return -1;
|
||||
return MORE_CHAR_FINISHED;
|
||||
}
|
||||
|
||||
if (res == econv_source_buffer_empty) {
|
||||
@ -1644,6 +1651,16 @@ more_char(rb_io_t *fptr)
|
||||
}
|
||||
}
|
||||
|
||||
static VALUE
|
||||
more_char(rb_io_t *fptr)
|
||||
{
|
||||
VALUE v;
|
||||
v = fill_cbuf(fptr, ECONV_AFTER_OUTPUT);
|
||||
if (v != MORE_CHAR_CBUF_FULL && v != MORE_CHAR_FINISHED)
|
||||
rb_exc_raise(v);
|
||||
return v;
|
||||
}
|
||||
|
||||
static VALUE
|
||||
io_shift_cbuf(rb_io_t *fptr, int len, VALUE *strp)
|
||||
{
|
||||
@ -1665,7 +1682,7 @@ io_shift_cbuf(rb_io_t *fptr, int len, VALUE *strp)
|
||||
/* xxx: set coderange */
|
||||
if (fptr->cbuf_len == 0)
|
||||
fptr->cbuf_off = 0;
|
||||
if (fptr->cbuf_off < fptr->cbuf_capa/2) {
|
||||
else if (fptr->cbuf_capa/2 < fptr->cbuf_off) {
|
||||
memmove(fptr->cbuf, fptr->cbuf+fptr->cbuf_off, fptr->cbuf_len);
|
||||
fptr->cbuf_off = 0;
|
||||
}
|
||||
@ -1686,21 +1703,19 @@ read_all(rb_io_t *fptr, long siz, VALUE str)
|
||||
else rb_str_set_len(str, 0);
|
||||
make_readconv(fptr, 0);
|
||||
while (1) {
|
||||
int fin, state = 0;
|
||||
|
||||
if (fptr->cbuf_len > fptr->cbuf_capa / 2) {
|
||||
VALUE v;
|
||||
if (fptr->cbuf_len) {
|
||||
io_shift_cbuf(fptr, fptr->cbuf_len, &str);
|
||||
}
|
||||
|
||||
fin = rb_protect((VALUE (*)(VALUE))more_char, (VALUE)fptr, &state);
|
||||
if (fin == -1 || state != 0) {
|
||||
if (fptr->cbuf_len) {
|
||||
io_shift_cbuf(fptr, fptr->cbuf_len, &str);
|
||||
}
|
||||
if (state != 0) {
|
||||
rb_jump_tag(state);
|
||||
}
|
||||
clear_readconv(fptr);
|
||||
v = fill_cbuf(fptr, 0);
|
||||
if (v != MORE_CHAR_CBUF_FULL && v != MORE_CHAR_FINISHED) {
|
||||
if (fptr->cbuf_len) {
|
||||
io_shift_cbuf(fptr, fptr->cbuf_len, &str);
|
||||
}
|
||||
rb_exc_raise(v);
|
||||
}
|
||||
if (v == MORE_CHAR_FINISHED) {
|
||||
clear_readconv(fptr);
|
||||
return io_enc_str(str, fptr);
|
||||
}
|
||||
}
|
||||
@ -2181,7 +2196,7 @@ appendline(rb_io_t *fptr, int delim, VALUE *strp, long *lp)
|
||||
return (unsigned char)RSTRING_PTR(str)[RSTRING_LEN(str)-1];
|
||||
}
|
||||
}
|
||||
} while (more_char(fptr) != -1);
|
||||
} while (more_char(fptr) != MORE_CHAR_FINISHED);
|
||||
clear_readconv(fptr);
|
||||
*lp = limit;
|
||||
return EOF;
|
||||
@ -2695,7 +2710,8 @@ io_getc(rb_io_t *fptr, rb_encoding *enc)
|
||||
}
|
||||
}
|
||||
|
||||
if (more_char(fptr) == -1) {
|
||||
if (more_char(fptr) == MORE_CHAR_FINISHED) {
|
||||
clear_readconv(fptr);
|
||||
if (fptr->cbuf_len == 0)
|
||||
return Qnil;
|
||||
/* return an incomplete character just before EOF */
|
||||
@ -2830,8 +2846,8 @@ rb_io_each_codepoint(VALUE io)
|
||||
rb_raise(rb_eIOError, "too long character");
|
||||
}
|
||||
}
|
||||
if (more_char(fptr) == -1) {
|
||||
clear_readconv(fptr);
|
||||
if (more_char(fptr) == MORE_CHAR_FINISHED) {
|
||||
clear_readconv(fptr);
|
||||
/* ignore an incomplete character before EOF */
|
||||
return io;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user