From 12eee69294f0692eb74b2daeb7dcf8e000491518 Mon Sep 17 00:00:00 2001 From: nobu Date: Tue, 18 Nov 2003 09:09:41 +0000 Subject: * ext/stringio/stringio.c (strio_read): behave as IO at empty string. [ruby-dev:21939] * ext/stringio/stringio.c (strio_getc, strio_getline): set EOF flag. * ext/stringio/stringio.c (strio_rewind, strio_seek, strio_ungetc): clear EOF flag. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@4978 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- ext/stringio/stringio.c | 33 +++++++++++++++++++++++++++------ 1 file changed, 27 insertions(+), 6 deletions(-) (limited to 'ext/stringio/stringio.c') diff --git a/ext/stringio/stringio.c b/ext/stringio/stringio.c index 6dd68fdb40..d6d5b7694a 100644 --- a/ext/stringio/stringio.c +++ b/ext/stringio/stringio.c @@ -16,6 +16,7 @@ #include "rubyio.h" #define STRIO_APPEND 4 +#define STRIO_EOF 8 struct StringIO { VALUE string; @@ -483,6 +484,7 @@ strio_rewind(self) struct StringIO *ptr = StringIO(self); ptr->pos = 0; ptr->lineno = 0; + ptr->flags &= ~STRIO_EOF; return INT2FIX(0); } @@ -514,6 +516,7 @@ strio_seek(argc, argv, self) error_inval(0); } ptr->pos = offset; + ptr->flags &= ~STRIO_EOF; return INT2FIX(0); } @@ -548,6 +551,7 @@ strio_getc(self) struct StringIO *ptr = readable(StringIO(self)); int c; if (ptr->pos >= RSTRING(ptr->string)->len) { + ptr->flags |= STRIO_EOF; return Qnil; } c = RSTRING(ptr->string)->ptr[ptr->pos++]; @@ -578,6 +582,7 @@ strio_ungetc(self, ch) OBJ_INFECT(ptr->string, self); } --ptr->pos; + ptr->flags &= ~STRIO_EOF; } return Qnil; } @@ -649,7 +654,10 @@ strio_getline(argc, argv, ptr) if (!NIL_P(str)) StringValue(str); } - if (ptr->pos >= (n = RSTRING(ptr->string)->len)) return Qnil; + if (ptr->pos >= (n = RSTRING(ptr->string)->len)) { + ptr->flags |= STRIO_EOF; + return Qnil; + } s = RSTRING(ptr->string)->ptr; e = s + RSTRING(ptr->string)->len; s += ptr->pos; @@ -659,7 +667,10 @@ strio_getline(argc, argv, ptr) else if ((n = RSTRING(str)->len) == 0) { p = s; while (*p == '\n') { - if (++p == e) return Qnil; + if (++p == e) { + ptr->flags |= STRIO_EOF; + return Qnil; + } } s = p; while (p = memchr(p, '\n', e - p)) { @@ -827,24 +838,34 @@ strio_read(argc, argv, self) VALUE str; long len; - if (ptr->pos >= RSTRING(ptr->string)->len) { - return Qnil; - } switch (argc) { case 1: if (!NIL_P(argv[0])) { len = NUM2LONG(argv[0]); + if (len < 0) { + rb_raise(rb_eArgError, "negative length %ld given", len); + } + if (len > 0 && ptr->pos >= RSTRING(ptr->string)->len) { + ptr->flags |= STRIO_EOF; + return Qnil; + } break; } /* fall through */ case 0: len = RSTRING(ptr->string)->len - ptr->pos; + if (len == 0 && ptr->pos == RSTRING(ptr->string)->len) { + if (ptr->flags & STRIO_EOF) return Qnil; + } break; default: rb_raise(rb_eArgError, "wrong number arguments (%d for 0)", argc); } str = rb_str_substr(ptr->string, ptr->pos, len); - ptr->pos += len; + if (len > 0 && + (NIL_P(str) || (ptr->pos += RSTRING(str)->len) >= RSTRING(ptr->string)->len)) { + ptr->flags |= STRIO_EOF; + } return str; } -- cgit v1.2.3