123456789_123456789_123456789_123456789_123456789_

Class: StringIO

Relationships & Source Files
Super Chains via Extension / Inclusion / Inheritance
Class Chain:
self, ::Data
Instance Chain:
Inherits: Data
  • Object
Defined in: ext/stringio/stringio.c

Overview

Pseudo I/O on String object, with interface corresponding to ::IO.

Commonly used to simulate $stdio or $stderr

Examples

require 'stringio'

# Writing stream emulation
io = StringIO.new
io.puts "Hello World"
io.string #=> "Hello World\n"

# Reading stream emulation
io = StringIO.new "first\nsecond\nlast\n"
io.getc #=> "f"
io.gets #=> "irst\n"
io.read #=> "second\nlast\n"

Constant Summary

Class Method Summary

Instance Attribute Summary

Instance Method Summary

::IO::generic_readable - Included

#read_nonblock

Similar to #read, but raises EOFError at end of string unless the exception: false option is passed in.

#readbyte

See IO#readbyte.

#readchar

See IO#readchar.

#readline

See IO#readline.

#readpartial
#sysread

Similar to #read, but raises EOFError at end of string instead of returning nil, as well as IO#sysread does.

::IO::generic_writable - Included

Constructor Details

.new(*args)

This method is for internal use only.
[ GitHub ]

  
# File 'ext/stringio/stringio.c', line 404

static VALUE
strio_s_new(int argc, VALUE *argv, VALUE klass)
{
    if (rb_block_given_p()) {
	VALUE cname = rb_obj_as_string(klass);

	rb_warn("%"PRIsVALUE"::new() does not take block; use %"PRIsVALUE"::open() instead",
		cname, cname);
    }
    return rb_class_new_instance_kw(argc, argv, klass, RB_PASS_CALLED_KEYWORDS);
}

#new(string=""[, mode])

Creates new StringIO instance from with string and mode.

[ GitHub ]

  
# File 'ext/stringio/stringio.c', line 258

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);
    return strio_init(argc, argv, ptr, self);
}

Class Method Details

.open(string=""[, mode]) {|strio| ... }

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.

[ GitHub ]

  
# File 'ext/stringio/stringio.c', line 395

static VALUE
strio_s_open(int argc, VALUE *argv, VALUE klass)
{
    VALUE obj = rb_class_new_instance_kw(argc, argv, klass, RB_PASS_CALLED_KEYWORDS);
    if (!rb_block_given_p()) return obj;
    return rb_ensure(rb_yield, obj, strio_finalize, obj);
}

Instance Attribute Details

#closed?Boolean (readonly)

Returns true if the stream is completely closed, false otherwise.

[ GitHub ]

  
# File 'ext/stringio/stringio.c', line 566

static VALUE
strio_closed(VALUE self)
{
    StringIO(self);
    if (!CLOSED(self)) return Qfalse;
    return Qtrue;
}

#closed_read?Boolean (readonly)

Returns true if the stream is not readable, false otherwise.

[ GitHub ]

  
# File 'ext/stringio/stringio.c', line 580

static VALUE
strio_closed_read(VALUE self)
{
    StringIO(self);
    if (READABLE(self)) return Qfalse;
    return Qtrue;
}

#closed_write?Boolean (readonly)

Returns true if the stream is not writable, false otherwise.

[ GitHub ]

  
# File 'ext/stringio/stringio.c', line 594

static VALUE
strio_closed_write(VALUE self)
{
    StringIO(self);
    if (WRITABLE(self)) return Qfalse;
    return Qtrue;
}

#eofBoolean (readonly) #eof?Boolean
Also known as: #eof?

Returns true if the stream is at the end of the data (underlying string). The stream must be opened for reading or an IOError will be raised.

[ GitHub ]

  
# File 'ext/stringio/stringio.c', line 610

static VALUE
strio_eof(VALUE self)
{
    struct StringIO *ptr = readable(self);
    if (ptr->pos < RSTRING_LEN(ptr->string)) return Qfalse;
    return Qtrue;
}

#eofBoolean (readonly) #eof?Boolean

Alias for #eof.

#linenoInteger (rw)

Returns the current line number. The stream 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.

[ GitHub ]

  
# File 'ext/stringio/stringio.c', line 647

static VALUE
strio_get_lineno(VALUE self)
{
    return LONG2NUM(StringIO(self)->lineno);
}

