1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00

stringio.c: padding in ungetbyte

* ext/stringio/stringio.c (strio_ungetbyte): pad with \000 when
  the current position is after the end.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@53181 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
nobu 2015-12-18 03:09:16 +00:00
parent 07f53e4830
commit b7d1536991
3 changed files with 50 additions and 7 deletions

View file

@ -1,3 +1,8 @@
Fri Dec 18 12:09:21 2015 Nobuyoshi Nakada <nobu@ruby-lang.org>
* ext/stringio/stringio.c (strio_ungetbyte): pad with \000 when
the current position is after the end.
Fri Dec 18 11:24:48 2015 Shugo Maeda <shugo@ruby-lang.org>
* vm_method.c (rb_method_entry_make, check_override_opt_method):

View file

@ -780,8 +780,9 @@ strio_ungetbyte(VALUE self, VALUE c)
{
struct StringIO *ptr = readable(self);
char buf[1], *cp = buf;
long pos = ptr->pos, cl = 1;
long pos = ptr->pos, cl = 1, len, rest;
VALUE str = ptr->string;
char *s;
if (NIL_P(c)) return Qnil;
if (FIXNUM_P(c)) {
@ -794,19 +795,26 @@ strio_ungetbyte(VALUE self, VALUE c)
if (cl == 0) return Qnil;
}
check_modifiable(ptr);
rb_str_modify(str);
len = RSTRING_LEN(str);
rest = pos - len;
if (cl > pos) {
char *s;
long rest = RSTRING_LEN(str) - pos;
rb_str_resize(str, rest + cl);
long ex = (rest < 0 ? cl-pos : cl+rest);
rb_str_modify_expand(str, ex);
rb_str_set_len(str, len + ex);
s = RSTRING_PTR(str);
memmove(s + cl, s + pos, rest);
if (rest < 0) memmove(s + cl, s + pos, -rest);
pos = 0;
}
else {
if (rest > 0) {
rb_str_modify_expand(str, rest);
rb_str_set_len(str, len + rest);
}
s = RSTRING_PTR(str);
if (rest > cl) memset(s + len, 0, rest - cl);
pos -= cl;
}
memcpy(RSTRING_PTR(str) + pos, cp, cl);
memcpy(s + pos, cp, cl);
ptr->pos = pos;
RB_GC_GUARD(c);
return Qnil;

View file

@ -362,6 +362,11 @@ class TestStringIO < Test::Unit::TestCase
t.ungetbyte("\xe7")
t.ungetbyte("\xe7\xb4\x85")
assert_equal("\u7d05\u7389bar\n", t.gets)
assert_equal("q\u7d05\u7389bar\n", s)
t.pos = 1
t.ungetbyte("\u{30eb 30d3 30fc}")
assert_equal(0, t.pos)
assert_equal("\u{30eb 30d3 30fc}\u7d05\u7389bar\n", s)
end
def test_ungetc
@ -582,6 +587,31 @@ class TestStringIO < Test::Unit::TestCase
assert_equal("b""\0""a", s.string)
end
def test_ungetbyte_pos
b = '\\b00010001 \\B00010001 \\b1 \\B1 \\b000100011'
s = StringIO.new( b )
expected_pos = 0
while n = s.getbyte
assert_equal( expected_pos + 1, s.pos )
s.ungetbyte( n )
assert_equal( expected_pos, s.pos )
assert_equal( n, s.getbyte )
expected_pos += 1
end
end
def test_ungetbyte_padding
s = StringIO.new()
s.pos = 2
s.ungetbyte("a".ord)
assert_equal("\0""a", s.string)
s.pos = 0
s.ungetbyte("b".ord)
assert_equal("b""\0""a", s.string)
end
def test_frozen
s = StringIO.new
s.freeze