e$B$J$+$@$G$9!#e(B
At Mon, 3 Mar 2008 00:54:33 +0900,
Tanaka A. wrote in [ruby-dev:33960]:
io_ungetc(c, fptr);
encdetect e$B$r<BAu$9$k$K$O!“e(BIO e$B$+$i%P%$%HNs$GFI$_=P$7$?$b$N$re(B
e$B%P%$%HNs$H$7$Fe(B ungetc e$B$9$k$3$H$,I,MW$J$s$G$9$,!”$=$l$O$G$-$ke(B
e$B$G$7$g$&$+!#e(B
e$B$=$l$O8=>u$G$b$G$-$J$$$G$9$M!#e(B?xe$B$be(BStringe$B$K$J$C$?$3$H$G$b$"$k$7!“e(B
0…255e$B$N@0?t$NJB$S$O%P%$%HNs$H$7$FLa$9!”$H$$$&$N$G$b$$$$$+$b!#e(B
e$BJL%a%=%C%I$+$J$!e(B?
getce$B$He(Bgetbytee$B$bJ,$1$?$3$H$r9M$($l$P!"$3$C$A$G$9$+$M$’!#e(B
ungetbytee$B$H$$$&$N$O$$$^$$$A$J5$$,$7$^$9$,!#e(B
Index: io.c
— io.c (revision 15671)
+++ io.c (working copy)
@@ -312,9 +312,7 @@ io_unread(rb_io_t *fptr)
}
-static void
-io_ungetc(VALUE str, rb_io_t *fptr)
+static char *
+io_unget_space(long len, rb_io_t *fptr)
{
- int len = RSTRING_LEN(str);
- if (fptr->rbuf == NULL) {
fptr->rbuf_off = 0;
@@ -337,5 +335,11 @@ io_ungetc(VALUE str, rb_io_t *fptr)
fptr->rbuf_off-=len;
fptr->rbuf_len+=len;
- MEMMOVE(fptr->rbuf+fptr->rbuf_off, RSTRING_PTR(str), char, len);
- return fptr->rbuf+fptr->rbuf_off;
+}
-
+static void
+io_ungetc(const char *ptr, long len, rb_io_t *fptr)
+{
- MEMMOVE(io_unget_space(len, fptr), ptr, char, len);
}
@@ -680,10 +684,10 @@ io_fwrite(VALUE str, rb_io_t fptr)
/ Can’t use encode! because puts writes a frozen newline */
if (fptr->enc2) {
-
str = rb_funcall(str, id_encode, 2,
rb_enc_from_encoding(fptr->enc2),
rb_enc_from_encoding(fptr->enc));
}
else {
- str = rb_funcall(str, id_encode, 2,
- str = rb_funcall(str, id_encode, 2,
rb_enc_from_encoding(fptr->enc),
rb_enc_from_encoding(fptr->enc2));
@@ -1896,5 +1900,5 @@ prepare_getline_args(int argc, VALUE *ar
if (fptr->enc2) {
VALUE rs2;
-
rs2 = rb_funcall(rs, id_encode, 2,
rb_enc_from_encoding(fptr->enc2),
rb_enc_from_encoding(fptr->enc));
@@ -2414,10 +2418,11 @@ rb_io_readbyte(VALUE io)
-
- Pushes back one character (passed as a parameter) onto
ios,
-
- such that a subsequent buffered read will return it. Only one
character
-
- may be pushed back before a subsequent read operation (that is,
-
- you will be able to read only the last of several characters that
have been pushed
-
- back). Has no effect with unbuffered reads (such as
IO#sysread
).
-
- Pushes back character string or byte sequence (passed as a
-
- parameter) onto ios, such that a subsequent buffered read
-
- will return it. Has no effect with unbuffered reads (such as
-
@@ -2425,25 +2430,89 @@ rb_io_readbyte(VALUE io)
-
f.ungetc(c) #=> nil
-
f.getc #=> "8"
VALUE
-rb_io_ungetc(VALUE io, VALUE c)
+rb_io_unget(int argc, VALUE *argv, VALUE io)
{
rb_io_t *fptr;
-
VALUE c;
GetOpenFile(io, fptr);
rb_io_check_readable(fptr);
-
if (argc < 1) return Qnil;
-
if (argc > 1) { /* expects byte array */
-
/* use temporary buffer to get rid of race condition */
-
volatile VALUE str = rb_str_tmp_new(argc);
-
char *ptr = RSTRING_PTR(str);
-
int i;
-
-
for (i = 0; i < argc; ++i) {
-
c = argv[i];
-
ptr[i] = (char)NUM2INT(c);
-
}
-
io_ungetc(ptr, argc, fptr);
-
rb_str_resize(str, 0);
-
return Qnil;
-
}
-
c = argv[0];
if (NIL_P©) return Qnil;
if (FIXNUM_P©) {
- int cc = FIX2INT©;
- rb_encoding *enc = io_read_encoding(fptr);
- char buf[16];
- char cc = (char)FIX2INT©;
- c = rb_str_new(buf, rb_enc_mbcput(cc, buf, enc));
+VALUE
+rb_io_ungetc(VALUE io, VALUE c)
+{
- VALUE ary = rb_check_array_type©;
- if (!NIL_P(ary)) {
- rb_io_unget(RARRAY_LEN(ary), RARRAY_PTR(ary), io);
- RB_GC_GUARD(ary);
}
- else {
- rb_io_unget(1, &c, io);
- }
- return Qnil;
+}
-
+/*
-
-
-
-
- Pushes back one character (passed as a parameter) onto
-
-
ios, such that a subsequent buffered read will return it.
-
-
-
-
-
-
- */
-
+VALUE
+rb_io_ungetbyte(VALUE io, VALUE c)
+{
- rb_io_t *fptr;
- int cc;
-
- GetOpenFile(io, fptr);
- rb_io_check_readable(fptr);
- if (NIL_P©) return Qnil;
- cc = NUM2INT©;
- *io_unget_space(1, fptr) = (char)cc;
return Qnil;
}
@@ -6789,5 +6858,6 @@ Init_IO(void)
rb_define_method(rb_cIO, “readchar”, rb_io_readchar, 0);
rb_define_method(rb_cIO, “readbyte”, rb_io_readbyte, 0);
- rb_define_method(rb_cIO, “ungetc”,rb_io_ungetc, 1);
- rb_define_method(rb_cIO, “ungetc”, rb_io_unget, -1);
- rb_define_method(rb_cIO, “ungetbyte”, rb_io_ungetbyte, 1);
rb_define_method(rb_cIO, “<<”, rb_io_addstr, 1);
rb_define_method(rb_cIO, “flush”, rb_io_flush, 0);