Class: StringIO

Inherits:
Object
  • Object
show all
Includes:
Enumerable, IO::generic_readable, IO::generic_writable
Defined in:
ext/stringio/stringio.c

Constant Summary collapse

VERSION =

The version string

rb_str_new_cstr(STRINGIO_VERSION)
MAX_LENGTH =

Maximum length that a StringIO instance can hold

LONG2NUM(LONG_MAX)

Class Method Summary collapse

Instance Method Summary collapse

Methods included from IO::generic_readable

#read_nonblock, #readbyte, #readchar, #readline, #readpartial, #sysread

Methods included from IO::generic_writable

#<<, #print, #printf, #puts, #syswrite, #write_nonblock

Constructor Details

#new(string = '', mode = 'r+') ⇒ Object

Returns a new StringIO instance formed from string and mode; the instance should be closed when no longer needed:

strio = StringIO.new
strio.string        # => ""
strio.closed_read?  # => false
strio.closed_write? # => false
strio.close

If string is frozen, the default mode is 'r':

strio = StringIO.new('foo'.freeze)
strio.string        # => "foo"
strio.closed_read?  # => false
strio.closed_write? # => true
strio.close

Argument mode must be a valid Access Mode, which may be a string or an integer constant:

StringIO.new('foo', 'w+')
StringIO.new('foo', File::RDONLY)

Related: StringIO.open (passes the StringIO object to the block; closes the object automatically on block exit).



255
256
257
258
259
260
261
262
263
264
265
# File 'ext/stringio/stringio.c', line 255

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

.new(*args) ⇒ Object

:nodoc:



414
415
416
417
418
419
420
421
422
423
424
# File 'ext/stringio/stringio.c', line 414

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

.open(string = '', mode = 'r+') ⇒ Object .open(string = '', mode = 'r+') {|strio| ... } ⇒ Object

Creates new StringIO instance by calling StringIO.new(string, mode).

With no block given, returns the new instance:

strio = StringIO.open # => #<StringIO>

With a block given, calls the block with the new instance and returns the block’s value; closes the instance on block exit:

StringIO.open('foo') {|strio| strio.string.upcase } # => "FOO"

Related: StringIO.new.

Overloads:

  • .open(string = '', mode = 'r+') {|strio| ... } ⇒ Object

    Yields:

    • (strio)

    Returns:

    • (Object)


405
406
407
408
409
410
411
# File 'ext/stringio/stringio.c', line 405

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 Method Details

#binmodeself

Sets the data mode in self to binary mode; see Data Mode.

Returns:

  • (self)


780
781
782
783
784
785
786
787
788
789
790
791
# File 'ext/stringio/stringio.c', line 780

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

#closenil

Closes self for both reading and writing; returns nil:

strio = StringIO.new
strio.closed? # => false
strio.close   # => nil
strio.closed? # => true
strio.read    # Raises IOError: not opened for reading
strio.write   # Raises IOError: not opened for writing

Related: StringIO#close_read, StringIO#close_write, StringIO.closed?.

Returns:

  • (nil)


563
564
565
566
567
568
569
# File 'ext/stringio/stringio.c', line 563

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

#close_readnil

Closes self for reading; closed-write setting remains unchanged; returns nil:

strio = StringIO.new
strio.closed_read?  # => false
strio.close_read    # => nil
strio.closed_read?  # => true
strio.closed_write? # => false
strio.read          # Raises IOError: not opened for reading

Related: StringIO#close, StringIO#close_write.

Returns:

  • (nil)


588
589
590
591
592
593
594
595
596
597
# File 'ext/stringio/stringio.c', line 588

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 self for writing; closed-read setting remains unchanged; returns nil:

strio = StringIO.new
strio.closed_write? # => false
strio.close_write   # => nil
strio.closed_write? # => true
strio.closed_read?  # => false
strio.write('foo')  # Raises IOError: not opened for writing

Related: StringIO#close, StringIO#close_read, StringIO#closed_write?.

Returns:

  • (nil)


