зеркало из https://github.com/github/ruby.git
* io.c (io_ungetbyte): renamed from io_ungetc.
(rb_io_ungetbyte): new method. (rb_io_ungetc): push back into character buffer if enc2 is set. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@18694 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
Родитель
e32e9a06e4
Коммит
1b821cb4a3
|
@ -1,3 +1,9 @@
|
||||||
|
Mon Aug 18 23:27:07 2008 Tanaka Akira <akr@fsij.org>
|
||||||
|
|
||||||
|
* io.c (io_ungetbyte): renamed from io_ungetc.
|
||||||
|
(rb_io_ungetbyte): new method.
|
||||||
|
(rb_io_ungetc): push back into character buffer if enc2 is set.
|
||||||
|
|
||||||
Mon Aug 18 22:41:46 2008 Tanaka Akira <akr@fsij.org>
|
Mon Aug 18 22:41:46 2008 Tanaka Akira <akr@fsij.org>
|
||||||
|
|
||||||
* io.c (id_encode): removed.
|
* io.c (id_encode): removed.
|
||||||
|
|
65
io.c
65
io.c
|
@ -326,14 +326,10 @@ io_unread(rb_io_t *fptr)
|
||||||
static rb_encoding *io_input_encoding(rb_io_t *fptr);
|
static rb_encoding *io_input_encoding(rb_io_t *fptr);
|
||||||
|
|
||||||
static void
|
static void
|
||||||
io_ungetc(VALUE str, rb_io_t *fptr)
|
io_ungetbyte(VALUE str, rb_io_t *fptr)
|
||||||
{
|
{
|
||||||
int len = RSTRING_LEN(str);
|
int len = RSTRING_LEN(str);
|
||||||
|
|
||||||
if (rb_enc_dummy_p(io_input_encoding(fptr))) {
|
|
||||||
rb_raise(rb_eNotImpError, "ungetc against dummy encoding is not currently supported");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (fptr->rbuf == NULL) {
|
if (fptr->rbuf == NULL) {
|
||||||
fptr->rbuf_off = 0;
|
fptr->rbuf_off = 0;
|
||||||
fptr->rbuf_len = 0;
|
fptr->rbuf_len = 0;
|
||||||
|
@ -344,7 +340,7 @@ io_ungetc(VALUE str, rb_io_t *fptr)
|
||||||
fptr->rbuf = ALLOC_N(char, fptr->rbuf_capa);
|
fptr->rbuf = ALLOC_N(char, fptr->rbuf_capa);
|
||||||
}
|
}
|
||||||
if (fptr->rbuf_capa < len + fptr->rbuf_len) {
|
if (fptr->rbuf_capa < len + fptr->rbuf_len) {
|
||||||
rb_raise(rb_eIOError, "ungetc failed");
|
rb_raise(rb_eIOError, "ungetbyte failed");
|
||||||
}
|
}
|
||||||
if (fptr->rbuf_off < len) {
|
if (fptr->rbuf_off < len) {
|
||||||
MEMMOVE(fptr->rbuf+fptr->rbuf_capa-fptr->rbuf_len,
|
MEMMOVE(fptr->rbuf+fptr->rbuf_capa-fptr->rbuf_len,
|
||||||
|
@ -2713,6 +2709,42 @@ rb_io_readbyte(VALUE io)
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* call-seq:
|
||||||
|
* ios.ungetbyte(string) => nil
|
||||||
|
* ios.ungetbyte(integer) => nil
|
||||||
|
*
|
||||||
|
* Pushes back bytes (passed as a parameter) onto <em>ios</em>,
|
||||||
|
* such that a subsequent buffered read will return it. Only one byte
|
||||||
|
* may be pushed back before a subsequent read operation (that is,
|
||||||
|
* you will be able to read only the last of several bytes that have been pushed
|
||||||
|
* back). Has no effect with unbuffered reads (such as <code>IO#sysread</code>).
|
||||||
|
*
|
||||||
|
* f = File.new("testfile") #=> #<File:testfile>
|
||||||
|
* b = f.getbyte #=> 0x38
|
||||||
|
* f.ungetbyte(b) #=> nil
|
||||||
|
* f.getbyte #=> 0x38
|
||||||
|
*/
|
||||||
|
|
||||||
|
VALUE
|
||||||
|
rb_io_ungetbyte(VALUE io, VALUE b)
|
||||||
|
{
|
||||||
|
rb_io_t *fptr;
|
||||||
|
|
||||||
|
GetOpenFile(io, fptr);
|
||||||
|
rb_io_check_readable(fptr);
|
||||||
|
if (NIL_P(b)) return Qnil;
|
||||||
|
if (FIXNUM_P(b)) {
|
||||||
|
char cc = FIX2INT(b);
|
||||||
|
b = rb_str_new(&cc, 1);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
SafeStringValue(b);
|
||||||
|
}
|
||||||
|
io_ungetbyte(b, fptr);
|
||||||
|
return Qnil;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* call-seq:
|
* call-seq:
|
||||||
* ios.ungetc(string) => nil
|
* ios.ungetc(string) => nil
|
||||||
|
@ -2733,6 +2765,7 @@ VALUE
|
||||||
rb_io_ungetc(VALUE io, VALUE c)
|
rb_io_ungetc(VALUE io, VALUE c)
|
||||||
{
|
{
|
||||||
rb_io_t *fptr;
|
rb_io_t *fptr;
|
||||||
|
long len;
|
||||||
|
|
||||||
GetOpenFile(io, fptr);
|
GetOpenFile(io, fptr);
|
||||||
rb_io_check_readable(fptr);
|
rb_io_check_readable(fptr);
|
||||||
|
@ -2747,7 +2780,24 @@ rb_io_ungetc(VALUE io, VALUE c)
|
||||||
else {
|
else {
|
||||||
SafeStringValue(c);
|
SafeStringValue(c);
|
||||||
}
|
}
|
||||||
io_ungetc(c, fptr);
|
if (fptr->enc2) {
|
||||||
|
make_readconv(fptr);
|
||||||
|
len = RSTRING_LEN(c);
|
||||||
|
if (fptr->crbuf_capa - fptr->crbuf_len < len)
|
||||||
|
rb_raise(rb_eIOError, "ungetc failed");
|
||||||
|
if (fptr->crbuf_off < len) {
|
||||||
|
MEMMOVE(fptr->crbuf+fptr->crbuf_capa-fptr->crbuf_len,
|
||||||
|
fptr->crbuf+fptr->crbuf_off,
|
||||||
|
char, fptr->crbuf_len);
|
||||||
|
fptr->crbuf_off = fptr->crbuf_capa-fptr->crbuf_len;
|
||||||
|
}
|
||||||
|
fptr->crbuf_off -= len;
|
||||||
|
fptr->crbuf_len += len;
|
||||||
|
MEMMOVE(fptr->crbuf+fptr->crbuf_off, RSTRING_PTR(c), char, len);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
io_ungetbyte(c, fptr);
|
||||||
|
}
|
||||||
return Qnil;
|
return Qnil;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8019,6 +8069,7 @@ Init_IO(void)
|
||||||
rb_define_method(rb_cIO, "getbyte", rb_io_getbyte, 0);
|
rb_define_method(rb_cIO, "getbyte", rb_io_getbyte, 0);
|
||||||
rb_define_method(rb_cIO, "readchar", rb_io_readchar, 0);
|
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, "readbyte", rb_io_readbyte, 0);
|
||||||
|
rb_define_method(rb_cIO, "ungetbyte",rb_io_ungetbyte, 1);
|
||||||
rb_define_method(rb_cIO, "ungetc",rb_io_ungetc, 1);
|
rb_define_method(rb_cIO, "ungetc",rb_io_ungetc, 1);
|
||||||
rb_define_method(rb_cIO, "<<", rb_io_addstr, 1);
|
rb_define_method(rb_cIO, "<<", rb_io_addstr, 1);
|
||||||
rb_define_method(rb_cIO, "flush", rb_io_flush, 0);
|
rb_define_method(rb_cIO, "flush", rb_io_flush, 0);
|
||||||
|
|
|
@ -239,14 +239,30 @@ EOT
|
||||||
with_tmpdir {
|
with_tmpdir {
|
||||||
src = "before \e$B\x23\x30\x23\x31\e(B after".force_encoding("iso-2022-jp")
|
src = "before \e$B\x23\x30\x23\x31\e(B after".force_encoding("iso-2022-jp")
|
||||||
generate_file('tmp', src)
|
generate_file('tmp', src)
|
||||||
assert_raise(NotImplementedError) do
|
|
||||||
s = open("tmp", "r:iso-2022-jp:euc-jp") {|f|
|
s = open("tmp", "r:iso-2022-jp:euc-jp") {|f|
|
||||||
f.ungetc("0".force_encoding("euc-jp"))
|
f.ungetc("0".force_encoding("euc-jp"))
|
||||||
f.read
|
f.read
|
||||||
}
|
}
|
||||||
assert_equal(Encoding.find("euc-jp"), s.encoding)
|
assert_equal(Encoding.find("euc-jp"), s.encoding)
|
||||||
assert_str_equal(("0" + src).encode("euc-jp"), s)
|
assert_str_equal("0" + src.encode("euc-jp"), s)
|
||||||
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_ungetc_stateful_conversion2
|
||||||
|
with_tmpdir {
|
||||||
|
src = "before \e$B\x23\x30\x23\x31\e(B after".force_encoding("iso-2022-jp")
|
||||||
|
former = "before \e$B\x23\x30\e(B".force_encoding("iso-2022-jp")
|
||||||
|
rs = "\e$B\x23\x30\e(B".force_encoding("iso-2022-jp")
|
||||||
|
latter = "\e$B\x23\x31\e(B after".force_encoding("iso-2022-jp")
|
||||||
|
generate_file('tmp', src)
|
||||||
|
s = open("tmp", "r:iso-2022-jp:euc-jp") {|f|
|
||||||
|
assert_equal(former.encode("euc-jp", "iso-2022-jp"),
|
||||||
|
f.gets(rs.encode("euc-jp", "iso-2022-jp")))
|
||||||
|
f.ungetc("0")
|
||||||
|
f.read
|
||||||
|
}
|
||||||
|
assert_equal(Encoding.find("euc-jp"), s.encoding)
|
||||||
|
assert_str_equal("0" + latter.encode("euc-jp"), s)
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
Загрузка…
Ссылка в новой задаче