Data
Pseudo I/O on String object.
Creates new StringIO instance from with string and mode.
static VALUE strio_initialize(int argc, VALUE *argv, VALUE self) { struct StringIO *ptr = check_strio(self); if (!ptr) { DATA_PTR(self) = ptr = strio_alloc(); } rb_call_super(0, 0); strio_init(argc, argv, ptr); return self; }
Equivalent to ::new except that when it is called with a block, it yields with the new instance and closes it, and returns the result which returned from the block.
static VALUE strio_s_open(int argc, VALUE *argv, VALUE klass) { VALUE obj = rb_class_new_instance(argc, argv, klass); if (!rb_block_given_p()) return obj; return rb_ensure(rb_yield, obj, strio_finalize, obj); }
See IO#each_byte.
static VALUE strio_each_byte(VALUE self) { struct StringIO *ptr = readable(StringIO(self)); RETURN_ENUMERATOR(self, 0, 0); while (ptr->pos < RSTRING_LEN(ptr->string)) { char c = RSTRING_PTR(ptr->string)[ptr->pos++]; rb_yield(CHR2FIX(c)); } return self; }
See IO#each_char.
static VALUE strio_each_char(VALUE self) { VALUE c; RETURN_ENUMERATOR(self, 0, 0); while (!NIL_P(c = strio_getc(self))) { rb_yield(c); } return self; }
Closes strio. The strio is unavailable for any further
data operations; an IOError
is raised if such an attempt is
made.
static VALUE strio_close(VALUE self) { struct StringIO *ptr = StringIO(self); if (CLOSED(ptr)) { rb_raise(rb_eIOError, "closed stream"); } ptr->flags &= ~FMODE_READWRITE; return Qnil; }
Closes the read end of a StringIO. Will raise
an IOError
if the strio is not readable.
static VALUE strio_close_read(VALUE self) { struct StringIO *ptr = StringIO(self); if (!READABLE(ptr)) { rb_raise(rb_eIOError, "closing non-duplex IO for reading"); } ptr->flags &= ~FMODE_READABLE; return Qnil; }
Closes the write end of a StringIO. Will raise
an IOError
if the strio is not writeable.
static VALUE strio_close_write(VALUE self) { struct StringIO *ptr = StringIO(self); if (!WRITABLE(ptr)) { rb_raise(rb_eIOError, "closing non-duplex IO for writing"); } ptr->flags &= ~FMODE_WRITABLE; return Qnil; }
Returns true
if strio is completely closed,
false
otherwise.
static VALUE strio_closed(VALUE self) { struct StringIO *ptr = StringIO(self); if (!CLOSED(ptr)) return Qfalse; return Qtrue; }
Returns true
if strio is not readable,
false
otherwise.
static VALUE strio_closed_read(VALUE self) { struct StringIO *ptr = StringIO(self); if (READABLE(ptr)) return Qfalse; return Qtrue; }
Returns true
if strio is not writable,
false
otherwise.
static VALUE strio_closed_write(VALUE self) { struct StringIO *ptr = StringIO(self); if (WRITABLE(ptr)) return Qfalse; return Qtrue; }
See IO#each.
static VALUE strio_each(int argc, VALUE *argv, VALUE self) { struct StringIO *ptr = StringIO(self); VALUE line; RETURN_ENUMERATOR(self, argc, argv); while (!NIL_P(line = strio_getline(argc, argv, readable(ptr)))) { rb_yield(line); } return self; }
See IO#each_byte.
static VALUE strio_each_byte(VALUE self) { struct StringIO *ptr = readable(StringIO(self)); RETURN_ENUMERATOR(self, 0, 0); while (ptr->pos < RSTRING_LEN(ptr->string)) { char c = RSTRING_PTR(ptr->string)[ptr->pos++]; rb_yield(CHR2FIX(c)); } return self; }
See IO#each_char.
static VALUE strio_each_char(VALUE self) { VALUE c; RETURN_ENUMERATOR(self, 0, 0); while (!NIL_P(c = strio_getc(self))) { rb_yield(c); } return self; }
See IO#each.
static VALUE strio_each(int argc, VALUE *argv, VALUE self) { struct StringIO *ptr = StringIO(self); VALUE line; RETURN_ENUMERATOR(self, argc, argv); while (!NIL_P(line = strio_getline(argc, argv, readable(ptr)))) { rb_yield(line); } return self; }
Returns true if strio is at end of file. The stringio must be
opened for reading or an IOError
will be raised.
static VALUE strio_eof(VALUE self) { struct StringIO *ptr = readable(StringIO(self)); if (ptr->pos < RSTRING_LEN(ptr->string)) return Qfalse; return Qtrue; }
Returns true if strio is at end of file. The stringio must be
opened for reading or an IOError
will be raised.
static VALUE strio_eof(VALUE self) { struct StringIO *ptr = readable(StringIO(self)); if (ptr->pos < RSTRING_LEN(ptr->string)) return Qfalse; return Qtrue; }
Returns the Encoding object that represents the encoding of the file. If
strio is write mode and no encoding is specified, returns nil
.
static VALUE strio_external_encoding(VALUE self) { return rb_enc_from_encoding(rb_enc_get(StringIO(self)->string)); }
See IO#getbyte.
static VALUE strio_getbyte(VALUE self) { struct StringIO *ptr = readable(StringIO(self)); int c; if (ptr->pos >= RSTRING_LEN(ptr->string)) { return Qnil; } c = RSTRING_PTR(ptr->string)[ptr->pos++]; return CHR2FIX(c); }
See IO#getc.
static VALUE strio_getc(VALUE self) { struct StringIO *ptr = readable(StringIO(self)); rb_encoding *enc = rb_enc_get(ptr->string); int len; char *p; if (ptr->pos >= RSTRING_LEN(ptr->string)) { return Qnil; } p = RSTRING_PTR(ptr->string)+ptr->pos; len = rb_enc_mbclen(p, RSTRING_END(ptr->string), enc); ptr->pos += len; return rb_enc_str_new(p, len, rb_enc_get(ptr->string)); }
See IO#gets.
static VALUE strio_gets(int argc, VALUE *argv, VALUE self) { VALUE str = strio_getline(argc, argv, readable(StringIO(self))); rb_lastline_set(str); return str; }
Returns the Encoding of the internal string if conversion is specified. Otherwise returns nil.
static VALUE strio_internal_encoding(VALUE self) { return Qnil; }
Returns the size of the buffer string.
static VALUE strio_size(VALUE self) { VALUE string = StringIO(self)->string; if (NIL_P(string)) { rb_raise(rb_eIOError, "not opened"); } return ULONG2NUM(RSTRING_LEN(string)); }
Returns the current line number in strio. The stringio
must be opened for reading. lineno
counts the number of times
gets
is called, rather than the number of newlines
encountered. The two values will differ if gets
is called
with a separator other than newline. See also the $.
variable.
static VALUE strio_get_lineno(VALUE self) { return LONG2NUM(StringIO(self)->lineno); }
Manually sets the current line number to the given value. $.
is updated only on the next read.
static VALUE strio_set_lineno(VALUE self, VALUE lineno) { StringIO(self)->lineno = NUM2LONG(lineno); return lineno; }
See IO#each.
static VALUE strio_each(int argc, VALUE *argv, VALUE self) { struct StringIO *ptr = StringIO(self); VALUE line; RETURN_ENUMERATOR(self, argc, argv); while (!NIL_P(line = strio_getline(argc, argv, readable(ptr)))) { rb_yield(line); } return self; }
Returns the current offset (in bytes) of strio.
static VALUE strio_get_pos(VALUE self) { return LONG2NUM(StringIO(self)->pos); }
Seeks to the given position (in bytes) in strio.
static VALUE strio_set_pos(VALUE self, VALUE pos) { struct StringIO *ptr = StringIO(self); long p = NUM2LONG(pos); if (p < 0) { error_inval(0); } ptr->pos = p; return pos; }
See IO#print.
#define strio_print rb_io_print
See IO#printf.
#define strio_printf rb_io_printf
See IO#putc.
static VALUE strio_putc(VALUE self, VALUE ch) { struct StringIO *ptr = writable(StringIO(self)); int c = NUM2CHR(ch); long olen; check_modifiable(ptr); olen = RSTRING_LEN(ptr->string); if (ptr->flags & FMODE_APPEND) { ptr->pos = olen; } strio_extend(ptr, ptr->pos, 1); RSTRING_PTR(ptr->string)[ptr->pos++] = c; OBJ_INFECT(ptr->string, self); return ch; }
See IO#read.
static VALUE strio_read(int argc, VALUE *argv, VALUE self) { struct StringIO *ptr = readable(StringIO(self)); VALUE str = Qnil; long len; switch (argc) { case 2: str = argv[1]; StringValue(str); rb_str_modify(str); case 1: if (!NIL_P(argv[0])) { len = NUM2LONG(argv[0]); if (len < 0) { rb_raise(rb_eArgError, "negative length %ld given", len); } if (len > 0 && ptr->pos >= RSTRING_LEN(ptr->string)) { if (!NIL_P(str)) rb_str_resize(str, 0); return Qnil; } break; } /* fall through */ case 0: len = RSTRING_LEN(ptr->string); if (len <= ptr->pos) { if (NIL_P(str)) { str = rb_str_new(0, 0); } else { rb_str_resize(str, 0); } return str; } else { len -= ptr->pos; } break; default: rb_raise(rb_eArgError, "wrong number of arguments (%d for 0)", argc); } if (NIL_P(str)) { str = strio_substr(ptr, ptr->pos, len); if (argc > 0) rb_enc_associate(str, rb_ascii8bit_encoding()); } else { long rest = RSTRING_LEN(ptr->string) - ptr->pos; if (len > rest) len = rest; rb_str_resize(str, len); MEMCPY(RSTRING_PTR(str), RSTRING_PTR(ptr->string) + ptr->pos, char, len); } if (NIL_P(str)) { str = rb_str_new(0, 0); len = 0; } else { ptr->pos += len = RSTRING_LEN(str); } return str; }
See IO#readbyte.
static VALUE strio_readbyte(VALUE self) { VALUE c = strio_getbyte(self); if (NIL_P(c)) rb_eof_error(); return c; }
See IO#readchar.
static VALUE strio_readchar(VALUE self) { VALUE c = strio_getc(self); if (NIL_P(c)) rb_eof_error(); return c; }
See IO#readline.
static VALUE strio_readline(int argc, VALUE *argv, VALUE self) { VALUE line = strio_gets(argc, argv, self); if (NIL_P(line)) rb_eof_error(); return line; }
See IO#readlines.
static VALUE strio_readlines(int argc, VALUE *argv, VALUE self) { struct StringIO *ptr = StringIO(self); VALUE ary = rb_ary_new(), line; while (!NIL_P(line = strio_getline(argc, argv, readable(ptr)))) { rb_ary_push(ary, line); } return ary; }
Similar to read, but raises
EOFError
at end of string instead of returning
nil
, as well as IO#sysread does.
static VALUE strio_sysread(int argc, VALUE *argv, VALUE self) { VALUE val = strio_read(argc, argv, self); if (NIL_P(val)) { rb_eof_error(); } return val; }
Reinitializes strio with the given other_StrIO or string and mode (see StringIO#new).
static VALUE strio_reopen(int argc, VALUE *argv, VALUE self) { if (!OBJ_TAINTED(self)) rb_secure(4); if (argc == 1 && TYPE(*argv) != T_STRING) { return strio_copy(self, *argv); } strio_init(argc, argv, StringIO(self)); return self; }
Positions strio to the beginning of input, resetting
lineno
to zero.
static VALUE strio_rewind(VALUE self) { struct StringIO *ptr = StringIO(self); ptr->pos = 0; ptr->lineno = 0; return INT2FIX(0); }
Seeks to a given offset amount in the stream according to the value of whence (see IO#seek).
static VALUE strio_seek(int argc, VALUE *argv, VALUE self) { VALUE whence; struct StringIO *ptr = StringIO(self); long offset; rb_scan_args(argc, argv, "11", NULL, &whence); offset = NUM2LONG(argv[0]); if (CLOSED(ptr)) { rb_raise(rb_eIOError, "closed stream"); } switch (NIL_P(whence) ? 0 : NUM2LONG(whence)) { case 0: break; case 1: offset += ptr->pos; break; case 2: offset += RSTRING_LEN(ptr->string); break; default: error_inval("invalid whence"); } if (offset < 0) { error_inval(0); } ptr->pos = offset; return INT2FIX(0); }
Tagged with the encoding specified.
static VALUE strio_set_encoding(VALUE self, VALUE ext_enc) { rb_encoding* enc; VALUE str = StringIO(self)->string; enc = rb_to_encoding(ext_enc); rb_enc_associate(str, enc); return self; }
Returns the size of the buffer string.
static VALUE strio_size(VALUE self) { VALUE string = StringIO(self)->string; if (NIL_P(string)) { rb_raise(rb_eIOError, "not opened"); } return ULONG2NUM(RSTRING_LEN(string)); }
Returns underlying String object, the subject of IO.
static VALUE strio_get_string(VALUE self) { return StringIO(self)->string; }
Changes underlying String object, the subject of IO.
static VALUE strio_set_string(VALUE self, VALUE string) { struct StringIO *ptr = StringIO(self); if (!OBJ_TAINTED(self)) rb_secure(4); ptr->flags &= ~FMODE_READWRITE; StringValue(string); ptr->flags = OBJ_FROZEN(string) ? FMODE_READABLE : FMODE_READWRITE; ptr->pos = 0; ptr->lineno = 0; return ptr->string = string; }
Returns true
always.
static VALUE strio_get_sync(VALUE self) { StringIO(self); return Qtrue; }
Similar to read, but raises
EOFError
at end of string instead of returning
nil
, as well as IO#sysread does.
static VALUE strio_sysread(int argc, VALUE *argv, VALUE self) { VALUE val = strio_read(argc, argv, self); if (NIL_P(val)) { rb_eof_error(); } return val; }
Appends the given string to the underlying buffer string of
strio. The stream must be opened for writing. If the
argument is not a string, it will be converted to a string using
to_s
. Returns the number of bytes written. See IO#write.
static VALUE strio_write(VALUE self, VALUE str) { struct StringIO *ptr = writable(StringIO(self)); long len, olen; rb_encoding *enc, *enc2; if (TYPE(str) != T_STRING) str = rb_obj_as_string(str); enc = rb_enc_get(ptr->string); enc2 = rb_enc_get(str); if (enc != enc2 && enc != rb_ascii8bit_encoding()) { str = rb_str_conv_enc(str, enc2, enc); } len = RSTRING_LEN(str); if (len == 0) return INT2FIX(0); check_modifiable(ptr); olen = RSTRING_LEN(ptr->string); if (ptr->flags & FMODE_APPEND) { ptr->pos = olen; } if (ptr->pos == olen) { rb_str_cat(ptr->string, RSTRING_PTR(str), len); } else { strio_extend(ptr, ptr->pos, len); memmove(RSTRING_PTR(ptr->string)+ptr->pos, RSTRING_PTR(str), len); OBJ_INFECT(ptr->string, str); } OBJ_INFECT(ptr->string, self); ptr->pos += len; return LONG2NUM(len); }
Returns the current offset (in bytes) of strio.
static VALUE strio_get_pos(VALUE self) { return LONG2NUM(StringIO(self)->pos); }
Truncates the buffer string to at most integer bytes. The strio must be opened for writing.
static VALUE strio_truncate(VALUE self, VALUE len) { VALUE string = writable(StringIO(self))->string; long l = NUM2LONG(len); long plen = RSTRING_LEN(string); if (l < 0) { error_inval("negative legnth"); } rb_str_resize(string, l); if (plen < l) { MEMZERO(RSTRING_PTR(string) + plen, char, l - plen); } return len; }
See IO#ungetbyte
static VALUE strio_ungetbyte(VALUE self, VALUE c) { struct StringIO *ptr = readable(StringIO(self)); char buf[1], *cp = buf; long pos = ptr->pos, cl = 1; VALUE str = ptr->string; if (NIL_P(c)) return Qnil; if (FIXNUM_P(c)) { buf[0] = (char)FIX2INT(c); } else { SafeStringValue(c); cp = RSTRING_PTR(c); cl = RSTRING_LEN(c); if (cl == 0) return Qnil; } rb_str_modify(str); if (cl > pos) { char *s; long rest = RSTRING_LEN(str) - pos; rb_str_resize(str, rest + cl); s = RSTRING_PTR(str); memmove(s + cl, s + pos, rest); pos = 0; } else { pos -= cl; } memcpy(RSTRING_PTR(str) + pos, cp, cl); ptr->pos = pos; RB_GC_GUARD(c); return Qnil; }
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(VALUE self, VALUE c) { struct StringIO *ptr = readable(StringIO(self)); long lpos, clen; char *p, *pend; rb_encoding *enc, *enc2; if (NIL_P(c)) return Qnil; if (FIXNUM_P(c)) { int cc = FIX2INT(c); char buf[16]; enc = rb_enc_get(ptr->string); rb_enc_mbcput(cc, buf, enc); c = rb_enc_str_new(buf, rb_enc_codelen(cc, enc), enc); } else { SafeStringValue(c); enc = rb_enc_get(ptr->string); enc2 = rb_enc_get(c); if (enc != enc2 && enc != rb_ascii8bit_encoding()) { c = rb_str_conv_enc(c, enc2, enc); } } /* get logical position */ lpos = 0; p = RSTRING_PTR(ptr->string); pend = p + ptr->pos; for (;;) { clen = rb_enc_mbclen(p, pend, enc); if (p+clen >= pend) break; p += clen; lpos++; } clen = p - RSTRING_PTR(ptr->string); rb_str_update(ptr->string, lpos, ptr->pos ? 1 : 0, c); ptr->pos = clen; return Qnil; }
Appends the given string to the underlying buffer string of
strio. The stream must be opened for writing. If the
argument is not a string, it will be converted to a string using
to_s
. Returns the number of bytes written. See IO#write.
static VALUE strio_write(VALUE self, VALUE str) { struct StringIO *ptr = writable(StringIO(self)); long len, olen; rb_encoding *enc, *enc2; if (TYPE(str) != T_STRING) str = rb_obj_as_string(str); enc = rb_enc_get(ptr->string); enc2 = rb_enc_get(str); if (enc != enc2 && enc != rb_ascii8bit_encoding()) { str = rb_str_conv_enc(str, enc2, enc); } len = RSTRING_LEN(str); if (len == 0) return INT2FIX(0); check_modifiable(ptr); olen = RSTRING_LEN(ptr->string); if (ptr->flags & FMODE_APPEND) { ptr->pos = olen; } if (ptr->pos == olen) { rb_str_cat(ptr->string, RSTRING_PTR(str), len); } else { strio_extend(ptr, ptr->pos, len); memmove(RSTRING_PTR(ptr->string)+ptr->pos, RSTRING_PTR(str), len); OBJ_INFECT(ptr->string, str); } OBJ_INFECT(ptr->string, self); ptr->pos += len; return LONG2NUM(len); }
Commenting is here to help enhance the documentation. For example, code samples, or clarification of the documentation.
If you have questions about Ruby or the documentation, please post to one of the Ruby mailing lists. You will get better, faster, help that way.
If you wish to post a correction of the docs, please do so, but also file bug report so that it can be corrected for the next release. Thank you.
If you want to help improve the Ruby documentation, please visit Documenting-ruby.org.