614
615
616
617
618
619
620
621
622
623
# File 'ext/stringio/stringio.c', line 614

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

#closed?Boolean

Returns whether self is closed for both reading and writing:

strio = StringIO.new
strio.closed?     # => false  # Open for reading and writing.
strio.close_read
strio.closed?     # => false  # Still open for writing.
strio.close_write
strio.closed?     # => true   # Now closed for both.

Related: StringIO.closed_read?, StringIO.closed_write?.

Returns:

  • (Boolean)


640
641
642
643
644
645
646
# File 'ext/stringio/stringio.c', line 640

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

#closed_read?Boolean

Returns whether self is closed for reading:

strio = StringIO.new
strio.closed_read?   # => false
strio.close_read
strio.closed_read?   # => true

Related: StringIO#closed?, StringIO#closed_write?, StringIO#close_read.

Returns:

  • (Boolean)


661
662
663
664
665
666
667
# File 'ext/stringio/stringio.c', line 661

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

#closed_write?Boolean

Returns whether self is closed for writing:

strio = StringIO.new
strio.closed_write? # => false
strio.close_write
strio.closed_write? # => true

Related: StringIO#close_write, StringIO#closed?, StringIO#closed_read?.

Returns:

  • (Boolean)


682
683
684
685
686
687
688
# File 'ext/stringio/stringio.c', line 682

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

#each(*args) ⇒ Object

:markup: markdown

call-seq:

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

:include: stringio/each_line.md



1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
# File 'ext/stringio/stringio.c', line 1479

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

    RETURN_ENUMERATOR(self, argc, argv);

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

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

#each_byte {|byte| ... } ⇒ self

:include: stringio/each_byte.rdoc

Related: StringIO#each_char, StringIO#each_codepoint, StringIO#each_line.

Yields:

  • (byte)

Returns:

  • (self)


951
952
953
954
955
956
957
958
959
960
961
962
963
# File 'ext/stringio/stringio.c', line 951

static VALUE
strio_each_byte(VALUE self)
{
    struct StringIO *ptr;

    RETURN_ENUMERATOR(self, 0, 0);

    while ((ptr = strio_to_read(self)) != NULL) {
	char c = RSTRING_PTR(ptr->string)[ptr->pos++];
	rb_yield(CHR2FIX(c));
    }
    return self;
}

#each_char {|char| ... } ⇒ self

:include: stringio/each_char.rdoc

Related: StringIO#each_byte, StringIO#each_codepoint, StringIO#each_line.

Yields:

  • (char)

Returns:

  • (self)


1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
# File 'ext/stringio/stringio.c', line 1178

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 {|codepoint| ... } ⇒ self

:include: stringio/each_codepoint.rdoc

Related: StringIO#each_byte, StringIO#each_char, StringIO#each_line.

Yields:

  • (codepoint)

Returns:

  • (self)


