class Sequence::IO

external iterator over data in an general IO object (a pipe, console, socket, serial port, or the like). For Files, please use Sequence::File instead, as it is more capable. This Sequence class can only go forward, and can only read, it cannot write to the data stream. Thus many of Sequence's usual methods will not work with this class. At the moment, this even includes scan and friends, tho I will try to make those work somewhat. Also note that this is one of the few Sequence classes that might return less that the amount asked for in a read, even if not at the end of file. Due to use of nonblocking io, this only works on windows when wrapping a socket, not a named pipe, anonymous pipe, or device. The value of size in this sequence continually increases over its lifetime, and it isn't possible to know the final value beforehand. Likewise, eof? may return false even tho it's destined to return true at the same position. This is because the 'other end' may not have closed the IO, even if there's no more data to send.

if you need to be able to scan forward and back, consider wrapping the IO in a Buffered or Shifting Sequence.

Attributes

pos[R]

Public Class Methods

new(io) click to toggle source
# File lib/sequence/io.rb, line 26
def initialize(io)
  @io=io
  @pos=0
  @fragment=''
end

Public Instance Methods

_pos=(newpos) click to toggle source
# File lib/sequence/io.rb, line 96
def _pos=newpos
  newpos<pos and raise ArgumentError
  if newpos<=@pos+@fragment.size
    len=newpos-@pos
    @fragment.slice!(0,len)
    @pos=newpos
  else
    len=newpos-(@pos+@fragment.size)
    len > 10*4096 and raise ArgumentError
    tossit=readchunk(len)
    @fragment=''
    @pos=newpos-(len-tossit.size)
  end
end
eof?() click to toggle source
# File lib/sequence/io.rb, line 54
def eof?; 
  @fragment.empty? and #need to be at buffer end
    @io.eof?  
end
match(pat) click to toggle source
# File lib/sequence/io.rb, line 86
def match pat
  unless @fragment.size>=scanbuflen 
    frag=@fragment
    frag<<readchunk([4096,scanbuflen].max)
  end
  @fragment=frag
  result=@fragment.match(pat)
  result if result.begin(0).zero?
end
more_data?() click to toggle source
# File lib/sequence/io.rb, line 47
def more_data?
  #refill fragment if needed
  @fragment=readchunk(4096) if @fragment.empty?
  
  return !eof 
end
read(len) click to toggle source
# File lib/sequence/io.rb, line 67
def read len
  if len<= @fragment.size
    @pos+=len
    @fragment.slice! 0,len
  else
    result=@fragment
    len-=@fragment.size
    
    readlen=len
    rem=len%4096
    rem.nonzero? and readlen+=4096-rem
    
    @fragment=readchunk(readlen) 
    result+=@fragment.slice!(0,len)
    @pos+=result.size
    result
  end
end
readchunk(len) click to toggle source
# File lib/sequence/io.rb, line 59
def readchunk len
  @fragment=@io.read_nonblock(len)
rescue IOError, EOFError
  raise
rescue Exception
  @fragment=''
end
size() click to toggle source
# File lib/sequence/io.rb, line 40
def size
  #refill fragment if needed
  @fragment=readchunk(4096) if @fragment.empty?

  return @pos+@fragment.size 
end