mruby-io/io.c: implement `IO#ungetc` in C
MODIFY
mrbgems/mruby-io/mrblib/io.rb
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)

MODIFY
mrbgems/mruby-io/src/io.c
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());

mruby-io/io.c: implement `IO#ungetc` in C