1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
# File 'ext/stringio/stringio.c', line 1199

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);
    while ((ptr = strio_to_read(self)) != NULL) {
	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_line(*args) ⇒ Object

:markup: markdown

call-seq:

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

:include: stringio/each_line.md



1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
# File 'ext/stringio/stringio.c', line 1479

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

    RETURN_ENUMERATOR(self, argc, argv);

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

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

#eof?Boolean

Returns whether self is positioned at end-of-stream:

strio = StringIO.new('foo')
strio.pos  # => 0
strio.eof? # => false
strio.read # => "foo"
strio.pos  # => 3
strio.eof? # => true
strio.close_read
strio.eof? # Raises IOError: not opened for reading

Related: StringIO#pos.

Returns:

  • (Boolean)


715
716
717
718
719
720
# File 'ext/stringio/stringio.c', line 715

static VALUE
strio_eof(VALUE self)
{
    if (strio_to_read(self)) return Qfalse;
    return Qtrue;
}

#eof?Boolean

Returns whether self is positioned at end-of-stream:

strio = StringIO.new('foo')
strio.pos  # => 0
strio.eof? # => false
strio.read # => "foo"
strio.pos  # => 3
strio.eof? # => true
strio.close_read
strio.eof? # Raises IOError: not opened for reading

Related: StringIO#pos.

Returns:

  • (Boolean)


715
716
717
718
719
720
# File 'ext/stringio/stringio.c', line 715

static VALUE
strio_eof(VALUE self)
{
    if (strio_to_read(self)) return Qfalse;
    return Qtrue;
}

#external_encodingEncoding?

Returns an Encoding object that represents the encoding of the string; see Encodings:

strio = StringIO.new('foo')
strio.external_encoding # => #<Encoding:UTF-8>

Returns nil if self has no string and is in write mode:

strio = StringIO.new(nil, 'w+')
strio.external_encoding # => nil

Returns:

  • (Encoding, nil)


1903
1904
1905
1906
1907
1908
# File 'ext/stringio/stringio.c', line 1903

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

#fcntlObject

#filenonil

Returns:

  • (nil)

#flushObject

#fsync0

Returns:

  • (0)

#getbyteInteger?

:include: stringio/getbyte.rdoc

Returns:

  • (Integer, nil)


998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
# File 'ext/stringio/stringio.c', line 998

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

#getcnil

:include: stringio/getc.rdoc

Returns:

  • (nil)


972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
# File 'ext/stringio/stringio.c', line 972

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 (eos_p(ptr)) {
	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?

:include: stringio/gets.rdoc

Overloads:

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

    Returns:

    • (String, nil)
  • #gets(limit, chomp: false) ⇒ String?

    Returns:

    • (String, nil)
  • #gets(sep, limit, chomp: false) ⇒ String?

    Returns:

    • (String, nil)


1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
# File 'ext/stringio/stringio.c', line 1434

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

    if (prepare_getline_args(ptr, &arg, argc, argv)->limit == 0) {
	if (NIL_P(ptr->string)) return Qnil;
	return rb_enc_str_new(0, 0, get_enc(ptr));
    }

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

#initialize_copy(orig) ⇒ Object

:nodoc:



723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
# File 'ext/stringio/stringio.c', line 723

static VALUE
strio_copy(VALUE copy, VALUE orig)
{
    struct StringIO *ptr, *old_ptr;
    VALUE old_string = Qundef;

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

#internal_encodingnil

Returns nil; for compatibility with IO.

Returns:

  • (nil)


1917
1918
1919
1920
1921
# File 'ext/stringio/stringio.c', line 1917

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

#isattynil #tty?nil

Overloads:

  • #isattynil

    Returns:

    • (nil)
  • #tty?nil

    Returns:

    • (nil)

#sizeInteger

:include: stringio/size.rdoc

Returns:

  • (Integer)


1851
1852
1853
1854
1855
1856
1857
1858
1859
# File 'ext/stringio/stringio.c', line 1851

static VALUE
strio_size(VALUE self)
{
    VALUE string = StringIO(self)->string;
    if (NIL_P(string)) {
	return INT2FIX(0);
    }
    return ULONG2NUM(RSTRING_LEN(string));
}

#linenoObject

Returns the current line number in self; see Line Number.



752
753
754
755
756
# File 'ext/stringio/stringio.c', line 752

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

#lineno=(new_line_number) ⇒ Object

Sets the current line number in self to the given new_line_number; see Line Number.



765
766
767
768
769
770
# File 'ext/stringio/stringio.c', line 765

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

#pidnil

Returns:

  • (nil)

#posObject

Returns the current position (in bytes); see Position.



840
841
842
843
844
# File 'ext/stringio/stringio.c', line 840

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

#pos=(new_position) ⇒ Object

Sets the current position (in bytes); see Position.



853
854
855
856
857
858
859
860
861
862
863
# File 'ext/stringio/stringio.c', line 853

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

#pread(maxlen, offset) ⇒ String #pread(maxlen, offset, out_string) ⇒ String

See IO#pread.

Overloads:

  • #pread(maxlen, offset) ⇒ String

    Returns:

    • (String)
  • #pread(maxlen, offset, out_string) ⇒ String

    Returns:

    • (String)


1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
# File 'ext/stringio/stringio.c', line 1731

static VALUE
strio_pread(int argc, VALUE *argv, VALUE self)
{
    VALUE rb_len, rb_offset, rb_buf;
    rb_scan_args(argc, argv, "21", &rb_len, &rb_offset, &rb_buf);
    long len = NUM2LONG(rb_len);
    long offset = NUM2LONG(rb_offset);

    if (len < 0) {
	rb_raise(rb_eArgError, "negative string size (or size too big): %" PRIsVALUE, rb_len);
    }

    if (len == 0) {
	if (NIL_P(rb_buf)) {
	    return rb_str_new("", 0);
	}
	return rb_buf;
    }

    if (offset < 0) {
	rb_syserr_fail_str(EINVAL, rb_sprintf("pread: Invalid offset argument: %" PRIsVALUE, rb_offset));
    }

    struct StringIO *ptr = readable(self);

    if (outside_p(ptr, offset)) {
	rb_eof_error();
    }

    if (NIL_P(rb_buf)) {
	return strio_substr(ptr, offset, len, rb_ascii8bit_encoding());
    }

    long rest = RSTRING_LEN(ptr->string) - offset;
    if (len > rest) len = rest;
    rb_str_resize(rb_buf, len);
    rb_enc_associate(rb_buf, rb_ascii8bit_encoding());
    MEMCPY(RSTRING_PTR(rb_buf), RSTRING_PTR(ptr->string) + offset, char, len);
    return rb_buf;
}

#putc(obj) ⇒ Object

See IO#putc.

Returns:

  • (Object)


1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
# File 'ext/stringio/stringio.c', line 1622

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)) {
	if (NIL_P(ptr->string)) return ch;
	str = rb_str_substr(ch, 0, 1);
    }
    else {
	char c = NUM2CHR(ch);
	if (NIL_P(ptr->string)) return ch;
	str = rb_str_new(&c, 1);
    }
    strio_write(self, str);
    return ch;
}

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

