summaryrefslogtreecommitdiff
path: root/io.c
diff options
context:
space:
mode:
authorusa <usa@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2010-05-13 04:05:19 +0000
committerusa <usa@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2010-05-13 04:05:19 +0000
commitfab261586ad20208a8ff7461f5b642845ffa3c32 (patch)
tree3e075217dbb61e7e1ef098a93a4b542ba20f6020 /io.c
parent01eb640ca8b6f63c0ad89216c0e896f49ae51481 (diff)
merge from trunk (r27768-r27770)
* io.c (swallow): support text mode and UTF-16/32 as internal encoding. [Bug #1576] * io.c (io_shift_cbuf): read and throw it away when str is NULL. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_1_9_2@27771 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'io.c')
-rw-r--r--io.c51
1 files changed, 42 insertions, 9 deletions
diff --git a/io.c b/io.c
index 00ec9ffdb4..c5a39c8384 100644
--- a/io.c
+++ b/io.c
@@ -187,6 +187,8 @@ static int max_file_descriptor = NOFILE;
#define READ_DATA_BUFFERED(fptr) READ_DATA_PENDING(fptr)
#define READ_CHAR_PENDING(fptr) ((fptr)->cbuf_len)
+#define READ_CHAR_PENDING_COUNT(fptr) ((fptr)->cbuf_len)
+#define READ_CHAR_PENDING_PTR(fptr) ((fptr)->cbuf+(fptr)->cbuf_off)
#if defined(_WIN32)
#define WAIT_FD_IN_WIN32(fptr) \
@@ -1713,18 +1715,20 @@ more_char(rb_io_t *fptr)
static VALUE
io_shift_cbuf(rb_io_t *fptr, int len, VALUE *strp)
{
- VALUE str;
- if (NIL_P(*strp)) {
- *strp = str = rb_str_new(fptr->cbuf+fptr->cbuf_off, len);
- }
- else {
- str = *strp;
- rb_str_cat(str, fptr->cbuf+fptr->cbuf_off, len);
+ VALUE str = Qnil;
+ if (strp) {
+ str = *strp;
+ if (NIL_P(str)) {
+ *strp = str = rb_str_new(fptr->cbuf+fptr->cbuf_off, len);
+ }
+ else {
+ rb_str_cat(str, fptr->cbuf+fptr->cbuf_off, len);
+ }
+ OBJ_TAINT(str);
+ rb_enc_associate(str, fptr->encs.enc);
}
fptr->cbuf_off += len;
fptr->cbuf_len -= len;
- OBJ_TAINT(str);
- rb_enc_associate(str, fptr->encs.enc);
/* xxx: set coderange */
if (fptr->cbuf_len == 0)
fptr->cbuf_off = 0;
@@ -2289,6 +2293,35 @@ appendline(rb_io_t *fptr, int delim, VALUE *strp, long *lp)
static inline int
swallow(rb_io_t *fptr, int term)
{
+ if (NEED_READCONV(fptr)) {
+ rb_encoding *enc = io_read_encoding(fptr);
+ int needconv = rb_enc_mbminlen(enc) != 1;
+ VALUE v;
+ make_readconv(fptr, 0);
+ do {
+ size_t cnt;
+ while ((cnt = READ_CHAR_PENDING_COUNT(fptr)) > 0) {
+ const char *p = READ_CHAR_PENDING_PTR(fptr);
+ int i;
+ if (needconv) {
+ if (*p != term) return TRUE;
+ while (--i && *++p == term);
+ }
+ else {
+ const char *e = p + cnt;
+ if (rb_enc_ascget(p, e, &i, enc) != term) return TRUE;
+ while ((p += i) < e && rb_enc_ascget(p, e, &i, enc) == term);
+ i = (int)(e - p);
+ }
+ io_shift_cbuf(fptr, (int)cnt - i, NULL);
+ }
+ v = fill_cbuf(fptr, 0);
+ if (v != MORE_CHAR_SUSPENDED && v != MORE_CHAR_FINISHED)
+ rb_exc_raise(v);
+ } while (v == MORE_CHAR_SUSPENDED);
+ return FALSE;
+ }
+
do {
size_t cnt;
while ((cnt = READ_DATA_PENDING_COUNT(fptr)) > 0) {