module IO::Like_1_9_2

Public Class Methods

new(*args) click to toggle source
# 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

Public Instance Methods

binmode → ios click to toggle source
Sets binary mode and returns <code>self</code>.
# 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
binmode? → true or false click to toggle source
Returns true if our external encoding is binary
# File lib/io/like-1.9.2.rb, line 25
def binmode?
  external_encoding == Encoding::BINARY
end
bytes() click to toggle source
Alias for: each_byte
chars() click to toggle source
Alias for: each_char
close_on_exec= → raise NotImplementedError click to toggle source
# File lib/io/like-1.9.2.rb, line 37
def close_on_exec=(coe)
  raise NotImplementedError
end
close_on_exec? → raise NotImplementedError click to toggle source
# File lib/io/like-1.9.2.rb, line 31
def close_on_exec?()
  raise NotImplementedError
end
codepoints() click to toggle source
Alias for: each_codepoint
each(sep = :io_like, limit = :io_like) click to toggle source
Alias for: each_line
each_byte { |char| block } → ios click to toggle source
each_byte → anEnumerator

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
Also aliased as: bytes
each_char { |char| block } → ios click to toggle source
each_char → anEnumerator

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
Also aliased as: chars
each_codepoint { |char| block } → ios click to toggle source
each_codepoint → anEnumerator

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
Also aliased as: codepoints
each_line(sep_string = $/) { |line| block } → ios click to toggle source
each_line(limit) { |line| block } → ios
each_line(sep_string = $/,limit) { |line| block } → ios
each_line(sep_string = $/) → anEnumerator
each_line(limit) { |line| block } → anEnumerator
each_line(sep_string = $/,limit) → anEnumerator

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
Also aliased as: each, lines
external_encoding → encoding click to toggle source

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
getbyte → fixnum or nil click to toggle source

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
gets(sep_string = $/) { |line| block } → ios click to toggle source
gets(limit) { |line| block } → ios
gets(sep_string = $/,limit) { |line| block } → ios
gets(sep_string = $/) → anEnumerator
gets(limit) { |line| block } → anEnumerator
gets(sep_string = $/,limit) → anEnumerator

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
ios-internal_encoding → encoding click to toggle source

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
lines(sep = :io_like, limit = :io_like) click to toggle source
Alias for: each_line
print([obj, ...]) → nil click to toggle source

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.

puts([obj, ...]) → nil click to toggle source

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
read([length[, buffer]]) → nil, buffer, or string click to toggle source

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
read_nonblock(length[, buffer]) → string or buffer click to toggle source

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
readbyte → fixnum click to toggle source

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
readchar → string click to toggle source

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
readline(sep_string = $/) { |line| block } → ios click to toggle source
readline(limit) { |line| block } → ios
readline(sep_string = $/,limit) { |line| block } → ios
readline(sep_string = $/) → anEnumerator
readline(limit) { |line| block } → anEnumerator
readline(sep_string = $/,limit) → anEnumerator

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
set_encoding(ext_enc) → ios click to toggle source
set_encoding("ext_enc:int_enc") → ios
set_encoding(ext_enc,int_enc) → ios
set_encoding("ext_enc:int_enc",opt) → ios
set_encoding(ext_enc,int_enc,opt) → ios
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
sysread(length) → string click to toggle source

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
ungetbyte(string) → nil click to toggle source
ungetbyte(integer) → nil

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
ungetc(string) → nil click to toggle source
ungetc(integer) → nil

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
write(string) → integer click to toggle source

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
write_nonblock(string) → integer click to toggle source

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