See IO#read.

Returns:

  • (String, nil)


1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
# File 'ext/stringio/stringio.c', line 1656

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 (eos_p(ptr)) {
		if (!NIL_P(str)) rb_str_resize(str, 0);
		return len > 0 ? Qnil : rb_str_new(0, 0);
	    }
	    binary = 1;
	    break;
	}
	/* fall through */
      case 0:
	if (NIL_P(ptr->string)) return Qnil;
	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_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.

Overloads:

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

    Returns:

    • (Array)
  • #readlines(limit, chomp: false) ⇒ Array

    Returns:

    • (Array)
  • #readlines(sep, limit, chomp: false) ⇒ Array

    Returns:

    • (Array)


1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
# File 'ext/stringio/stringio.c', line 1506

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

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

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

#reopen(other, mode = 'r+') ⇒ self

Reinitializes the stream with the given other (string or StringIO) and mode; see IO.new:

StringIO.open('foo') do |strio|
  p strio.string
  strio.reopen('bar')
  p strio.string
  other_strio = StringIO.new('baz')
  strio.reopen(other_strio)
  p strio.string
  other_strio.close
end

Output:

"foo"
"bar"
"baz"

Returns:

  • (self)


823
824
825
826
827
828
829
830
831
# File 'ext/stringio/stringio.c', line 823

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

Sets the current position and line number to zero; see Position and Line Number.

Returns:

  • (0)


873
874
875
876
877
878
879
880
# File 'ext/stringio/stringio.c', line 873

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

#seek(offset, whence = SEEK_SET) ⇒ 0

Sets the position to the given integer offset (in bytes), with respect to a given constant whence; see IO#seek.

Returns:

  • (0)


890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
# File 'ext/stringio/stringio.c', line 890

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:
	if (NIL_P(ptr->string)) {
	    offset = 0;
	} else {
	    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]]) ⇒ Object

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.



