summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--mrbgems/mruby-io/mrblib/io.rb13
-rw-r--r--mrbgems/mruby-io/src/io.c23
-rw-r--r--mrbgems/mruby-io/test/io.rb9
3 files changed, 32 insertions, 13 deletions
diff --git a/mrbgems/mruby-io/mrblib/io.rb b/mrbgems/mruby-io/mrblib/io.rb
index a6e3ef3de..aaf22da2e 100644
--- a/mrbgems/mruby-io/mrblib/io.rb
+++ b/mrbgems/mruby-io/mrblib/io.rb
@@ -208,8 +208,7 @@ class IO
if length
consume = (length <= @buf.bytesize) ? length : @buf.bytesize
- array.push @buf.byteslice(0, consume)
- @buf = @buf.byteslice(consume, @buf.bytesize - consume)
+ array.push IO._bufread(@buf, consume)
length -= consume
break if length == 0
else
@@ -255,13 +254,11 @@ class IO
end
if limit && limit <= @buf.bytesize
- array.push @buf.byteslice(0, limit)
- @buf = @buf.byteslice(limit, @buf.bytesize - limit)
+ array.push IO._bufread(@buf, limit)
break
elsif idx = @buf.index(rs)
len = idx + rs.bytesize
- array.push @buf.byteslice(0, len)
- @buf = @buf.byteslice(len, @buf.bytesize - len)
+ array.push IO._bufread(@buf, len)
break
else
array.push @buf
@@ -284,9 +281,7 @@ class IO
def readchar
_read_buf
- c = @buf.byteslice(0,1)
- @buf = @buf.byteslice(1, @buf.bytesize)
- c
+ IO._bufread(@buf, 1)
end
def getc
diff --git a/mrbgems/mruby-io/src/io.c b/mrbgems/mruby-io/src/io.c
index 784cdaf49..8228097cb 100644
--- a/mrbgems/mruby-io/src/io.c
+++ b/mrbgems/mruby-io/src/io.c
@@ -1294,6 +1294,27 @@ mrb_io_sync(mrb_state *mrb, mrb_value self)
return mrb_bool_value(fptr->sync);
}
+static mrb_value
+io_bufread(mrb_state *mrb, mrb_value self)
+{
+ mrb_value str, str2;
+ mrb_int len, newlen;
+ struct RString *s;
+ char *p;
+
+ mrb_get_args(mrb, "Si", &str, &len);
+ s = RSTRING(str);
+ mrb_str_modify(mrb, s);
+ p = RSTR_PTR(s);
+ str2 = mrb_str_new(mrb, p, len);
+ newlen = RSTR_LEN(s)-len;
+ memmove(p, p+len, newlen);
+ p[newlen] = '\0';
+ RSTR_SET_LEN(s, newlen);
+
+ return str2;
+}
+
void
mrb_init_io(mrb_state *mrb)
{
@@ -1328,4 +1349,6 @@ mrb_init_io(mrb_state *mrb)
mrb_define_method(mrb, io, "closed?", mrb_io_closed, MRB_ARGS_NONE()); /* 15.2.20.5.2 */
mrb_define_method(mrb, io, "pid", mrb_io_pid, MRB_ARGS_NONE()); /* 15.2.20.5.2 */
mrb_define_method(mrb, io, "fileno", mrb_io_fileno, MRB_ARGS_NONE());
+
+ mrb_define_class_method(mrb, io, "_bufread", io_bufread, MRB_ARGS_REQ(2));
}
diff --git a/mrbgems/mruby-io/test/io.rb b/mrbgems/mruby-io/test/io.rb
index 3aaa109a8..e3024cf9a 100644
--- a/mrbgems/mruby-io/test/io.rb
+++ b/mrbgems/mruby-io/test/io.rb
@@ -129,10 +129,11 @@ end
assert "IO#read(n) with n > IO::BUF_SIZE" do
skip "pipe is not supported on this platform" if MRubyIOTestUtil.win?
- r,w = IO.pipe
- n = IO::BUF_SIZE+1
- w.write 'a'*n
- assert_equal r.read(n), 'a'*n
+ IO.pipe do |r,w|
+ n = IO::BUF_SIZE+1
+ w.write 'a'*n
+ assert_equal 'a'*n, r.read(n)
+ end
end
assert('IO#readchar', '15.2.20.5.15') do