Class: Sequence::IO
- 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 might not work on windows. 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 inherited from Sequence
Instance Attribute Summary collapse
-
#pos ⇒ Object
readonly
Returns the value of attribute pos.
Instance Method Summary collapse
- #_pos=(newpos) ⇒ Object
- #eof? ⇒ Boolean
-
#initialize(io) ⇒ IO
constructor
A new instance of IO.
- #match(pat) ⇒ Object
- #more_data? ⇒ Boolean
- #read(len) ⇒ Object
- #size ⇒ Object
Constructor Details
#initialize(io) ⇒ IO
Returns a new instance of IO.
25 26 27 28 29 30 31 32 33 |
# File 'lib/sequence/io.rb', line 25 def initialize(io) @io=io @pos=0 @io.fcntl(::Fcntl::F_SETFL, ::Fcntl::O_NONBLOCK) #I gather this won't work on windows.... @fragment='' end |
Instance Attribute Details
#pos ⇒ Object (readonly)
Returns the value of attribute pos.
35 36 37 |
# File 'lib/sequence/io.rb', line 35 def pos @pos end |
Instance Method Details
#_pos=(newpos) ⇒ Object
87 88 89 90 91 92 93 94 95 96 97 98 99 100 |
# File 'lib/sequence/io.rb', line 87 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 @fragment='' tossit=@io.sysread(len) @pos=newpos-(len-tossit.size) end end |
#eof? ⇒ Boolean
57 58 59 60 |
# File 'lib/sequence/io.rb', line 57 def eof?; @fragment.empty? and #need to be at buffer end @io.eof? end |
#match(pat) ⇒ Object
81 82 83 84 85 |
# File 'lib/sequence/io.rb', line 81 def match pat @fragment.size>=scanbuflen or @fragment<<@io.sysread(4096) result=@fragment.match(pat) result if result.begin(0).zero? end |
#more_data? ⇒ Boolean
50 51 52 53 54 55 |
# File 'lib/sequence/io.rb', line 50 def more_data? #refill fragment if needed @fragment=@io.sysread(4096) if @fragment.empty? return !eof end |
#read(len) ⇒ Object
62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 |
# File 'lib/sequence/io.rb', line 62 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=@io.sysread(readlen) result+=@fragment.slice!(0,len) @pos+=result.size result end end |
#size ⇒ Object
43 44 45 46 47 48 |
# File 'lib/sequence/io.rb', line 43 def size #refill fragment if needed @fragment=@io.sysread(4096) if @fragment.empty? return @pos+@fragment.size end |