Class: Sequence::IO

Inherits:
Sequence show all
Includes:
StringLike
Defined in:
lib/sequence/io.rb

Overview

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.

Constant Summary

Constants included from StringLike

StringLike::FFS_4BITTABLE

Constants inherited from Sequence

SubSequence, VERSION

Instance Attribute Summary collapse

Attributes inherited from Sequence

#last_match, #maxmatchlen

Instance Method Summary collapse

Methods included from StringLike

#_anchor, #data_class, #ffs, #fixup_match_result, #fns, #group_anchors, #index, #like, #match_fast, #matchback, #new_data, #push, #read_til_charset, #rindex, #scan, #scan_until, #scanback, #scanback_until, #unshift

Methods inherited from Sequence

#+, #-, #<<, [], #[], #[]=, #_adjust_pos_on_change, #_default_maxmatchlen, #_delete_position, #_normalize_pos, #_parse_slice_args, #all_data, #append, #begin, #begin!, #check, #check_until, #checkback, #checkback_until, #close, #closed?, #delete, #each, #empty?, #end, #end!, #exist?, #existback?, #first, #goto, #holding, #holding!, #holding?, #holding_position, #holding_position!, #holding_position?, #insert, #last, #length, #match?, #matchback?, #modify, #move, #move!, #nearbegin, #nearend, #new, #notify_change, #on_change_notify, #original__new, #overwrite, #pop, #pos=, #pos?, #position, #position=, #position?, #pred, #prepend, #prop, #read!, #read1, #readahead, #readahead1, #readback, #readback1, #readbehind, #readbehind1, #rest_size, #reversed, #shift, #skip, #skip_literal, #skip_until, #skip_until_literal, #skipback, #skipback_until, #slice, #slice!, #slice1, #slice1!, #subseq, #succ, #to_sequence, #was_data?, #write, #writeahead, #writeback, #writebehind

Constructor Details

#initialize(io) ⇒ IO

Returns a new instance of IO.



26
27
28
29
30
# File 'lib/sequence/io.rb', line 26

def initialize(io)
  @io=io
  @pos=0
  @fragment=''
end

Instance Attribute Details

#posObject (readonly)

Returns the value of attribute pos.



32
33
34
# File 'lib/sequence/io.rb', line 32

def pos
  @pos
end

Instance Method Details

#_pos=(newpos) ⇒ Object



96
97
98
99
100
101
102
103
104
105
106
107
108
109
# 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?Boolean

Returns:

  • (Boolean)


54
55
56
57
# File 'lib/sequence/io.rb', line 54

def eof?; 
  @fragment.empty? and #need to be at buffer end
    @io.eof?  
end

#match(pat) ⇒ Object



86
87
88
89
90
91
92
93
94
# 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?Boolean

Returns:

  • (Boolean)


47
48
49
50
51
52
# 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) ⇒ Object



67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
# 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) ⇒ Object



59
60
61
62
63
64
65
# File 'lib/sequence/io.rb', line 59

def readchunk len
  @fragment=@io.read_nonblock(len)
rescue IOError, EOFError
  raise
rescue Exception
  @fragment=''
end

#sizeObject



40
41
42
43
44
45
# File 'lib/sequence/io.rb', line 40

def size
  #refill fragment if needed
  @fragment=readchunk(4096) if @fragment.empty?

  return @pos+@fragment.size 
end