Class: IO::Like
- Inherits:
-
IO::LikeHelpers::DuplexedIO
- Object
- IO::LikeHelpers::AbstractIO
- IO::LikeHelpers::DelegatedIO
- IO::LikeHelpers::DuplexedIO
- IO::Like
- Includes:
- Enumerable, IO::LikeHelpers::RubyFacts
- Defined in:
- lib/io/like.rb
Overview
This is a wrapper class that provides the same instance methods as the IO class for simpler delegates given to it.
Constant Summary collapse
- ORS =
This is used by #puts as the separator between all arguments.
"\n"
Constants included from IO::LikeHelpers::RubyFacts
IO::LikeHelpers::RubyFacts::RBVER_LT_3_0, IO::LikeHelpers::RubyFacts::RBVER_LT_3_0_4, IO::LikeHelpers::RubyFacts::RBVER_LT_3_1, IO::LikeHelpers::RubyFacts::RBVER_LT_3_2, IO::LikeHelpers::RubyFacts::RBVER_LT_3_3, IO::LikeHelpers::RubyFacts::RBVER_LT_3_4
Instance Method Summary collapse
-
#<<(obj) ⇒ self
Writes ‘obj` to the stream using #write.
-
#binmode ⇒ self
Puts the stream into binary mode.
-
#binmode? ⇒ Boolean
Returns ‘true` if the stream is in binary mode and `false` otherwise.
-
#bytes(&block) ⇒ Object
deprecated
Deprecated.
Use #each_byte instead.
-
#chars(&block) ⇒ Object
deprecated
Deprecated.
Use #each_char instead.
-
#close ⇒ nil
Closes the stream, flushing any buffered data first.
-
#close_read ⇒ nil
Closes the read side of duplexed streams and closes the entire stream for read-only, non-duplexed streams.
-
#close_write ⇒ nil
Closes the write side of duplexed streams and closes the entire stream for write-only, non-duplexed streams.
-
#codepoints(&block) ⇒ Object
deprecated
Deprecated.
Use #each_codepoint instead.
- #each_byte ⇒ Object
- #each_char ⇒ Object
- #each_codepoint ⇒ Object
- #each_line(*args, **opts) ⇒ Object (also: #each)
-
#eof? ⇒ Boolean
(also: #eof)
Returns ‘true` if the end of the stream has been reached and `false` otherwise.
-
#external_encoding ⇒ Encoding?
Returns the external encoding of the stream, if any.
-
#flush ⇒ self
Flushes the internal write buffer to the underlying stream.
-
#getbyte ⇒ Integer?
Returns the next byte from the stream.
-
#getc ⇒ String?
Returns the next character from the stream.
-
#gets(*args, **opts) ⇒ Object
Returns the next line from the stream.
-
#initialize(delegate_r, delegate_w = delegate_r, autoclose: true, binmode: false, encoding: nil, encoding_opts: {}, external_encoding: nil, internal_encoding: nil, sync: false, pid: nil, pipeline_class: LikeHelpers::Pipeline) ⇒ Like
constructor
Creates a new instance of this class.
-
#internal_encoding ⇒ Encoding?
Returns the internal encoding of the stream, if any.
-
#lineno ⇒ Integer
Returns the current line number of the stream.
-
#lineno=(integer) ⇒ Integer
Sets the current line number of the stream to the given value.
-
#lines(*args, &block) ⇒ Object
deprecated
Deprecated.
Use #each_line instead.
-
#nread ⇒ Integer
The number of bytes that can be read without blocking or ‘0` if unknown.
-
#pid ⇒ Integer?
Returns the process ID of a child process associated with this stream, if any.
-
#pos ⇒ Integer
(also: #tell)
The current byte offset of the stream.
-
#pos=(position) ⇒ Integer
Sets the position of the stream to the given byte offset.
-
#pread(maxlen, offset, buffer = nil) ⇒ String
Reads at most ‘maxlen` bytes from the stream starting at `offset` without modifying the read position in the stream.
-
#print(*args) ⇒ nil
Writes the given object(s), if any, to the stream using #write.
-
#printf(*args) ⇒ nil
Writes the String returned by calling ‘Kernel.sprintf` using the given arguments.
-
#putc(obj) ⇒ obj
If ‘obj` is a String, write the first character; otherwise, convert `obj` to an Integer using the `Integer` method and write the low order byte.
-
#puts(*args) ⇒ nil
Writes the given object(s), if any, to the stream.
-
#pwrite(string, offset) ⇒ Integer
Writes at most ‘string.to_s.length` bytes to the stream starting at `offset` without modifying the write position in the stream.
-
#read(length = nil, buffer = nil) ⇒ String?
Reads data from the stream.
-
#read_nonblock(length, buffer = nil, exception: true) ⇒ String, ...
Reads and returns at most ‘length` bytes from the stream.
-
#readbyte ⇒ Integer
The next 8-bit byte (0..255) from the stream.
-
#readchar ⇒ String
The next character from the stream.
-
#readline(*args, **opts) ⇒ Object
Returns the next line from the stream.
- #readlines(*args, **opts) ⇒ Object
-
#readpartial(length, buffer = nil) ⇒ String
Reads and returns at most ‘length` bytes from the stream.
-
#reopen(*args, **opts) ⇒ self
Replaces the delegate(s) of this stream with another instance’s delegate(s) or an IO instance.
-
#rewind ⇒ 0
Sets the position of the file pointer to the beginning of the stream.
-
#seek(amount, whence = IO::SEEK_SET) ⇒ 0
Sets the current stream position to ‘amount` based on the setting of `whence`.
-
#set_encoding(ext_enc, int_enc = nil, **opts) ⇒ self
Sets the external and internal encodings of the stream.
-
#set_encoding_by_bom ⇒ nil, Encoding
Sets the external encoding of the stream based on a byte order mark (BOM) in the next bytes of the stream if found or to ‘nil` if not found.
-
#sync ⇒ Boolean
Returns ‘true` if the internal write buffer is being bypassed and `false` otherwise.
-
#sync=(sync) ⇒ Boolean
When set to ‘true` the internal write buffer will be bypassed.
-
#sysread(length, buffer = nil) ⇒ String
Reads and returns up to ‘length` bytes directly from the data stream, bypassing the internal read buffer.
-
#sysseek(offset, whence = IO::SEEK_SET) ⇒ Integer
Sets the current, unbuffered stream position to ‘amount` based on the setting of `whence`.
-
#syswrite(string) ⇒ Integer
Writes ‘string` directly to the data stream, bypassing the internal write buffer.
-
#ungetbyte(obj) ⇒ nil
Pushes bytes onto the internal read buffer such that subsequent read operations will return them first.
-
#ungetc(string) ⇒ nil
Pushes characters onto the internal read buffer such that subsequent read operations will return them first.
- #wait(*args) ⇒ self?
-
#wait_priority(timeout = nil) ⇒ self?
Waits until the stream is priority or until ‘timeout` is reached.
-
#wait_readable(timeout = nil) ⇒ self?
Waits until the stream is readable or until ‘timeout` is reached.
-
#wait_writable(timeout = nil) ⇒ self?
Waits until the stream is writable or until ‘timeout` is reached.
-
#write(*strings) ⇒ Integer
Writes the given arguments to the stream via an internal buffer and returns the number of bytes written.
-
#write_nonblock(string, exception: true) ⇒ Integer, ...
Enables blocking mode on the stream (via #nonblock=), flushes any buffered data, and then directly writes ‘string`, bypassing the internal buffer.
Methods inherited from IO::LikeHelpers::DuplexedIO
#close_on_exec=, #closed?, #closed_read?, #closed_write?, #inspect, #nonblock=, #readable?, #writable?
Methods inherited from IO::LikeHelpers::DelegatedIO
#advise, #autoclose=, #autoclose?, #close_on_exec=, #close_on_exec?, create_finalizer, #fcntl, #fdatasync, #fileno, #fsync, #inspect, #ioctl, #nonblock=, #nonblock?, #path, #readable?, #ready?, #stat, #to_io, #tty?, #writable?
Methods inherited from IO::LikeHelpers::AbstractIO
#advise, #close_on_exec=, #close_on_exec?, #closed?, #fcntl, #fdatasync, #fileno, #fsync, #ioctl, #nonblock, #nonblock=, #nonblock?, open, #path, #readable?, #ready?, #stat, #to_io, #tty?, #writable?
Constructor Details
#initialize(delegate_r, delegate_w = delegate_r, autoclose: true, binmode: false, encoding: nil, encoding_opts: {}, external_encoding: nil, internal_encoding: nil, sync: false, pid: nil, pipeline_class: LikeHelpers::Pipeline) ⇒ Like
Creates a new instance of this class.
43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 |
# File 'lib/io/like.rb', line 43 def initialize( delegate_r, delegate_w = delegate_r, autoclose: true, binmode: false, encoding: nil, encoding_opts: {}, external_encoding: nil, internal_encoding: nil, sync: false, pid: nil, pipeline_class: LikeHelpers::Pipeline ) if encoding if external_encoding warn("Ignoring encoding parameter '#{encoding}': external_encoding is used") encoding = nil elsif internal_encoding warn("Ignoring encoding parameter '#{encoding}': internal_encoding is used") encoding = nil end end if external_encoding external_encoding = Encoding.find(external_encoding) elsif internal_encoding external_encoding = Encoding.default_external end @pipeline_class = pipeline_class pipeline_r = @pipeline_class.new(delegate_r, autoclose: autoclose) pipeline_w = delegate_r == delegate_w ? pipeline_r : @pipeline_class.new(delegate_w, autoclose: autoclose) super(pipeline_r, pipeline_w) # NOTE: # Binary mode must be set before the encoding in order to allow any # explicitly set external encoding to override the implicit ASCII-8BIT # encoding when binmode is set. @binmode = false self.binmode if binmode if ! binmode || encoding || external_encoding || internal_encoding if encoding && ! (Encoding === encoding) && encoding =~ /^bom\|/i if ! set_encoding_by_bom set_encoding(encoding.to_s[4..-1], **encoding_opts) end else set_encoding( encoding || external_encoding, internal_encoding, **encoding_opts ) end end @pid = nil == pid ? pid : ensure_integer(pid) self.sync = sync @skip_duplexed_check = false @readable = @writable = nil end |
Instance Method Details
#<<(obj) ⇒ self
Writes ‘obj` to the stream using #write.
112 113 114 115 |
# File 'lib/io/like.rb', line 112 def <<(obj) write(obj) self end |
#binmode ⇒ self
Puts the stream into binary mode.
Once a stream is in binary mode, it cannot be reset to nonbinary mode.
-
Newline conversion disabled
-
Encoding conversion disabled
-
Content is treated as ASCII-8BIT
128 129 130 131 132 133 |
# File 'lib/io/like.rb', line 128 def binmode assert_open @binmode = true set_encoding(Encoding::BINARY) self end |
#binmode? ⇒ Boolean
Returns ‘true` if the stream is in binary mode and `false` otherwise.
141 142 143 144 |
# File 'lib/io/like.rb', line 141 def binmode? assert_open @binmode end |
#bytes(&block) ⇒ Object
Use #each_byte instead.
151 152 153 154 |
# File 'lib/io/like.rb', line 151 def bytes(&block) warn('warning: IO#bytes is deprecated; use #each_byte instead') each_byte(&block) end |
#chars(&block) ⇒ Object
Use #each_char instead.
160 161 162 163 |
# File 'lib/io/like.rb', line 160 def chars(&block) warn('warning: IO#chars is deprecated; use #each_char instead') each_char(&block) end |
#close ⇒ nil
Closes the stream, flushing any buffered data first.
This always blocks when buffered data needs to be written, even when the stream is in nonblocking mode.
173 174 175 176 177 178 179 180 |
# File 'lib/io/like.rb', line 173 def close @skip_duplexed_check = true super nil ensure @skip_duplexed_check = false end |
#close_read ⇒ nil
Closes the read side of duplexed streams and closes the entire stream for read-only, non-duplexed streams.
189 190 191 192 193 194 195 196 197 198 199 |
# File 'lib/io/like.rb', line 189 def close_read return if closed_read? if ! @skip_duplexed_check && ! duplexed? && writable? raise IOError, 'closing non-duplex IO for reading' end super nil end |
#close_write ⇒ nil
Closes the write side of duplexed streams and closes the entire stream for write-only, non-duplexed streams.
208 209 210 211 212 213 214 215 216 217 218 219 |
# File 'lib/io/like.rb', line 208 def close_write return if closed_write? if ! @skip_duplexed_check && ! duplexed? && readable? raise IOError, 'closing non-duplex IO for writing' end flush if writable? super nil end |
#codepoints(&block) ⇒ Object
Use #each_codepoint instead.
226 227 228 229 |
# File 'lib/io/like.rb', line 226 def codepoints(&block) warn('warning: IO#codepoints is deprecated; use #each_codepoint instead') each_codepoint(&block) end |
#each_byte ⇒ Enumerator #each_byte {|byte| ... } ⇒ self
246 247 248 249 250 251 252 253 |
# File 'lib/io/like.rb', line 246 def each_byte return to_enum(:each_byte) unless block_given? while (byte = getbyte) do yield(byte) end self end |
#each_char ⇒ Enumerator #each_char {|char| ... } ⇒ self
269 270 271 272 273 274 275 276 |
# File 'lib/io/like.rb', line 269 def each_char return to_enum(:each_char) unless block_given? while char = getc do yield(char) end self end |
#each_codepoint ⇒ Enumerator #each_codepoint {|codepoint| ... } ⇒ self
293 294 295 296 297 298 |
# File 'lib/io/like.rb', line 293 def each_codepoint return to_enum(:each_codepoint) unless block_given? each_char { |c| yield(c.codepoints[0]) } self end |
#each_line(separator = $/, limit = nil, chomp: false) ⇒ Enumerator #each_line(limit, chomp: false) ⇒ Enumerator #each_line(separator = $/, limit = nil, chomp: false) {|line| ... } ⇒ self #each_line(limit, chomp: false) {|line| ... } ⇒ self Also known as: each
352 353 354 355 356 357 358 359 360 361 362 363 364 |
# File 'lib/io/like.rb', line 352 def each_line(*args, **opts) unless block_given? return to_enum(:each_line, *args, **opts) end sep_string, limit = parse_readline_args(*args) raise ArgumentError, 'invalid limit: 0 for each_line' if limit == 0 while (line = gets(sep_string, limit, **opts)) do yield(line) end self end |
#eof? ⇒ Boolean Also known as: eof
This method will block if reading the stream blocks.
This method relies on buffered operations, so using it in conjuction with #sysread will be complicated at best.
Returns ‘true` if the end of the stream has been reached and `false` otherwise.
378 379 380 381 382 383 384 |
# File 'lib/io/like.rb', line 378 def eof? if byte = getbyte ungetbyte(byte) return false end true end |
#external_encoding ⇒ Encoding?
Returns the external encoding of the stream, if any.
395 396 397 398 399 400 401 402 |
# File 'lib/io/like.rb', line 395 def external_encoding assert_open if RBVER_LT_3_1 encoding = delegate.character_io.external_encoding return encoding if encoding || writable? Encoding::default_external end |
#flush ⇒ self
Flushes the internal write buffer to the underlying stream.
Regardless of the blocking status of the stream or interruptions during writing, this method will block until either all the data is flushed or until an error is raised.
414 415 416 417 418 419 420 |
# File 'lib/io/like.rb', line 414 def flush assert_open delegate_w.buffered_io.flush self end |
#getbyte ⇒ Integer?
Returns the next byte from the stream.
429 430 431 432 433 |
# File 'lib/io/like.rb', line 429 def getbyte readbyte rescue EOFError return nil end |
#getc ⇒ String?
Returns the next character from the stream.
442 443 444 445 446 |
# File 'lib/io/like.rb', line 442 def getc readchar rescue EOFError nil end |
#gets(separator = $/, limit = nil, chomp: false) ⇒ String? #gets(limit, chomp: false) ⇒ String?
Returns the next line from the stream.
475 476 477 478 479 480 481 482 483 |
# File 'lib/io/like.rb', line 475 def gets(*args, **opts) readline(*args, **opts) rescue EOFError # NOTE: # Through Ruby 3.3, assigning to $_ has no effect outside of a method that # does it. This assignment is kept in case that ever changes. $_ = nil nil end |
#internal_encoding ⇒ Encoding?
Returns the internal encoding of the stream, if any.
493 494 495 496 |
# File 'lib/io/like.rb', line 493 def internal_encoding assert_open if RBVER_LT_3_1 delegate.character_io.internal_encoding end |
#lineno ⇒ Integer
Returns the current line number of the stream.
More accurately the number of times #gets is called on the stream and returns a non-‘nil` result, either explicitly or implicitly via methods such as #each_line, #readline, #readlines, etc. is returned. This may differ from the number of lines if `$/` is changed from the default or if #gets is called with a different separator.
514 515 516 517 518 |
# File 'lib/io/like.rb', line 514 def lineno assert_readable @lineno ||= 0 end |
#lineno=(integer) ⇒ Integer
Sets the current line number of the stream to the given value. ‘$.` is updated by the next call to #gets. If the object given is not an Integer, it is converted to one using the `Integer` method.
528 529 530 531 532 |
# File 'lib/io/like.rb', line 528 def lineno=(integer) assert_readable @lineno = ensure_integer(integer) end |
#lines(*args, &block) ⇒ Object
Use #each_line instead.
539 540 541 542 |
# File 'lib/io/like.rb', line 539 def lines(*args, &block) warn('warning: IO#lines is deprecated; use #each_line instead') each_line(*args, &block) end |
#nread ⇒ Integer
Returns the number of bytes that can be read without blocking or ‘0` if unknown.
550 551 552 553 554 555 556 557 |
# File 'lib/io/like.rb', line 550 def nread assert_readable unless delegate_r.character_io.buffer_empty? raise IOError, 'byte oriented read for character buffered IO' end delegate_r.nread end |
#pid ⇒ Integer?
Returns the process ID of a child process associated with this stream, if any.
567 568 569 570 571 |
# File 'lib/io/like.rb', line 567 def pid assert_open return @pid unless nil == @pid super end |
#pos ⇒ Integer Also known as: tell
This method will block if writing the stream blocks and there is data in the write buffer.
Returns the current byte offset of the stream.
581 582 583 584 585 586 |
# File 'lib/io/like.rb', line 581 def pos assert_open flush delegate.seek(0, IO::SEEK_CUR) end |
#pos=(position) ⇒ Integer
Sets the position of the stream to the given byte offset.
598 599 600 601 |
# File 'lib/io/like.rb', line 598 def pos=(position) seek(position, IO::SEEK_SET) position end |
#pread(maxlen, offset, buffer = nil) ⇒ String
Reads at most ‘maxlen` bytes from the stream starting at `offset` without modifying the read position in the stream.
618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 |
# File 'lib/io/like.rb', line 618 def pread(maxlen, offset, buffer = nil) maxlen = ensure_integer(maxlen) raise ArgumentError, 'negative string size (or size too big)' if maxlen < 0 buffer = nil == buffer ? ''.b : ensure_string(buffer) return buffer if maxlen == 0 offset = ensure_integer(offset) raise Errno::EINVAL if offset < 0 assert_readable if maxlen > buffer.bytesize buffer << "\0" * (maxlen - buffer.bytesize) end bytes_read = delegate_r.pread(maxlen, offset, buffer: buffer) buffer.slice!(bytes_read..-1) buffer end |
#print(*args) ⇒ nil
Writes the given object(s), if any, to the stream using #write.
If no objects are given, ‘$_` is written. The field separator (`$,`) is written between successive objects if it is not `nil`. The output record separator (`$`) is written after all other data if it is not `nil`.
651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 |
# File 'lib/io/like.rb', line 651 def print(*args) # NOTE: # Through Ruby 3.1, $_ is always nil on entry to a Ruby method. This # assignment is kept in case that ever changes. args << $_ if args.empty? first_arg = true args.each do |arg| # Write a field separator before writing each argument after the first # one unless no field separator is specified. if first_arg first_arg = false else write($,) end write(arg) end # Write the output record separator if one is specified. write($\) if $\ nil end |
#printf(*args) ⇒ nil
Writes the String returned by calling ‘Kernel.sprintf` using the given arguments.
683 684 685 686 |
# File 'lib/io/like.rb', line 683 def printf(*args) write(sprintf(*args)) nil end |
#putc(obj) ⇒ obj
If ‘obj` is a String, write the first character; otherwise, convert `obj` to an Integer using the `Integer` method and write the low order byte.
699 700 701 702 703 704 705 706 707 708 |
# File 'lib/io/like.rb', line 699 def putc(obj) char = case obj when String obj[0] else [ensure_integer(obj)].pack('V')[0] end write(char) obj end |
#puts(*args) ⇒ nil
Writes the given object(s), if any, to the stream.
Uses #write after converting objects to strings using their ‘to_s` methods. Unlike #print, Array instances are recursively processed. The record separator character (`$`) is written after each object which does not end with the record separator already.
If no objects are given, a single record separator is written.
725 726 727 728 729 730 731 732 733 734 |
# File 'lib/io/like.rb', line 725 def puts(*args) # Write only the record separator if no arguments are given. if args.length == 0 write(ORS) return end flatten_puts(args) nil end |
#pwrite(string, offset) ⇒ Integer
Writes at most ‘string.to_s.length` bytes to the stream starting at `offset` without modifying the write position in the stream.
747 748 749 750 751 752 753 754 755 756 |
# File 'lib/io/like.rb', line 747 def pwrite(string, offset) string = string.to_s offset = ensure_integer(offset) raise Errno::EINVAL if offset < 0 assert_writable delegate_w.pwrite(string, offset) end |
#read(length = nil, buffer = nil) ⇒ String?
Reads data from the stream.
If ‘length` is specified as a positive integer, at most `length` bytes are returned. Truncated data will occur if there is insufficient data left to fulfill the request. If the read starts at the end of data, `nil` is returned.
If ‘length` is unspecified or `nil`, an attempt to return all remaining data is made. Partial data will be returned if a low-level error is raised after some data is retrieved. If no data would be returned at all, an empty String is returned.
If ‘buffer` is specified, it will be converted to a String using its `to_str` method if necessary and will be filled with the returned data if any.
783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 |
# File 'lib/io/like.rb', line 783 def read(length = nil, buffer = nil) length = ensure_integer(length) if nil != length if nil != length && length < 0 raise ArgumentError, "negative length #{length} given" end buffer = ensure_string(buffer) unless nil == buffer assert_readable unless length content = begin delegate_r.character_io.read_all rescue EOFError ''.encode( internal_encoding || external_encoding || Encoding.default_external ) end return content unless buffer return buffer.replace(content) end unless delegate_r.character_io.buffer_empty? raise IOError, 'byte oriented read for character buffered IO' end content = read_bytes(length) if buffer orig_encoding = buffer.encoding buffer.replace(content) buffer.force_encoding(orig_encoding) content = buffer end return nil if content.empty? && length > 0 return content end |
#read_nonblock(length, buffer = nil, exception: true) ⇒ String, ...
Reads and returns at most ‘length` bytes from the stream.
If the internal read buffer is not empty, only the buffer is used, even if less than ‘length` bytes are available. If the internal buffer is empty, sets non-blocking mode via IO::LikeHelpers::DuplexedIO#nonblock= and then reads from the underlying stream.
847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 |
# File 'lib/io/like.rb', line 847 def read_nonblock(length, buffer = nil, exception: true) length = ensure_integer(length) raise ArgumentError, 'length must be at least 0' if length < 0 buffer = ensure_string(buffer) if nil != buffer assert_readable if RBVER_LT_3_0_4 && length == 0 return (buffer || ''.b) end unless delegate_r.character_io.buffer_empty? raise IOError, 'byte oriented read for character buffered IO' end result = ensure_buffer(length, buffer) do |binary_buffer| unless delegate_r.buffered_io.read_buffer_empty? next delegate_r.read(length, buffer: binary_buffer) end self.nonblock = true delegate_r.concrete_io.read(length, buffer: binary_buffer) end case result when String # This means that a buffer was not given and that the delegate returned a # buffer with the content. return result when Integer # This means that a buffer was given and that the content is in the # buffer. return buffer else return nonblock_response(result, exception) end rescue EOFError raise if exception return nil end |
#readbyte ⇒ Integer
Returns the next 8-bit byte (0..255) from the stream.
893 894 895 896 897 898 899 900 901 |
# File 'lib/io/like.rb', line 893 def readbyte assert_readable unless delegate_r.character_io.buffer_empty? raise IOError, 'byte oriented read for character buffered IO' end byte = delegate_r.read(1) byte[0].ord end |
#readchar ⇒ String
Returns the next character from the stream.
908 909 910 911 912 |
# File 'lib/io/like.rb', line 908 def readchar assert_readable delegate_r.character_io.read_char end |
#readline(separator = $/, limit = nil, chomp: false) ⇒ String #readline(limit, chomp: false) ⇒ String
Returns the next line from the stream.
940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 |
# File 'lib/io/like.rb', line 940 def readline(*args, **opts) separator, limit = parse_readline_args(*args) chomp = opts.fetch(:chomp, false) assert_readable discard_newlines = false encoding = internal_encoding || external_encoding || Encoding.default_external if separator # Reading with a record separator is performed using bytes rather than # characters, so ensure that the separator is correctly encoded to make # this possible. if separator.empty? # Read by paragraph is requested. The separator is 2 newline characters # in the encoding of the character reader. discard_newlines = true separator = "\n\n" separator = separator.b if RBVER_LT_3_4 elsif $/.equal?(separator) # When using the default record separator character, convert it into the # encoding of the character reader. separator = separator.encode(encoding) elsif ! (separator.encoding == encoding || (separator.ascii_only? && encoding.ascii_compatible?)) # Raise an error when the separator encoding doesn't match the reader # encoding and ASCII compatibility is not available. # # NOTE: # We should probably attempt to convert the encoding of the separator # into the encoding of the reader before raising this error, but MRI # doesn't appear to do that. raise ArgumentError, 'encoding mismatch: %s IO with %s RS' % [encoding, separator.encoding] end end buffer = delegate_r.character_io.read_line( separator: separator, limit: limit, chomp: chomp, discard_newlines: discard_newlines ) # Increment the number of times this method has returned a "line". self.lineno += 1 # Set the last line number in the global. $. = lineno # Set the last read line in the global and return it. # NOTE: # Through Ruby 3.3, assigning to $_ has no effect outside of a method that # does it. This assignment is kept in case that ever changes. $_ = buffer end |
#readlines(separator = $/, limit = nil, chomp: false) ⇒ Array<String> #readlines(limit, chomp: false) ⇒ Array<String>
1020 1021 1022 |
# File 'lib/io/like.rb', line 1020 def readlines(*args, **opts) each_line(*args, **opts).to_a end |
#readpartial(length, buffer = nil) ⇒ String
Reads and returns at most ‘length` bytes from the stream.
If the internal read buffer is not empty, only the buffer is used, even if less than ‘length` bytes are available. If the internal buffer is empty, reads from the underlying stream.
1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 |
# File 'lib/io/like.rb', line 1038 def readpartial(length, buffer = nil) length = ensure_integer(length) raise ArgumentError, 'length must be at least 0' if length < 0 buffer = ensure_string(buffer) if nil != buffer assert_readable if RBVER_LT_3_0_4 && length == 0 return (buffer || ''.b) end unless delegate_r.character_io.buffer_empty? raise IOError, 'byte oriented read for character buffered IO' end result = ensure_buffer(length, buffer) do |binary_buffer| unless delegate_r.buffered_io.read_buffer_empty? next delegate_r.read(length, buffer: binary_buffer) end delegate_r.blocking_io.read(length, buffer: binary_buffer) end # The delegate returns the read content unless a buffer is given. return nil == buffer ? result : buffer end |
#reopen(other) ⇒ self #reopen(io) ⇒ self #reopen(path, mode, **opt) ⇒ self
Replaces the delegate(s) of this stream with another instance’s delegate(s) or an IO instance.
1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 |
# File 'lib/io/like.rb', line 1091 def reopen(*args, **opts) unless args.size == 1 || args.size == 2 raise ArgumentError, "wrong number of arguments (given #{args.size}, expected 1..2)" end if args.size == 1 begin io = args[0] io = args[0].to_io unless IO::Like === io if IO::Like === io assert_open new_delegate_r = io.delegate_r.concrete_io.dup new_delegate_w = io.duplexed? ? io.delegate_w.concrete_io.dup : new_delegate_r close initialize( new_delegate_r, new_delegate_w, binmode: io.binmode?, internal_encoding: delegate_r.character_io.internal_encoding, external_encoding: delegate_r.character_io.external_encoding, sync: io.sync, pid: io.pid, pipeline_class: @pipeline_class ) return self end unless IO === io raise TypeError, "can't convert #{args[0].class} to IO (#{args[0].class}#to_io gives #{io.class})" end assert_open io = io.dup rescue NoMethodError mode = (readable? ? 'r' : 'w').dup mode << '+' if readable? && writable? mode << 'b' io = File.open(args[0], mode) end else io = File.open(*args, **opts) end close initialize( IO::LikeHelpers::IOWrapper.new(io), binmode: io.binmode?, internal_encoding: delegate_r.character_io.internal_encoding, external_encoding: delegate_r.character_io.external_encoding, sync: io.sync, pid: io.pid, pipeline_class: @pipeline_class ) self end |
#rewind ⇒ 0
Sets the position of the file pointer to the beginning of the stream.
The ‘lineno` attribute is reset to `0` if successful and the stream is readable.
1161 1162 1163 1164 1165 |
# File 'lib/io/like.rb', line 1161 def rewind seek(0, IO::SEEK_SET) self.lineno = 0 if readable? 0 end |
#seek(amount, whence = IO::SEEK_SET) ⇒ 0
Sets the current stream position to ‘amount` based on the setting of `whence`.
| ‘whence` | `amount` Interpretation | | ——– | ———————– | | `:CUR` or `IO::SEEK_CUR` | `amount` added to current stream position | | `:END` or `IO::SEEK_END` | `amount` added to end of stream position (`amount` will usually be negative here) | | `:SET` or `IO::SEEK_SET` | `amount` used as absolute position |
1185 1186 1187 1188 1189 1190 1191 |
# File 'lib/io/like.rb', line 1185 def seek(amount, whence = IO::SEEK_SET) super # This also clears the byte oriented read buffer, so calling # delegate_r.buffered_io.flush would be redundant. delegate_r.character_io.clear 0 end |
#set_encoding(encoding, **opts) ⇒ self #set_encoding(external, internal, **opts) ⇒ self
Sets the external and internal encodings of the stream.
When the given external encoding is not ‘nil` or `Encoding::BINARY` or an equivalent and the internal encoding is either not given or `nil`, the current value of `Encoding.default_internal` is used for the internal encoding.
When the given external encoding is ‘nil` and the internal encoding is either not given or `nil`, the current values of `Encoding.default_external` and `Encoding.default_internal` are used, respectively, unless `Encoding.default_external` is `Encoding::BINARY` or an equivalent or `Encoding.default_internal` is `nil`, in which case `nil` is used for both.
Setting the given internal encoding to ‘“-”` indicates no character conversion should be performed. The internal encoding of the stream will be set to `nil`. This is needed in cases where `Encoding.default_internal` is not `nil` but character conversion is not desired.
1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 |
# File 'lib/io/like.rb', line 1229 def set_encoding(ext_enc, int_enc = nil, **opts) assert_open # Check that any given newline option is valid. if opts.key?(:newline) && ! %i{cr lf crlf universal}.include?(opts[:newline]) = 'unexpected value for newline option' += ": #{opts[:newline]}" if Symbol === opts[:newline] raise ArgumentError, end # Newline handling is not allowed in binary mode. if binmode? && (opts.key?(:newline) || opts[:cr_newline] || opts[:crlf_newline] || opts[:lf_newline] || opts[:universal_newline]) raise ArgumentError, 'newline decorator with binary mode' end # Ruby 3.2 and below have a bug (#18899) handling the internal encoding # correctly when the external encoding is binary that only happens when they # are supplied individually to this method. bug_18899_compatibility = RBVER_LT_3_3 # Convert the argument(s) into Encoding objects. if ! (nil == ext_enc || Encoding === ext_enc) && nil == int_enc string_arg = ensure_string(ext_enc) begin e, _, i = string_arg.rpartition(':') # Bug #18899 compatibility is unnecessary when the encodings are passed # together as a colon speparated string. ext_enc, int_enc, bug_18899_compatibility = e, i, false unless e.empty? rescue Encoding::CompatibilityError # This is caused by failure to split on colon when the string argument # is not ASCII compatible. Ignore it and use the argument as is. end end # Potential values: # ext_enc int_enc # ====================== # nil Object => error # nil nil => maybe copy default encodings # Object Object => use given encodings # Object nil => maybe copy default internal encoding if nil == ext_enc && nil == int_enc unless Encoding::BINARY == Encoding.default_external || nil == Encoding.default_internal ext_enc = Encoding.default_external int_enc = Encoding.default_internal end else ext_enc = Encoding.find(ext_enc) int_enc = case int_enc when nil RBVER_LT_3_3 ? nil : Encoding.default_internal when '-' # Allows explicit request of no conversion when # Encoding.default_internal is set. nil else Encoding.find(int_enc) end end # Ignore the chosen internal encoding when no conversion will be performed. if int_enc == ext_enc || Encoding::BINARY == ext_enc && ! bug_18899_compatibility int_enc = nil end # ASCII incompatible external encoding without conversion when reading # requires binmode. if ! binmode? && readable? && nil == int_enc && ! (ext_enc || Encoding.default_external).ascii_compatible? raise ArgumentError, 'ASCII incompatible encoding needs binmode' end delegate_r.character_io.set_encoding(ext_enc, int_enc, **opts) if duplexed? delegate_w.character_io.set_encoding(ext_enc, int_enc, **opts) end self end |
#set_encoding_by_bom ⇒ nil, Encoding
Sets the external encoding of the stream based on a byte order mark (BOM) in the next bytes of the stream if found or to ‘nil` if not found.
1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 |
# File 'lib/io/like.rb', line 1326 def set_encoding_by_bom unless binmode? raise ArgumentError, 'ASCII incompatible encoding needs binmode' end if nil != internal_encoding raise ArgumentError, 'encoding conversion is set' elsif nil != external_encoding && Encoding::BINARY != external_encoding raise ArgumentError, "encoding is set to #{external_encoding} already" end return nil unless readable? case b1 = getbyte when nil when 0xEF case b2 = getbyte when nil when 0xBB case b3 = getbyte when nil when 0xBF set_encoding(Encoding::UTF_8) return Encoding::UTF_8 end ungetbyte(b3) end ungetbyte(b2) when 0xFE case b2 = getbyte when nil when 0xFF set_encoding(Encoding::UTF_16BE) return Encoding::UTF_16BE end ungetbyte(b2) when 0xFF case b2 = getbyte when nil when 0xFE case b3 = getbyte when nil when 0x00 case b4 = getbyte when nil when 0x00 set_encoding(Encoding::UTF_32LE) return Encoding::UTF_32LE end ungetbyte(b4) end ungetbyte(b3) set_encoding(Encoding::UTF_16LE) return Encoding::UTF_16LE end ungetbyte(b2) when 0x00 case b2 = getbyte when nil when 0x00 case b3 = getbyte when nil when 0xFE case b4 = getbyte when nil when 0xFF set_encoding(Encoding::UTF_32BE) return Encoding::UTF_32BE end ungetbyte(b4) end ungetbyte(b3) end ungetbyte(b2) end ungetbyte(b1) return nil end |
#sync ⇒ Boolean
Returns ‘true` if the internal write buffer is being bypassed and `false` otherwise.
1412 1413 1414 1415 |
# File 'lib/io/like.rb', line 1412 def sync assert_open delegate_w.character_io.sync? end |
#sync=(sync) ⇒ Boolean
When set to ‘true` the internal write buffer will be bypassed. Any data currently in the buffer will be flushed prior to the next output operation. When set to `false`, the internal write buffer will be enabled.
1427 1428 1429 1430 |
# File 'lib/io/like.rb', line 1427 def sync=(sync) assert_open delegate_w.character_io.sync = sync end |
#sysread(length, buffer = nil) ⇒ String
Reads and returns up to ‘length` bytes directly from the data stream, bypassing the internal read buffer.
If ‘buffer` is given, it is used to store the bytes that are read; otherwise, a new buffer is created.
Returns an empty String if ‘length` is `0` regardless of the status of the data stream. This is for compatibility with `IO#sysread`.
1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 |
# File 'lib/io/like.rb', line 1450 def sysread(length, buffer = nil) length = ensure_integer(length) raise ArgumentError, "negative length #{length} given" if length < 0 buffer = ensure_string(buffer) unless nil == buffer return (buffer || ''.b) if length == 0 assert_readable if ! delegate_r.buffered_io.read_buffer_empty? raise IOError, 'sysread for buffered IO' elsif ! delegate_r.character_io.buffer_empty? raise IOError, 'byte oriented read for character buffered IO' end result = ensure_buffer(length, buffer) do |binary_buffer| delegate_r.blocking_io.read(length, buffer: binary_buffer) end # The delegate returns the read content unless a buffer is given. return buffer ? buffer : result end |
#sysseek(offset, whence = IO::SEEK_SET) ⇒ Integer
Sets the current, unbuffered stream position to ‘amount` based on the setting of `whence`.
| ‘whence` | `amount` Interpretation | | ——– | ———————– | | `:CUR` or `IO::SEEK_CUR` | `amount` added to current stream position | | `:END` or `IO::SEEK_END` | `amount` added to end of stream position (`amount` will usually be negative here) | | `:SET` or `IO::SEEK_SET` | `amount` used as absolute position |
1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 |
# File 'lib/io/like.rb', line 1492 def sysseek(offset, whence = IO::SEEK_SET) assert_open if ! delegate_r.buffered_io.read_buffer_empty? || ! delegate_r.character_io.buffer_empty? raise IOError, 'sysseek for buffered IO' end unless delegate_w.buffered_io.write_buffer_empty? warn('warning: sysseek for buffered IO') end delegate.blocking_io.seek(offset, whence) end |
#syswrite(string) ⇒ Integer
Writes ‘string` directly to the data stream, bypassing the internal write buffer.
1514 1515 1516 1517 1518 1519 1520 1521 |
# File 'lib/io/like.rb', line 1514 def syswrite(string) assert_writable unless delegate_w.buffered_io.write_buffer_empty? warn('warning: syswrite for buffered IO') end delegate_w.buffered_io.flush || delegate_w.blocking_io.write(string.to_s.b) end |
#ungetbyte(string) ⇒ nil #ungetbyte(integer) ⇒ nil
Pushes bytes onto the internal read buffer such that subsequent read operations will return them first.
1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 |
# File 'lib/io/like.rb', line 1543 def ungetbyte(obj) assert_readable return if nil == obj string = case obj when String obj when Integer (obj & 255).chr else ensure_string(obj) end delegate_r.character_io.unread(string.b) nil end |
#ungetc(string) ⇒ nil #ungetc(integer) ⇒ nil
Pushes characters onto the internal read buffer such that subsequent read operations will return them first.
1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 |
# File 'lib/io/like.rb', line 1579 def ungetc(string) assert_readable return if nil == string && RBVER_LT_3_0 string = case string when String string.dup when Integer encoding = internal_encoding || external_encoding nil == encoding ? string.chr : string.chr(encoding) else ensure_string(string) end delegate_r.character_io.unread(string.b) nil end |
#wait(events, timeout) ⇒ self? #wait(timeout = nil, mode = :read) ⇒ self?
1617 1618 1619 1620 1621 1622 1623 1624 1625 1626 1627 1628 1629 1630 1631 1632 1633 1634 1635 1636 1637 1638 1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651 1652 1653 1654 1655 1656 1657 1658 1659 1660 1661 |
# File 'lib/io/like.rb', line 1617 def wait(*args) events = 0 timeout = nil if RBVER_LT_3_0 # Ruby <=2.7 compatibility mode while running Ruby <=2.7. args.each do |arg| case arg when Symbol events |= wait_event_from_symbol(arg) else timeout = arg if nil != timeout && timeout < 0 raise ArgumentError, 'time interval must not be negative' end end end else if args.size < 2 || args.size >= 2 && Symbol === args[1] # Ruby <=2.7 compatibility mode while running Ruby >=3.0. timeout = args[0] if args.size > 0 if nil != timeout && timeout < 0 raise ArgumentError, 'time interval must not be negative' end events = args[1..-1] .map { |mode| wait_event_from_symbol(mode) } .inject(0) { |memo, value| memo | value } elsif args.size == 2 # Ruby >=3.0 mode. events = ensure_integer(args[0]) timeout = args[1] if nil != timeout && timeout < 0 raise ArgumentError, 'time interval must not be negative' end else # Arguments are invalid, but punt like Ruby 3.0 does. return nil end end events = IO::READABLE if events == 0 assert_open return self if super(events, timeout) return nil end |
#wait_priority(timeout = nil) ⇒ self?
Waits until the stream is priority or until ‘timeout` is reached.
Returns ‘true` immediately if buffered data is available to read.
1675 1676 1677 1678 1679 1680 |
# File 'lib/io/like.rb', line 1675 def wait_priority(timeout = nil) assert_readable return self if delegate.wait(IO::PRIORITY, timeout) return nil end |
#wait_readable(timeout = nil) ⇒ self?
Waits until the stream is readable or until ‘timeout` is reached.
Returns ‘true` immediately if buffered data is available to read.
1692 1693 1694 1695 1696 1697 |
# File 'lib/io/like.rb', line 1692 def wait_readable(timeout = nil) assert_readable return self if delegate.wait(IO::READABLE, timeout) return nil end |
#wait_writable(timeout = nil) ⇒ self?
Waits until the stream is writable or until ‘timeout` is reached.
1706 1707 1708 1709 1710 1711 |
# File 'lib/io/like.rb', line 1706 def wait_writable(timeout = nil) assert_writable return self if delegate.wait(IO::WRITABLE, timeout) return nil end |
#write(*strings) ⇒ Integer
Writes the given arguments to the stream via an internal buffer and returns the number of bytes written.
If an argument is not a ‘String`, its `to_s` method is used to convert it into one. The entire contents of all arguments are written, blocking as necessary even if the underlying stream does not block.
1726 1727 1728 1729 1730 1731 1732 1733 1734 1735 1736 1737 1738 1739 1740 1741 1742 1743 1744 1745 1746 1747 1748 1749 |
# File 'lib/io/like.rb', line 1726 def write(*strings) # This short circuit is for compatibility with old Ruby versions where this # method took a single argument and would return 0 when the argument # resulted in a 0 length string without first checking if the stream was # already closed. if strings.size == 1 # This satisfies rubyspec by ensuring that the argument's #to_s method is # only called once in the case where it results in a non-empty string and # the short circuit is skipped. strings[0] = strings[0].to_s return 0 if strings[0].empty? end assert_writable delegate_w.buffered_io.flush if sync bytes_written = 0 strings.each do |string| bytes_written += delegate_w.character_io.write(string.to_s) end bytes_written end |
#write_nonblock(string, exception: true) ⇒ Integer, ...
Enables blocking mode on the stream (via #nonblock=), flushes any buffered data, and then directly writes ‘string`, bypassing the internal buffer.
If ‘string` is not a `String`, its `to_s` method is used to convert it into one. If any of `string` is written, this method returns the number of bytes written, which may be less than all requested bytes (partial write).
1772 1773 1774 1775 1776 1777 1778 1779 1780 1781 1782 1783 1784 1785 |
# File 'lib/io/like.rb', line 1772 def write_nonblock(string, exception: true) assert_writable string = string.to_s self.nonblock = true result = delegate_w.buffered_io.flush || delegate_w.concrete_io.write(string.b) case result when Integer return result else return nonblock_response(result, exception) end end |