class LogParser::Buffer

Log buffers provide line after line from a given source, and only store as many lines as necessary:

* Read lines from `log` lazily, i.e. only if {find_index} or {[]} are called.
* Drop lines that are no longer needed, i.e. when {forward} is called.

Public Class Methods

new(log) click to toggle source

Creates a new buffer that reads lines from the given source.

@param [Array<String>,IO,StringIO] log

Where to read log lines from. Can be either an array of `String`,
an `IO` (e.g. `STDIN`), or a `StringIO`.
# File lib/log_parser/buffer.rb, line 15
def initialize(log)
  @buffer = []
  @stream = nil

  @buffer = log if log.is_a?(Array)
  @stream = log if log.is_a?(IO) || log.is_a?(StringIO)
end

Public Instance Methods

[](offset, length = nil) click to toggle source

Retrieves the next `length` many log lines starting from index `offset`.

@param [Integer] offset

The first index to retrieve.
*Note:* Indices are relative to the start of the buffer, _not_ the start of the log!

@param [Integer] length

The number of elements to retrieve.

@return [String,Array<String>]

If `length` is set, returns the array of lines with indices in `(offset..offset+length-1)`.
Otherwise, returns the line with index `offset`.
# File lib/log_parser/buffer.rb, line 84
def [](offset, length = nil)
  base_length = length || 1
  while offset + base_length > @buffer.size
    return (length.nil? ? nil : @buffer[offset, @buffer.size]) if stream_is_done?
    @buffer.push(@stream.readline.rstrip)
  end

  length.nil? ? @buffer[offset] : @buffer[offset, length]
end
buffer_size() click to toggle source

The current size of this buffer, that is the number of lines currently stored.

@return [Integer]

# File lib/log_parser/buffer.rb, line 33
def buffer_size
  @buffer.size
end
close() click to toggle source

Closes the `IO` this buffer reads from, if any.

@return [void]

# File lib/log_parser/buffer.rb, line 115
def close
  @stream.close unless @stream.nil? || @stream.closed?
end
empty?() click to toggle source

Determines whether there are more lines in this log (buffer).

@return [true,false]

# File lib/log_parser/buffer.rb, line 26
def empty?
  @buffer.empty? && stream_is_done?
end
find_index(starting_from = 0) { |element| ... } click to toggle source

Finds the first index of an element that fulfills a predicate.

@param [Integer] starting_from

The first index to check. That is, indices `(0..starting_from - 1)` are skipped.
*Note:* Indices are relative to the start of the buffer, _not_ the start of the log!

@yield Invokes a block as predicate over lines. @yieldparam [String] line

A line of the log.

@yieldreturn [true,false]

`true` if (and only if) `line` fulfills the predicate.

@return [Integer, nil]

The first index of an element that fulfills the predicate, if any;
otherwise, `nil`.
# File lib/log_parser/buffer.rb, line 61
def find_index(starting_from = 0)
  index = starting_from
  element = self[index]

  until element.nil?
    return index if yield(element)
    index += 1
    element = self[index]
  end

  nil
end
first() click to toggle source

The first available line, if any.

Note: Will read from the source if necessary.

@return [String,nil]

# File lib/log_parser/buffer.rb, line 42
def first
  self[0]
end
forward(offset = 1) click to toggle source

Moves the front of this buffer forwards by `offset` elements.

That is, the following code returns `true`: “`ruby before = buffer buffer.forward after = buffer.first before == after “`

@param [Integer] offset

The number of lines to drop.

@return [void]

# File lib/log_parser/buffer.rb, line 107
def forward(offset = 1)
  self[offset]
  @buffer.slice!(0, offset)
end

Private Instance Methods

stream_is_done?() click to toggle source

False if (and only if) this buffer reads from an `IO`, that `IO` is not closed, and has not yet reached the end.

@return [true,false]

# File lib/log_parser/buffer.rb, line 125
def stream_is_done?
  @stream.nil? || @stream.closed? || @stream.eof?
end