# File lib/io/like-1.9.2.rb, line 7 def initialize(*args) super(*args) @init_external_encoding = Encoding.default_external @init_internal_encoding = Encoding.default_internal end
# File lib/io/like-1.9.2.rb, line 16 def binmode raise IOError, "closed stream" if closed? set_encoding(Encoding::BINARY,nil) self end
# File lib/io/like-1.9.2.rb, line 25 def binmode? external_encoding == Encoding::BINARY end
# File lib/io/like-1.9.2.rb, line 37 def close_on_exec=(coe) raise NotImplementedError end
# File lib/io/like-1.9.2.rb, line 31 def close_on_exec?() raise NotImplementedError end
Reads each byte from the stream and calls the given block once for each character, passing the byte as an argument.
When called without a block, returns an instance of Enumerator
which will iterate over each byte in the same manner.
NOTE: This method ignores Errno::EAGAIN
and
Errno::EINTR
raised by unbuffered_read. Therefore, this
method always blocks. Aside from that exception and the conversion of
EOFError
results into nil
results, this method
will also raise the same errors and block at the same times as
unbuffered_read.
# File lib/io/like-1.9.2.rb, line 58 def each_byte unless block_given? self.to_enum(:each_byte) else while (byte = getbyte) yield byte end self end end
As each_byte but yields characters (encoded strings of length 1) instead of bytes
# File lib/io/like-1.9.2.rb, line 77 def each_char unless block_given? self.to_enum(:each_char) else while (char = getc) yield char end self end end
As each_char but yields codepoints instead of characters.
# File lib/io/like-1.9.2.rb, line 95 def each_codepoint unless block_given? self.to_enum(:each_codepoint) else while (char = getc) yield char.codepoints.next end self end end
Reads each line from the stream using gets and calls the given block once for each line, passing the line as an argument. Alternatively if no block is given returns an enumerator
NOTE: When sep_string is not nil
,
this method ignores Errno::EAGAIN
and
Errno::EINTR
raised by unbuffered_read. Therefore, this
method always blocks. Aside from that exception and the conversion of
EOFError
results into nil
results, this method
will also raise the same errors and block at the same times as
unbuffered_read.
# File lib/io/like-1.9.2.rb, line 126 def each_line(sep = :io_like, limit = :io_like) unless block_given? self.to_enum(:each) else while line = gets(sep, limit) yield line end self end end
Returns the Encoding
object used for the external encoding.
# File lib/io/like-1.9.2.rb, line 591 def external_encoding if writable? @external_encoding || (Encoding.default_internal ? @init_external_encoding : nil ) else @external_encoding || (Encoding.default_internal ? @init_external_encoding : Encoding.default_external) end end
Calls readbyte and either
returns the result or nil
if on EOFError
.
Raises IOError
if closed? returns true
. Raises
IOError
unless readable? returns true
. Raises
all errors raised by unbuffered_read except for EOFError
.
NOTE: This method ignores Errno::EAGAIN
and
Errno::EINTR
raised by unbuffered_read. Therefore, this
method always blocks. Aside from that exception and the conversion of
EOFError
results into nil
results, this method
will also raise the same errors and block at the same times as
unbuffered_read. nil at eof
# File lib/io/like-1.9.2.rb, line 157 def getbyte readbyte() rescue EOFError nil end
Calls readline and either
returns the result or nil
if readline raises
EOFError
.
If readline returns some
data, $.
is set to the value of lineno.
NOTE: Due to limitations of MRI up to version 1.9.x when
running managed (Ruby) code, this method fails to set $_
to
the returned data; however, other implementations may allow it.
# File lib/io/like-1.9.2.rb, line 181 def gets(sep_string = :io_like, limit = :io_like) # Set the last read line in the global. $_ = readline(sep_string, limit) # Set the last line number in the global. $. = lineno # Return the last read line. $_ rescue EOFError nil end
Returns the Encoding
object used for internal conversion or
nil if no internal conversion has been specified.
# File lib/io/like-1.9.2.rb, line 604 def internal_encoding @internal_encoding || (@init_internal_encoding == external_encoding ? nil : @init_internal_encoding) end
Writes the given object(s), if any, to the stream using write after converting them to
strings by calling their to_s
methods. If no objects are
given, $_
is used. The field separator ($,
) is
written between successive objects if it is not nil
. The
output record separator ($\</code>) is written after all other
data if it is not <code>nil
.
Raises IOError
if closed? returns true
. Raises
IOError
unless writable? returns true
.
NOTE: This method ignores Errno::EAGAIN
and
Errno::EINTR
raised by unbuffered_write. Therefore, this
method always blocks if unable to immediately write [obj, ...]
completely. Aside from that exception, this method will also raise the
same errors and block at the same times as unbuffered_write.
# File lib/io/like-1.9.2.rb, line 211 def print(*args) 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 then first_arg = false elsif ! $,.nil? then write($,) end # If the argument is nil, write 'nil'; otherwise, write the stringified # form of the argument. if arg.nil? then write("") else write(arg) end end # Write the output record separator if one is specified. write($\) unless $\.nil? nil end
Writes the given object(s), if any, to the stream using write after converting them to
strings using their to_s
methods. Unlike print, Array instances are
recursively processed. A 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.
Raises IOError
if closed? returns true
. Raises
IOError
unless writable? returns true
.
NOTE: This method ignores Errno::EAGAIN
and
Errno::EINTR
raised by unbuffered_write. Therefore, this
method always blocks if unable to immediately write [obj, ...]
completely. Aside from that exception, this method will also raise the
same errors and block at the same times as unbuffered_write.
NOTE: In order to be compatible with IO#puts
,
the record separator is currently hardcoded to be a single newline
("\n"
) even though the documentation implies that
the output record separator (<code>$</code>) should be used.
# File lib/io/like-1.9.2.rb, line 261 def puts(*args) # Set the output record separator such that this method is compatible with # IO#puts. ors = "\n" # Write only the record separator if no arguments are given. if args.length == 0 then write(ors) return end # Write each argument followed by the record separator. Recursively # process arguments which are Array instances. __io_like__array_flatten(args) do |string| write(string.nil? ? '' : string) write(ors) if string.nil? || string.index(ors, -ors.length).nil? end nil end
If length is specified and is 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.
Raises IOError
if closed? returns true
. Raises
IOError
unless readable? returns true
.
NOTE: Because this method relies on unbuffered_read, it will also raise the same errors and block at the same times as that function.
# File lib/io/like-1.9.2.rb, line 303 def read(length = nil, buffer = nil) # Check the validity of the method arguments. unless length.nil? || length >= 0 then raise ArgumentError, "negative length #{length} given" end buffer = buffer.nil? ? ''.force_encoding(Encoding::BINARY) : buffer.to_str buffer.slice!(0..-1) unless buffer.empty? if length.nil? then # Read and return everything. begin loop do buffer << __io_like__buffered_read(4096) end rescue EOFError # Ignore this. rescue SystemCallError # Reraise the error if there is nothing to return. raise if buffer.empty? end buffer.force_encoding(__io_like__external_encoding) buffer.encode!(__io_like__internal_encoding,__io_like__encoding_options) if !binmode? || @internal_encoding else # Read and return up to length bytes. enc = buffer.encoding begin buffer << __io_like__buffered_read(length) rescue EOFError # Return nil to the caller at end of file when requesting a specific # amount of data. return nil end buffer.force_encoding(enc) end buffer end
Returns at most length bytes from the data stream using only the internal read buffer if the buffer is not empty.
If internal buffer is empty sets nonblocking mode via nonblock=(true) and then reads from the underlying stream
Raises Errno::EBADF
if nonblocking mode is not supported
Raises EOFError
when there is no more data in the stream.
Raises IOError
if closed? returns true
. Raises
IOError
unless readable? returns true
.
This method will raise errors directly from buffered_read to be handled by
the caller. If unbuffered_read raises Errno::EAGAIN
or
Errno::EWOULDBLOCK
the exception will be extended with
IO::WaitReadable
.
# File lib/io/like-1.9.2.rb, line 530 def read_nonblock(*args) begin super(*args) rescue IO::WaitReadable raise rescue Errno::EWOULDBLOCK, Errno::EAGAIN => ex ex.extend(IO::WaitReadable) raise ex end end
Returns the next 8-bit byte (0..255) from the stream.
Raises EOFError
when there is no more data in the stream.
Raises IOError
if closed? returns true
. Raises
IOError
unless readable? returns true
.
NOTE: This method ignores Errno::EAGAIN
and
Errno::EINTR
raised by unbuffered_read. Therefore, this
method always blocks. Aside from that exception, this method will also
raise the same errors and block at the same times as unbuffered_read.
# File lib/io/like-1.9.2.rb, line 353 def readbyte __io_like__buffered_read(1).getbyte(0) end
Returns the next character (encoded string of length 1) from the stream
Raises EOFError
when there is no more data in the stream.
Raises IOError
if closed? returns true
. Raises
IOError
unless readable? returns true
.
NOTE: This method ignores Errno::EAGAIN
and
Errno::EINTR
raised by unbuffered_read. Therefore, this
method always blocks. Aside from that exception, this method will also
raise the same errors and block at the same times as unbuffered_read.
# File lib/io/like-1.9.2.rb, line 370 def readchar __io_like__buffered_read_chars(1) end
Returns the next line from the stream, where lines are separated by
sep_string. Increments lineno by 1
for each call
regardless of the value of sep_string.
If sep_string is not nil
and not a
String
, it is first converted to a String
using
its to_str
method and processing continues as follows.
If sep_string is nil
, a line is defined as the
remaining contents of the stream. Partial data will be returned if a
low-level error of any kind is raised after some data is retrieved. This
is equivalent to calling read
without any arguments except that this method will raise an
EOFError
if called at the end of the stream.
If sep_string is an empty String
, a paragraph is
returned, where a paragraph is defined as data followed by 2 or more
successive newline characters. A maximum of 2 newlines are returned at the
end of the returned data. Fewer may be returned if the stream ends before
at least 2 successive newlines are seen.
Any other value for sep_string is used as a delimiter to mark the end of a line. The returned data includes this delimiter unless the stream ends before the delimiter is seen.
In any case, the end of the stream terminates the current line.
If the limit argument is given, only that many bytesi, plus whatever is required to complete a partial multibyte character, will be read from the underlying stream while searching for the separator. If the separator is not found the partial data will be returned.
Raises EOFError
when there is no more data in the stream.
Raises IOError
if closed? returns true
. Raises
IOError
unless readable? returns true
.
NOTE: When sep_string is not nil
,
this method ignores Errno::EAGAIN
and
Errno::EINTR
raised by unbuffered_read. Therefore, this
method will always block in that case. Aside from that exception, this
method will raise the same errors and block at the same times as
unbuffered_read.
# File lib/io/like-1.9.2.rb, line 423 def readline(sep_string = :io_like , limit = :io_like) if sep_string == :io_like #no args limit = 0 sep_string = $/ elsif limit == :io_like if sep_string.nil? limit = 0 elsif sep_string.respond_to?(:to_int) #single arg (limit) limit = sep_string.to_int sep_string = $/ elsif sep_string.respond_to?(:to_str) #single arg (seperator) sep_string = sep_string.to_str if sep_string limit = 0 else raise ArgumentError, "invalid args #{sep_string}, #{limit}" end else #two args limit = limit.to_int if limit sep_string = sep_string.to_str if sep_string end buffer = '' begin if sep_string.nil? then # A nil line separator means that the user wants to capture all the # remaining input. while limit <= 0 || buffer.bytesize < limit buffer << __io_like__buffered_read_chars(limit <= 0 ? 4096 : limit - buffer.bytesize) end else begin # Record if the user requested paragraphs rather than lines. paragraph_requested = sep_string.empty? # An empty line separator string indicates that the user wants to # return paragraphs. A pair of newlines in the stream is used to # mark this. sep_string = "\n\n" if paragraph_requested # GG: I can't find any general guidance on how this should work in terms of searching # when the separator encoding (suually from source file) doesn't match # the default internal/external encoding. So instead we'll just do # a binary match. if paragraph_requested then # If the user requested paragraphs instead of lines, we need to # consume and discard all newlines remaining at the front of the # input. char = __io_like__buffered_read(1) char = __io_like__buffered_read(1) while char == "\n" # Put back the last character. __io_like__unread(char[0]) end # Add each character from the input to the buffer until either the # buffer has the right ending or the end of the input is reached. while buffer.index(sep_string, -sep_string.length).nil? && (limit == 0 || buffer.bytesize < limit) do buffer << __io_like__buffered_read_chars(1) end if paragraph_requested then # If the user requested paragraphs instead of lines, we need to # consume and discard all newlines remaining at the front of the # input. char = __io_like__buffered_read(1) char = __io_like__buffered_read(1) while char == "\n" # Put back the last character. __io_like__unread(char[0]) end rescue Errno::EAGAIN, Errno::EINTR retry if read_ready? end end rescue EOFError, SystemCallError # Reraise the error if there is nothing to return. raise if buffer.empty? end # Increment the number of times this method has returned a "line". self.lineno += 1 buffer end
Sets external and internal encodings and encoding options. Encodings can be specified as a single string with external and internal encoding names separate by a colon, or separately as name strings or <code>Encoding</code> objects. If the final argument is a <code>Hash</code> it will be used to specify conversion options during encoding operations.
TODO: There are no rubyspecs for the option argument
# File lib/io/like-1.9.2.rb, line 558 def set_encoding(enc,arg2=:io_like, arg3=:io_like) if enc.respond_to?(:to_str) ext,int = enc.to_str.split(":", 2) @external_encoding = Encoding.find(ext) @internal_encoding = Encoding.find(int) if int && int != ext elsif Encoding === enc @external_encoding = enc elsif enc.nil? @external_encoding = nil @init_external_encoding = writable? ? nil : Encoding.default_external end if arg2.respond_to?(:to_str) @internal_encoding = Encoding.find(arg2.to_str) elsif Encoding === arg2 @internal_encoding = arg2 if arg2 != @external_encoding elsif Hash === arg2 @encoding_options = arg2 elsif arg2.nil? @internal_encoding = nil @init_internal_encoding = writable? ? nil : Encoding.default_internal end if Hash === arg3 @encoding_options = arg3 end self end
Reads and returns up to length bytes directly from the data stream, bypassing the internal read buffer.
Returns ""
if length is 0
regardless of the status of the data stream. This is for compatibility
with IO#sysread
.
Raises EOFError
if reading begins at the end of the stream.
Raises IOError
if closed? returns true
.
NOTE: Because this method relies on unbuffered_read, it will also raise the same errors and block at the same times as that function.
# File lib/io/like-1.9.2.rb, line 623 def sysread(length, buffer = nil) buffer = buffer.nil? ? '' : buffer.to_str buffer.slice!(0..-1) unless buffer.empty? return buffer if length == 0 raise IOError, 'closed stream' if closed? raise IOError, 'not opened for reading' unless readable? # Flush the internal write buffer for writable, non-duplexed objects. __io_like__buffered_flush if writable? && ! duplexed? buffer << unbuffered_read(length) end
A string argument is forced to 'binary' encoding and then passed on to unread.
The low byte of an integer argument is converted to a binary string and passed on to unread.
# File lib/io/like-1.9.2.rb, line 647 def ungetbyte(string) raise IOError, 'closed stream' if closed? raise IOError, 'not opened for reading' unless readable? return nil if string.nil? if Fixnum === string int = string & 0xFF __io_like__unread(int.chr(Encoding::BINARY)) else __io_like__unread(string.to_str) end nil end
A string arguement is encoded to external_encoding, then forced to 'binary' and passed to unread
An integer argument is treated as a codepoint in the internal_encoding, converted to a character with external_encoding, then forced to 'binary' and passed to unread. TODO: Raise doc bug against MRI as above behaviour is undocumented (although tested by rubyspec)
Raises IOError
if closed? returns true
. Raises
IOError
unless readable? returns true
.
# File lib/io/like-1.9.2.rb, line 677 def ungetc(string) raise IOError, 'closed stream' if closed? raise IOError, 'not opened for reading' unless readable? return nil if string.nil? if string.respond_to?(:to_int) #is expected to be a codepoint in the internal encoding chr = string.to_int.chr(__io_like__internal_encoding) __io_like__unread(chr.encode!(__io_like__external_encoding, __io_like__encoding_options)) else __io_like__unread(string.to_str.encode(__io_like__external_encoding, __io_like__encoding_options)) end nil end
The argument is converted to a string with to_s
, converted to
external_encoding
if not already 'binary', forced to 'binary' and then written to the stream.
The number of bytes written is returned. TODO: rubyspec for encodings on
write.
The entire contents of string are written, blocking as necessary even if the data stream does not block.
Raises IOError
if closed? returns true
. Raises
IOError
unless writable? returns true
.
NOTE: This method ignores Errno::EAGAIN
and
Errno::EINTR
raised by unbuffered_write. Therefore, this
method always blocks if unable to immediately write string
completely. Aside from that exception, this method will also raise the
same errors and block at the same times as unbuffered_write.
# File lib/io/like-1.9.2.rb, line 713 def write(string) super(__io_like__write_encode(string)) end
The argument is converted to a string with to_s
, converted to
external_encoding
if not already 'binary', forced to 'binary' and then written to the stream.
As many bytes as possible are written without blocking or SystemCallError from unbuffered_write is passed directly through to be handled by the caller.
Raises IOError
if closed? returns true
. Raises
IOError
unless writable? returns true
. TODO:
rubyspec to test raises IO::WaitWritable
.
# File lib/io/like-1.9.2.rb, line 731 def write_nonblock(string) begin super(__io_like__write_encode(string)) rescue IO::WaitWritable raise rescue Errno::EAGAIN => ex ex.extend(IO::WaitWritable) raise ex end end