summaryrefslogtreecommitdiff
path: root/io.c
diff options
context:
space:
mode:
authorusa <usa@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2010-05-13 03:55:19 +0000
committerusa <usa@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2010-05-13 03:55:19 +0000
commitef7992801df0c91b49fff8465d19f114d9d069dc (patch)
treeba65e8f4bc3d00c99d06acb3fcf5f70ade9acfbf /io.c
parent2603874f8f657de3747d57f2fe17f0da3d2bfa58 (diff)
* io.c (swallow): support text mode and UTF-16/32 as internal encoding.
* io.c (io_shift_cbuf): read and throw it away when str is NULL. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@27768 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 b3caf4b1bc..79f155eea9 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)) {
+ 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);
+ rb_encoding *enc = io_read_encoding(fptr);
+ int i;
+ if (rb_enc_mbminlen(enc) == 1) {
+ 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) {