#lineno=(integer) ⇒ Integer (rw)

Manually sets the current line number to the given value. $. is updated only on the next read.

[ GitHub ]

  
# File 'ext/stringio/stringio.c', line 660

static VALUE
strio_set_lineno(VALUE self, VALUE lineno)
{
    StringIO(self)->lineno = NUM2LONG(lineno);
    return lineno;
}

#posInteger (rw) #tellInteger

Returns the current offset (in bytes).

[ GitHub ]

  
# File 'ext/stringio/stringio.c', line 718

static VALUE
strio_get_pos(VALUE self)
{
    return LONG2NUM(StringIO(self)->pos);
}

#pos=(integer) ⇒ Integer (rw)

Seeks to the given position (in bytes).

[ GitHub ]

  
# File 'ext/stringio/stringio.c', line 730

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

#stringString (rw)

Returns underlying String object, the subject of ::IO.

[ GitHub ]

  
# File 'ext/stringio/stringio.c', line 483

static VALUE
strio_get_string(VALUE self)
{
    return StringIO(self)->string;
}

#string=(string) ⇒ String (rw)

Changes underlying String object, the subject of ::IO.

[ GitHub ]

  
# File 'ext/stringio/stringio.c', line 495

static VALUE
strio_set_string(VALUE self, VALUE string)
{
    struct StringIO *ptr = StringIO(self);

    rb_io_taint_check(self);
    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;
}

#tty?Boolean (readonly)

[ GitHub ]

Instance Method Details

#binmodeStringIO

Puts stream into binary mode. See IO#binmode.

[ GitHub ]

  
# File 'ext/stringio/stringio.c', line 674

static VALUE
strio_binmode(VALUE self)
{
    struct StringIO *ptr = StringIO(self);
    rb_encoding *enc = rb_ascii8bit_encoding();

    ptr->enc = enc;
    if (WRITABLE(self)) {
	rb_enc_associate(ptr->string, enc);
    }
    return self;
}

#bytes

This is a deprecated alias for #each_byte.

[ GitHub ]

  
# File 'ext/stringio/stringio.c', line 838

static VALUE
strio_bytes(VALUE self)
{
    rb_warn("StringIO#bytes is deprecated; use #each_byte instead");
    if (!rb_block_given_p())
	return rb_enumeratorize(self, ID2SYM(rb_intern("each_byte")), 0, 0);
    return strio_each_byte(self);
}

#chars

This is a deprecated alias for #each_char.

[ GitHub ]

  
# File 'ext/stringio/stringio.c', line 1063

static VALUE
strio_chars(VALUE self)
{
    rb_warn("StringIO#chars is deprecated; use #each_char instead");
    if (!rb_block_given_p())
	return rb_enumeratorize(self, ID2SYM(rb_intern("each_char")), 0, 0);
    return strio_each_char(self);
}

#closenil

Closes a StringIO. The stream is unavailable for any further data operations; an IOError is raised if such an attempt is made.

[ GitHub ]

  
# File 'ext/stringio/stringio.c', line 516

static VALUE
strio_close(VALUE self)
{
    StringIO(self);
    RBASIC(self)->flags &= ~STRIO_READWRITE;
    return Qnil;
}

#close_readnil

Closes the read end of a StringIO. Will raise an IOError if the receiver is not readable.

[ GitHub ]

  
# File 'ext/stringio/stringio.c', line 531

static VALUE
strio_close_read(VALUE self)
{
    struct StringIO *ptr = StringIO(self);
    if (!(ptr->flags & FMODE_READABLE)) {
	rb_raise(rb_eIOError, "closing non-duplex IO for reading");
    }
    RBASIC(self)->flags &= ~STRIO_READABLE;
    return Qnil;
}

#close_writenil

Closes the write end of a StringIO. Will raise an IOError if the receiver is not writeable.

[ GitHub ]

  
# File 'ext/stringio/stringio.c', line 549

static VALUE
strio_close_write(VALUE self)
{
    struct StringIO *ptr = StringIO(self);
    if (!(ptr->flags & FMODE_WRITABLE)) {
	rb_raise(rb_eIOError, "closing non-duplex IO for writing");
    }
    RBASIC(self)->flags &= ~STRIO_WRITABLE;
    return Qnil;
}

