/* * 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; }