/*
* call-seq:
* strio.ungetc(integer) -> nil
*
* Pushes back one character (passed as a parameter) onto *strio*
* such that a subsequent buffered read will return it. Pushing back
* behind the beginning of the buffer string is not possible. Nothing
* will be done if such an attempt is made.
* In other case, there is no limitation for multiple pushbacks.
*/
static VALUE
strio_ungetc(self, ch)
VALUE self, ch;
{
struct StringIO *ptr = readable(StringIO(self));
int cc = NUM2INT(ch);
long len, pos = ptr->pos;
if (cc != EOF) {
len = RSTRING(ptr->string)->len;
if (pos == 0) {
char *p;
rb_str_resize(ptr->string, len + 1);
p = RSTRING(ptr->string)->ptr;
memmove(p + 1, p, len);
}
else {
if (len < pos-- ||
(unsigned char)RSTRING(ptr->string)->ptr[pos] !=
(unsigned char)cc) {
strio_extend(ptr, pos, 1);
}
--ptr->pos;
}
RSTRING(ptr->string)->ptr[pos] = cc;
OBJ_INFECT(ptr->string, self);
ptr->flags &= ~STRIO_EOF;
}
return Qnil;
}