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

With a block given calls the block with each remaining line (see “Position” below) in the stream; returns ‘self`.

Leaves stream position as end-of-stream.

**No Arguments**

With no arguments given, reads lines using the default record separator global variable ‘$/`, whose initial value is `“n”`.

“‘ strio = StringIO.new(TEXT) strio.each_line {|line| p line } strio.eof? # => true “`

Output:

“‘ “First linen” “Second linen” “n” “Fourth linen” “Fifth linen” “`

**Argument ‘sep`**

With only string argument ‘sep` given, reads lines using that string as the record separator:

“‘ strio = StringIO.new(TEXT) strio.each_line(’ ‘) {|line| p line } “`

Output:

“‘ “First ” “linenSecond ” “linennFourth ” “linenFifth ” “linen” “`

**Argument ‘limit`**

With only integer argument ‘limit` given, reads lines using the default record separator global variable `$/`, whose initial value is `“n”`; also limits the size (in characters) of each line to the given limit:

“‘ strio = StringIO.new(TEXT) strio.each_line(10) {|line| p line } “`

Output:

“‘ “First line” “n” “Second lin” “en” “n” “Fourth lin” “en” “Fifth line” “n” “` **Arguments `sep` and `limit`**

With arguments ‘sep` and `limit` both given, honors both:

“‘ strio = StringIO.new(TEXT) strio.each_line(’ ‘, 10) {|line| p line } “`

Output:

“‘ “First ” “linenSecon” “d ” “linennFour” “th ” “linenFifth” “ ” “linen” “`

Position