#codepoints

This is a deprecated alias for #each_codepoint.

[ GitHub ]

  
# File 'ext/stringio/stringio.c', line 1107

static VALUE
strio_codepoints(VALUE self)
{
    rb_warn("StringIO#codepoints is deprecated; use #each_codepoint instead");
    if (!rb_block_given_p())
	return rb_enumeratorize(self, ID2SYM(rb_intern("each_codepoint")), 0, 0);
    return strio_each_codepoint(self);
}

#each(sep = $/, chomp: false) {|line| ... } ⇒ strio #each(limit, chomp: false) {|line| ... } ⇒ strio #each(sep, limit, chomp: false) {|line| ... } ⇒ strio #each(...) ⇒ Enumerator
Also known as: #each_line

strio.each_line(sep=$/, chomp: false) {|line| block } -> strio

strio.each_line(limit, chomp: false) {|line| block }      -> strio
strio.each_line(sep, limit, chomp: false) {|line| block } -> strio
strio.each_line(...)                                      -> anEnumerator

See IO#each.

[ GitHub ]

  
# File 'ext/stringio/stringio.c', line 1347

static VALUE
strio_each(int argc, VALUE *argv, VALUE self)
{
    VALUE line;
    struct getline_arg arg;

    StringIO(self);
    RETURN_ENUMERATOR(self, argc, argv);

    if (prepare_getline_args(&arg, argc, argv)->limit == 0) {
	rb_raise(rb_eArgError, "invalid limit: 0 for each_line");
    }

    while (!NIL_P(line = strio_getline(&arg, readable(self)))) {
	rb_yield(line);
    }
    return self;
}

#each_byte {|byte| ... } ⇒ strio #each_byteEnumerator

See IO#each_byte.

[ GitHub ]

  
# File 'ext/stringio/stringio.c', line 821

