Class: LCR::LineReader

Inherits:
Object
  • Object
show all
Defined in:
lib/long-command-runner/line_reader.rb

Overview

This class aims to read over a groupe of stream and triger a block when new lines are read on one of them.

Constant Summary collapse

LINE_END =

What is considered as a return line

/[\n\r][\n\r]?/.freeze
MAX_READ_CHAR =

How must characters to read at a time.

1_000_000

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(streams) {|io0_new_line, io1_new_line, ...| ... } ⇒ LineReader

Initializer takes an array of IO streams. You can optionaly pass a block that will be called at each new line.

The block will be called with as must as IO stream there is to treat.

Yields:

  • (io0_new_line, io1_new_line, ...)

    Will be called each time a new line is read.

Yield Parameters:

  • io0_new_line (String | nil)

    The string read as a new line without the endline characters. It will be nil if the new line detected is not on the first IO given in the initializer.

  • io1io1_new_line (String | nil)

    Same as previous param except it is for IO stream at index 1 given to the initializer.

Yield Returns:

  • (void)

    It is ignored.



25
26
27
28
29
# File 'lib/long-command-runner/line_reader.rb', line 25

def initialize(streams, &on_input)
  @streams = streams
  @streams_lines = Array.new(streams.length) { [] }
  @on_input = on_input
end

Instance Attribute Details

#streamsArray<IO> (readonly)

access to the array of streams. Be carefull accessing these, because you may prevent line_reader to run correctly.

Returns:

  • (Array<IO>)


34
35
36
# File 'lib/long-command-runner/line_reader.rb', line 34

def streams
  @streams
end

Instance Method Details

#[](index) ⇒ Array<String>

Access to the lines of a stream

Parameters:

  • index (Integer)

    The index of the stream in the order given at the initialization of this object.

Returns:

  • (Array<String>)


75
76
77
# File 'lib/long-command-runner/line_reader.rb', line 75

def [](index)
  @streams_lines[index].dup
end

#eof?Boolean

Are all the streams reached End-Of-File ?

Returns:

  • (Boolean)


59
60
61
62
63
64
65
66
67
# File 'lib/long-command-runner/line_reader.rb', line 59

def eof?
  @streams.all? do |stream|
    begin
      Timeout.timeout(0.001) { stream.eof? }
    rescue Timeout::Error
      false
    end
  end
end

#read { ... } ⇒ Array<Integer>

Blocking method to read on the streams (you may call it in a dedicated thread).

It will stop when eof is reach. Never the less it may not be the end.

Block is optional:

Yields:

  • Will be called just before waiting on the select(streams)

Yield Returns:

  • (Float | Integer | nil)

    a value for the timeout on the next select call. A nil value for no timeout (which is default when no block is provided).

Returns:

  • (Array<Integer>)

    the number of lines read on each streams



45
46
47
48
49
50
51
52
53
54
# File 'lib/long-command-runner/line_reader.rb', line 45

def read
  buffers = Array.new(@streams.length) { nil }
  loop do
    # puts "read - loop"
    timeout = block_given? ? yield : nil
    break if internal_read(buffers, timeout)
  end
  # puts "read - quitting: #{@streams_lines.map(&:length)}"
  @streams_lines.map(&:length)
end