As stated above, method ‘each` remaining line in the stream.

In the examples above each ‘strio` object starts with its position at beginning-of-stream; but in other cases the position may be anywhere (see StringIO#pos):

“‘ strio = StringIO.new(TEXT) strio.pos = 30 # Set stream position to character 30. strio.each_line {|line| p line } “`

Output:

“‘ “ linen” “Fifth linen” “`

**Special Record Separators**

Like some methds in class ‘IO`, StringIO.each honors two special record separators; see Special Line Separators.

“‘ strio = StringIO.new(TEXT) strio.each_line(”) {|line| p line } # Read as paragraphs (separated by blank lines). “`

Output:

“‘ “First linenSecond linenn” “Fourth linenFifth linen” “`

“‘ strio = StringIO.new(TEXT) strio.each_line(nil) {|line| p line } # “Slurp”; read it all. “`

Output:

“‘ “First linenSecond linennFourth linenFifth linen” “`

**Keyword Argument ‘chomp`**

With keyword argument ‘chomp` given as `true` (the default is `false`), removes trailing newline (if any) from each line:

“‘ strio = StringIO.new(TEXT) strio.each_line(chomp: true) {|line| p line } “`

Output:

“‘ “First line” “Second line” “” “Fourth line” “Fifth line” “`

With no block given, returns a new Enumerator.

Related: StringIO.each_byte, StringIO.each_char, StringIO.each_codepoint.



1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
# File 'ext/stringio/stringio.c', line 1641

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

With a block given calls the block with each remaining line (see “Position” below) in the stream; returns ‘self`.

Leaves stream position as end-of-stream.

**No Arguments**

With no arguments given, reads lines using the default record separator global variable ‘$/`, whose initial value is `“n”`.

“‘ strio = StringIO.new(TEXT) strio.each_line {|line| p line } strio.eof? # => true “`

Output:

“‘ “First linen” “Second linen” “n” “Fourth linen” “Fifth linen” “`

**Argument ‘sep`**

With only string argument ‘sep` given, reads lines using that string as the record separator:

“‘ strio = StringIO.new(TEXT) strio.each_line(’ ‘) {|line| p line } “`

Output:

“‘ “First ” “linenSecond ” “linennFourth ” “linenFifth ” “linen” “`

**Argument ‘limit`**

With only integer argument ‘limit` given, reads lines using the default record separator global variable `$/`, whose initial value is `“n”`; also limits the size (in characters) of each line to the given limit:

“‘ strio = StringIO.new(TEXT) strio.each_line(10) {|line| p line } “`

Output:

“‘ “First line” “n” “Second lin” “en” “n” “Fourth lin” “en” “Fifth line” “n” “` **Arguments `sep` and `limit`**

With arguments ‘sep` and `limit` both given, honors both:

“‘ strio = StringIO.new(TEXT) strio.each_line(’ ‘, 10) {|line| p line } “`

Output:

“‘ “First ” “linenSecon” “d ” “linennFour” “th ” “linenFifth” “ ” “linen” “`

Position

As stated above, method ‘each` remaining line in the stream.

In the examples above each ‘strio` object starts with its position at beginning-of-stream; but in other cases the position may be anywhere (see StringIO#pos):

“‘ strio = StringIO.new(TEXT) strio.pos = 30 # Set stream position to character 30. strio.each_line {|line| p line } “`

Output:

“‘ “ linen” “Fifth linen” “`

**Special Record Separators**

Like some methds in class ‘IO`, StringIO.each honors two special record separators; see Special Line Separators.

“‘ strio = StringIO.new(TEXT) strio.each_line(”) {|line| p line } # Read as paragraphs (separated by blank lines). “`

Output:

“‘ “First linenSecond linenn” “Fourth linenFifth linen” “`

“‘ strio = StringIO.new(TEXT) strio.each_line(nil) {|line| p line } # “Slurp”; read it all. “`

Output:

“‘ “First linenSecond linennFourth linenFifth linen” “`

**Keyword Argument ‘chomp`**

With keyword argument ‘chomp` given as `true` (the default is `false`), removes trailing newline (if any) from each line:

“‘ strio = StringIO.new(TEXT) strio.each_line(chomp: true) {|line| p line } “`

Output:

“‘ “First line” “Second line” “” “Fourth line” “Fifth line” “`

With no block given, returns a new Enumerator.

Related: StringIO.each_byte, StringIO.each_char, StringIO.each_codepoint.



1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
# File 'ext/stringio/stringio.c', line 1641

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 Encoding:

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)


2065
2066
2067
2068
2069
2070
# File 'ext/stringio/stringio.c', line 2065

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)


2079
2080
2081
2082
2083
# File 'ext/stringio/stringio.c', line 2079

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

#isattynil #tty?nil

Overloads:

  • #isattynil

    Returns:

    • (nil)
  • #tty?nil

    Returns:

    • (nil)

#lengthInteger #sizeInteger

Returns the size of the buffer string.

Overloads:

  • #lengthInteger

    Returns:

    • (Integer)
  • #sizeInteger

    Returns:

    • (Integer)


2013
2014
2015
2016
2017
2018
2019
2020
2021
# File 'ext/stringio/stringio.c', line 2013

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)


1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
# File 'ext/stringio/stringio.c', line 1893

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)


1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
# File 'ext/stringio/stringio.c', line 1784

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)


1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
# File 'ext/stringio/stringio.c', line 1818

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)


1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
# File 'ext/stringio/stringio.c', line 1668

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 current position to the given integer offset (in bytes), with respect to a given constant whence; see Position.

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.



2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
# File 'ext/stringio/stringio.c', line 2095

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)


2135
2136
2137
2138
2139
2140
2141
2142
# File 'ext/stringio/stringio.c', line 2135

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

Returns the size of the buffer string.

Overloads:

  • #lengthInteger

    Returns:

    • (Integer)
  • #sizeInteger

    Returns:

    • (Integer)


2013
2014
2015
2016
2017
2018
2019
2020
2021
# File 'ext/stringio/stringio.c', line 2013

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)


2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
# File 'ext/stringio/stringio.c', line 2030

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)


1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
# File 'ext/stringio/stringio.c', line 1696

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