static VALUE
strio_each_byte(VALUE self)
{
    struct StringIO *ptr = readable(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;
}

#each_char {|char| ... } ⇒ strio #each_charEnumerator

See IO#each_char.

[ GitHub ]

  
# File 'ext/stringio/stringio.c', line 1047

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

#each_codepoint {|c| ... } ⇒ strio #each_codepointEnumerator

See IO#each_codepoint.

[ GitHub ]

  
# File 'ext/stringio/stringio.c', line 1079

static VALUE
strio_each_codepoint(VALUE self)
{
    struct StringIO *ptr;
    rb_encoding *enc;
    unsigned int c;
    int n;

    RETURN_ENUMERATOR(self, 0, 0);

    ptr = readable(self);
    enc = get_enc(ptr);
    for (;;) {
	if (ptr->pos >= RSTRING_LEN(ptr->string)) {
	    return self;
	}

	c = rb_enc_codepoint_len(RSTRING_PTR(ptr->string)+ptr->pos,
				 RSTRING_END(ptr->string), &n, enc);
	ptr->pos += n;
	rb_yield(UINT2NUM(c));
    }
    return self;
}

#each(sep = $/, chomp: false) {|line| ... } ⇒ strio #each(limit, chomp: false) {|line| ... } ⇒ strio #each(sep, limit, chomp: false) {|line| ... } ⇒ strio #each(...) ⇒ Enumerator

Alias for #each.

#external_encodingEncoding

Returns the Encoding object that represents the encoding of the file. If the stream is write mode and no encoding is specified, returns nil.

[ GitHub ]

  
# File 'ext/stringio/stringio.c', line 1714

static VALUE
strio_external_encoding(VALUE self)
{
    struct StringIO *ptr = StringIO(self);
    return rb_enc_from_encoding(get_enc(ptr));
}

#fcntl

[ GitHub ]

#fileno

[ GitHub ]

#flush

[ GitHub ]

#fsync

[ GitHub ]

#getbyteFixnum?

See IO#getbyte.

[ GitHub ]

  
# File 'ext/stringio/stringio.c', line 878

static VALUE
strio_getbyte(VALUE self)
{
    struct StringIO *ptr = readable(self);
    int c;
    if (ptr->pos >= RSTRING_LEN(ptr->string)) {
	return Qnil;
    }
    c = RSTRING_PTR(ptr->string)[ptr->pos++];
    return CHR2FIX(c);
}

#getcString?

See IO#getc.

[ GitHub ]

  
# File 'ext/stringio/stringio.c', line 853

static VALUE
strio_getc(VALUE self)
{
    struct StringIO *ptr = readable(self);
    rb_encoding *enc = get_enc(ptr);
    VALUE str = ptr->string;
    long pos = ptr->pos;
    int len;
    char *p;

    if (pos >= RSTRING_LEN(str)) {
	return Qnil;
    }
    p = RSTRING_PTR(str)+pos;
    len = rb_enc_mbclen(p, RSTRING_END(str), enc);
    ptr->pos += len;
    return enc_subseq(str, pos, len, enc);
}

#gets(sep = $/, chomp: false) ⇒ String? #gets(limit, chomp: false) ⇒ String? #gets(sep, limit, chomp: false) ⇒ String?

See IO#gets.

[ GitHub ]

  
# File 'ext/stringio/stringio.c', line 1301

static VALUE
strio_gets(int argc, VALUE *argv, VALUE self)
{
    struct getline_arg arg;
    VALUE str;

    if (prepare_getline_args(&arg, argc, argv)->limit == 0) {
	struct StringIO *ptr = readable(self);
	return rb_enc_str_new(0, 0, get_enc(ptr));
    }

    str = strio_getline(&arg, readable(self));
    rb_lastline_set(str);
    return str;
}

#initialize_copy(orig)

This method is for internal use only.
[ GitHub ]

  
# File 'ext/stringio/stringio.c', line 619

static VALUE
strio_copy(VALUE copy, VALUE orig)
{
    struct StringIO *ptr;

    orig = rb_convert_type(orig, T_DATA, "StringIO", "to_strio");
    if (copy == orig) return copy;
    ptr = StringIO(orig);
    if (check_strio(copy)) {
	strio_free(DATA_PTR(copy));
    }
    DATA_PTR(copy) = ptr;
    RBASIC(copy)->flags &= ~STRIO_READWRITE;
    RBASIC(copy)->flags |= RBASIC(orig)->flags & STRIO_READWRITE;
    ++ptr->count;
    return copy;
}

#internal_encodingEncoding

Returns the Encoding of the internal string if conversion is specified. Otherwise returns nil.

[ GitHub ]

  
# File 'ext/stringio/stringio.c', line 1729

static VALUE
strio_internal_encoding(VALUE self)
{
    return Qnil;
}

#isatty

[ GitHub ]

#lengthInteger #sizeInteger
Also known as: #size

Returns the size of the buffer string.

[ GitHub ]

  
# File 'ext/stringio/stringio.c', line 1672

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));
}

#lines(*args)

This is a deprecated alias for #each_line.

[ GitHub ]

  
# File 'ext/stringio/stringio.c', line 1369

static VALUE
strio_lines(int argc, VALUE *argv, VALUE self)
{
    rb_warn("StringIO#lines is deprecated; use #each_line instead");
    if (!rb_block_given_p())
	return rb_enumeratorize(self, ID2SYM(rb_intern("each_line")), argc, argv);
    return strio_each(argc, argv, self);
}

#pid

[ GitHub ]

#putc(obj) ⇒ Object

See IO#putc.

[ GitHub ]

  
# File 'ext/stringio/stringio.c', line 1500

static VALUE
strio_putc(VALUE self, VALUE ch)
{
    struct StringIO *ptr = writable(self);
    VALUE str;

    check_modifiable(ptr);
    if (RB_TYPE_P(ch, T_STRING)) {
	str = rb_str_substr(ch, 0, 1);
    }
    else {
	char c = NUM2CHR(ch);
	str = rb_str_new(&c, 1);
    }
    strio_write(self, str);
    return ch;
}

#read([length [, outbuf]]) ⇒ String, ...

See IO#read.

[ GitHub ]

  
# File 'ext/stringio/stringio.c', line 1532

