From 26f458baab29267129b47bfa142ad15c2dc2dede Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Fri, 30 Dec 2022 13:52:14 +0900 Subject: [PATCH] mruby-io/io.c: implement `IO#ungetc` in C --- mrbgems/mruby-io/mrblib/io.rb | 10 ---------- mrbgems/mruby-io/src/io.c | 17 +++++++++++++++++ 2 files changed, 17 insertions(+), 10 deletions(-) diff --git a/mrbgems/mruby-io/mrblib/io.rb b/mrbgems/mruby-io/mrblib/io.rb index f482f97e2..27c6f554e 100644 --- a/mrbgems/mruby-io/mrblib/io.rb +++ b/mrbgems/mruby-io/mrblib/io.rb @@ -112,16 +112,6 @@ class IO seek(0, SEEK_SET) end - def ungetc(substr) - raise TypeError.new "expect String, got #{substr.class}" unless substr.is_a?(String) - if @buf.empty? - @buf.replace(substr) - else - @buf[0,0] = substr - end - nil - end - def ungetbyte(c) if c.is_a? String c = c.getbyte(0) diff --git a/mrbgems/mruby-io/src/io.c b/mrbgems/mruby-io/src/io.c index bb9485622..0f0cbcde4 100644 --- a/mrbgems/mruby-io/src/io.c +++ b/mrbgems/mruby-io/src/io.c @@ -1540,6 +1540,22 @@ io_pwrite(mrb_state *mrb, mrb_value io) } #endif /* MRB_WITH_IO_PREAD_PWRITE */ +static mrb_value +io_ungetc(mrb_state *mrb, mrb_value io) +{ + mrb_value str, buf; + + io_get_read_fptr(mrb, io); + mrb_get_args(mrb, "S", &str); + buf = io_buf(mrb, io); + str = mrb_str_dup(mrb, str); + if (RSTRING_LEN(buf) > 0) { + mrb_str_cat_str(mrb, str, buf); + } + mrb_iv_set(mrb, io, MRB_IVSYM(buf), str); + return mrb_nil_value(); +} + static mrb_value io_bufread(mrb_state *mrb, mrb_value str, mrb_int len) { @@ -1648,6 +1664,7 @@ mrb_init_io(mrb_state *mrb) mrb_define_method(mrb, io, "close_on_exec=", io_set_close_on_exec, MRB_ARGS_REQ(1)); mrb_define_method(mrb, io, "close_on_exec?", io_close_on_exec_p, MRB_ARGS_NONE()); mrb_define_method(mrb, io, "closed?", io_closed, MRB_ARGS_NONE()); /* 15.2.20.5.2 */ + mrb_define_method(mrb, io, "ungetc", io_ungetc, MRB_ARGS_REQ(1)); mrb_define_method(mrb, io, "pos", io_pos, MRB_ARGS_NONE()); mrb_define_method(mrb, io, "pid", io_pid, MRB_ARGS_NONE()); mrb_define_method(mrb, io, "fileno", io_fileno, MRB_ARGS_NONE());