diff options
| author | Yukihiro "Matz" Matsumoto <[email protected]> | 2019-09-14 15:58:11 +0900 |
|---|---|---|
| committer | Yukihiro "Matz" Matsumoto <[email protected]> | 2019-09-14 23:21:44 +0900 |
| commit | 6f1c08f7d8a43a5d220aca7a5c449a8d04d3017b (patch) | |
| tree | 909b7875490061854828f40e5495e8cc335c631d | |
| parent | dcc2d44d930ee5dea7e737ad6fa298d3f4bf9f59 (diff) | |
| download | mruby-6f1c08f7d8a43a5d220aca7a5c449a8d04d3017b.tar.gz mruby-6f1c08f7d8a43a5d220aca7a5c449a8d04d3017b.zip | |
Replace `String#byteslice` by custom `IO._bufread`.
`byteslice` creates 2 string objects. `_bufread` creates one, and
modifies the original buffer string, that is more efficient.
| -rw-r--r-- | mrbgems/mruby-io/mrblib/io.rb | 13 | ||||
| -rw-r--r-- | mrbgems/mruby-io/src/io.c | 23 | ||||
| -rw-r--r-- | mrbgems/mruby-io/test/io.rb | 9 |
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 |