static VALUE
strio_read(int argc, VALUE *argv, VALUE self)
{
    struct StringIO *ptr = readable(self);
    VALUE str = Qnil;
    long len;
    int binary = 0;

    switch (argc) {
      case 2:
	str = argv[1];
	if (!NIL_P(str)) {
	    StringValue(str);
	    rb_str_modify(str);
	}
	/* fall through */
      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;
	    }
	    binary = 1;
	    break;
	}
	/* fall through */
      case 0:
	len = RSTRING_LEN(ptr->string);
	if (len <= ptr->pos) {
	    rb_encoding *enc = get_enc(ptr);
	    if (NIL_P(str)) {
		str = rb_str_new(0, 0);
	    }
	    else {
		rb_str_resize(str, 0);
	    }
	    rb_enc_associate(str, enc);
	    return str;
	}
	else {
	    len -= ptr->pos;
	}
	break;
      default:
        rb_error_arity(argc, 0, 2);
    }
    if (NIL_P(str)) {
	rb_encoding *enc = binary ? rb_ascii8bit_encoding() : get_enc(ptr);
	str = strio_substr(ptr, ptr->pos, len, enc);
    }
    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 (binary)
	    rb_enc_associate(str, rb_ascii8bit_encoding());
	else
	    rb_enc_copy(str, ptr->string);
    }
    ptr->pos += RSTRING_LEN(str);
    return str;
}

#readlines(sep = $/, chomp: false) ⇒ Array #readlines(limit, chomp: false) ⇒ Array #readlines(sep, limit, chomp: false) ⇒ Array

See IO#readlines.

[ GitHub ]

  
# File 'ext/stringio/stringio.c', line 1386

static VALUE
strio_readlines(int argc, VALUE *argv, VALUE self)
{
    VALUE ary, line;
    struct getline_arg arg;

    StringIO(self);
    ary = rb_ary_new();
    if (prepare_getline_args(&arg, argc, argv)->limit == 0) {
	rb_raise(rb_eArgError, "invalid limit: 0 for readlines");
    }

    while (!NIL_P(line = strio_getline(&arg, readable(self)))) {
	rb_ary_push(ary, line);
    }
    return ary;
}

#reopen(other_StrIO) ⇒ strio #reopen(string, mode) ⇒ strio