1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
# File 'ext/stringio/stringio.c', line 1933

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_find_encoding(ext_enc);
	if (!enc) {
	    rb_io_enc_t convconfig;
	    int oflags;
	    rb_io_mode_t fmode;
	    VALUE vmode = rb_str_append(rb_str_new_cstr("r:"), ext_enc);
	    rb_io_extract_modeenc(&vmode, 0, Qnil, &oflags, &fmode, &convconfig);
	    enc = convconfig.enc2;
	}
    }
    ptr->enc = enc;
    if (!NIL_P(ptr->string) && WRITABLE(self) && !str_chilled_p(ptr->string)) {
	rb_enc_associate(ptr->string, enc);
    }

    return self;
}

#set_encoding_by_bomnil

Sets the encoding according to the BOM (Byte Order Mark) in the string.

Returns self if the BOM is found, otherwise +nil.

Returns:

  • (nil)


1973
1974
1975
1976
1977
1978
1979
1980
# File 'ext/stringio/stringio.c', line 1973

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

#sizeInteger

:include: stringio/size.rdoc

Returns:

  • (Integer)


1851
1852
1853
1854
1855
1856
1857
1858
1859
# File 'ext/stringio/stringio.c', line 1851

static VALUE
strio_size(VALUE self)
{
    VALUE string = StringIO(self)->string;
    if (NIL_P(string)) {
	return INT2FIX(0);
    }
    return ULONG2NUM(RSTRING_LEN(string));
}

#stringString

Returns underlying string:

StringIO.open('foo') do |strio|
  p strio.string
  strio.string = 'bar'
  p strio.string
end

Output:

"foo"
"bar"

Related: StringIO#string= (assigns the underlying string).

Returns:

  • (String)


507
508
509
510
511
# File 'ext/stringio/stringio.c', line 507

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

#string=(other_string) ⇒ Object

Replaces the stored string with other_string, and sets the position to zero; returns other_string:

StringIO.open('foo') do |strio|
  p strio.string
  strio.string = 'bar'
  p strio.string
end

Output:

"foo"
"bar"

Related: StringIO#string (returns the stored string).



533
534
535
536
537
538
539
540
541
542
543
544
545
546
# File 'ext/stringio/stringio.c', line 533

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 = readonly_string_p(string) ? FMODE_READABLE : FMODE_READWRITE;
    ptr->pos = 0;
    ptr->lineno = 0;
    RB_OBJ_WRITE(self, &ptr->string, string);
    return string;
}

#synctrue

Returns true; implemented only for compatibility with other stream classes.

Returns:

  • (true)


932
933
934
935
936
937
# File 'ext/stringio/stringio.c', line 932

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

#sync=(boolean) ⇒ Boolean

Returns:

  • (Boolean)

#tellObject

#truncate(integer) ⇒ 0

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

Returns:

  • (0)


1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
# File 'ext/stringio/stringio.c', line 1868

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

#tty?Boolean

Returns:

  • (Boolean)

#ungetbyte(byte) ⇒ nil

Pushes back (“unshifts”) an 8-bit byte onto the stream; see Byte IO.

Returns:

  • (nil)


1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
# File 'ext/stringio/stringio.c', line 1088

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

    check_modifiable(ptr);
    if (NIL_P(ptr->string)) return Qnil;
    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 {
	StringValue(c);
	strio_unget_string(ptr, c);
    }
    return Qnil;
}

#ungetc(character) ⇒ nil

Pushes back (“unshifts”) a character or integer onto the stream; see Character IO.

Returns:

  • (nil)


1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
# File 'ext/stringio/stringio.c', line 1046

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

    check_modifiable(ptr);
    if (NIL_P(ptr->string)) return Qnil;
    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); /* to raise an exception */
	    UNREACHABLE;
	}
	rb_enc_mbcput(cc, buf, enc);
	return strio_unget_bytes(ptr, buf, len);
    }
    else {
	StringValue(c);
	if (RSTRING_LEN(c) == 0) return Qnil;
	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_string(ptr, 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.

Overloads:

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

    Returns:

    • (Integer)
  • #syswrite(string) ⇒ Integer

    Returns:

    • (Integer)


1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
# File 'ext/stringio/stringio.c', line 1534

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