Reinitializes the stream with the given other_StrIO or string and mode (see StringIO#new).

[ GitHub ]

  
# File 'ext/stringio/stringio.c', line 701

static VALUE
strio_reopen(int argc, VALUE *argv, VALUE self)
{
    rb_io_taint_check(self);
    if (argc == 1 && !RB_TYPE_P(*argv, T_STRING)) {
	return strio_copy(self, *argv);
    }
    return strio_init(argc, argv, StringIO(self), self);
}

#rewind0

Positions the stream to the beginning of input, resetting #lineno to zero.

[ GitHub ]

  
# File 'ext/stringio/stringio.c', line 749

static VALUE
strio_rewind(VALUE self)
{
    struct StringIO *ptr = StringIO(self);
    ptr->pos = 0;
    ptr->lineno = 0;
    return INT2FIX(0);
}

#seek(amount, whence = SEEK_SET) ⇒ 0

Seeks to a given offset amount in the stream according to the value of whence (see IO#seek).

[ GitHub ]

  
# File 'ext/stringio/stringio.c', line 765

static VALUE
strio_seek(int argc, VALUE *argv, VALUE self)
{
    VALUE whence;
    struct StringIO *ptr = StringIO(self);
    long amount, offset;

    rb_scan_args(argc, argv, "11", NULL, &whence);
    amount = NUM2LONG(argv[0]);
    if (CLOSED(self)) {
	rb_raise(rb_eIOError, "closed stream");
    }
    switch (NIL_P(whence) ? 0 : NUM2LONG(whence)) {
      case 0:
	offset = 0;
	break;
      case 1:
	offset = ptr->pos;
	break;
      case 2:
	offset = RSTRING_LEN(ptr->string);
	break;
      default:
	error_inval("invalid whence");
    }
    if (amount > LONG_MAX - offset || amount + offset < 0) {
	error_inval(0);
    }
    ptr->pos = amount + offset;
    return INT2FIX(0);
}

#set_encoding(ext_enc, [int_enc[, opt]]) ⇒ strio

Specify the encoding of the StringIO as ext_enc. Use the default external encoding if ext_enc is nil. 2nd argument int_enc and optional hash opt argument are ignored; they are for API compatibility to ::IO.

[ GitHub ]

  
# File 'ext/stringio/stringio.c', line 1745

static VALUE
strio_set_encoding(int argc, VALUE *argv, VALUE self)
{
    rb_encoding* enc;
    struct StringIO *ptr = StringIO(self);
    VALUE ext_enc, int_enc, opt;

    argc = rb_scan_args(argc, argv, "11:", &ext_enc, &int_enc, &opt);

    if (NIL_P(ext_enc)) {
	enc = rb_default_external_encoding();
    }
    else {
	enc = rb_to_encoding(ext_enc);
    }
    ptr->enc = enc;
    if (WRITABLE(self)) {
	rb_enc_associate(ptr->string, enc);
    }

    return self;
}

#set_encoding_by_bom

[ GitHub ]

  
# File 'ext/stringio/stringio.c', line 1768

static VALUE
strio_set_encoding_by_bom(VALUE self)
{
    struct StringIO *ptr = StringIO(self);

    if (!set_encoding_by_bom(ptr)) return Qnil;
    return rb_enc_from_encoding(ptr->enc);
}

#lengthInteger #sizeInteger

Alias for #length.

#synctrue

Returns true always.

[ GitHub ]

  
# File 'ext/stringio/stringio.c', line 803

static VALUE
strio_get_sync(VALUE self)
{
    StringIO(self);
    return Qtrue;
}

#sync=

[ GitHub ]

#tell

[ GitHub ]

#truncate(integer) ⇒ 0

Truncates the buffer string to at most integer bytes. The stream must be opened for writing.

[ GitHub ]

  
# File 'ext/stringio/stringio.c', line 1689

static VALUE
strio_truncate(VALUE self, VALUE len)
{
    VALUE string = writable(self)->string;
    long l = NUM2LONG(len);
    long plen = RSTRING_LEN(string);
    if (l < 0) {
	error_inval("negative length");
    }
    rb_str_resize(string, l);
    if (plen < l) {
	MEMZERO(RSTRING_PTR(string) + plen, char, l - plen);
    }
    return len;
}

#ungetbyte(fixnum) ⇒ nil

See IO#ungetbyte

[ GitHub ]

  
# File 'ext/stringio/stringio.c', line 956

static VALUE
strio_ungetbyte(VALUE self, VALUE c)
{
    struct StringIO *ptr = readable(self);

    check_modifiable(ptr);
    if (NIL_P(c)) return Qnil;
    if (RB_INTEGER_TYPE_P(c)) {
        /* rb_int_and() not visible from exts */
        VALUE v = rb_funcall(c, '&', 1, INT2FIX(0xff));
        const char cc = NUM2INT(v) & 0xFF;
        strio_unget_bytes(ptr, &cc, 1);
    }
    else {
	long cl;
	SafeStringValue(c);
	cl = RSTRING_LEN(c);
	if (cl > 0) {
	    strio_unget_bytes(ptr, RSTRING_PTR(c), cl);
	    RB_GC_GUARD(c);
	}
    }
    return Qnil;
}

#ungetc(string) ⇒ nil

Pushes back one character (passed as a parameter) such that a subsequent buffered read will return it. There is no limitation for multiple pushbacks including pushing back behind the beginning of the buffer string.

[ GitHub ]

  
# File 'ext/stringio/stringio.c', line 919

static VALUE
strio_ungetc(VALUE self, VALUE c)
{
    struct StringIO *ptr = readable(self);
    rb_encoding *enc, *enc2;

    check_modifiable(ptr);
    if (NIL_P(c)) return Qnil;
    if (RB_INTEGER_TYPE_P(c)) {
	int len, cc = NUM2INT(c);
	char buf[16];

	enc = rb_enc_get(ptr->string);
	len = rb_enc_codelen(cc, enc);
	if (len <= 0) rb_enc_uint_chr(cc, enc);
	rb_enc_mbcput(cc, buf, enc);
	return strio_unget_bytes(ptr, buf, len);
    }
    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);
	}
	strio_unget_bytes(ptr, RSTRING_PTR(c), RSTRING_LEN(c));
	RB_GC_GUARD(c);
	return Qnil;
    }
}

#write(string, ...) ⇒ Integer #syswrite(string) ⇒ Integer

Appends the given string to the underlying buffer string. 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.

[ GitHub ]

  
# File 'ext/stringio/stringio.c', line 1414

static VALUE
strio_write_m(int argc, VALUE *argv, VALUE self)
{
    long len = 0;
    while (argc-- > 0) {
	/* StringIO can't exceed long limit */
	len += strio_write(self, *argv++);
    }
    return LONG2NUM(len);
}