|
|
|
class Stdout
|
|
|
|
include Enumerable
|
|
|
|
|
|
|
|
class SingleFile < self
|
|
|
|
attr_reader :path
|
|
|
|
|
|
|
|
def initialize(path)
|
|
|
|
@path = path
|
|
|
|
end
|
|
|
|
|
|
|
|
def each(&blk)
|
|
|
|
File.open(path, 'r') do |f|
|
|
|
|
Oj.sc_parse(FrameIterator.new(blk), f)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
class FrameIterator < ::Oj::ScHandler
|
|
|
|
|
|
|
|
def initialize(callback)
|
|
|
|
@callback = callback
|
|
|
|
end
|
|
|
|
|
|
|
|
def array_start
|
|
|
|
if @top # we're already inside top level array
|
|
|
|
[] # <- this will hold pair [delay, data]
|
|
|
|
else
|
|
|
|
@top = []
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
def array_append(a, v)
|
|
|
|
if a.equal?(@top)
|
|
|
|
@callback.call(*v)
|
|
|
|
else
|
|
|
|
a << v
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
end
|
|
|
|
|
|
|
|
end
|
|
|
|
|
|
|
|
class MultiFile < self
|
|
|
|
attr_reader :data_path, :timing_path
|
|
|
|
|
|
|
|
def initialize(data_path, timing_path)
|
|
|
|
@data_path = data_path
|
|
|
|
@timing_path = timing_path
|
|
|
|
end
|
|
|
|
|
|
|
|
def each
|
|
|
|
File.open(data_path, 'rb') do |file|
|
|
|
|
File.foreach(timing_path) do |line|
|
|
|
|
yield(*delay_and_data_for_line(file, line))
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
private
|
|
|
|
|
|
|
|
def delay_and_data_for_line(file, line)
|
|
|
|
delay, size = TimingParser.parse_line(line)
|
|
|
|
data = file.read(size).to_s.force_encoding('utf-8')
|
|
|
|
|
|
|
|
[delay, data]
|
|
|
|
end
|
|
|
|
|
|
|
|
end
|
|
|
|
|
|
|
|
class Buffered < self
|
|
|
|
MIN_FRAME_LENGTH = 1.0 / 60
|
|
|
|
|
|
|
|
attr_reader :stdout
|
|
|
|
|
|
|
|
def initialize(stdout)
|
|
|
|
@stdout = stdout
|
|
|
|
end
|
|
|
|
|
|
|
|
def each
|
|
|
|
buffered_delay, buffered_data = 0.0, []
|
|
|
|
|
|
|
|
stdout.each do |delay, data|
|
|
|
|
if buffered_delay + delay < MIN_FRAME_LENGTH || buffered_data.empty?
|
|
|
|
buffered_delay += delay
|
|
|
|
buffered_data << data
|
|
|
|
else
|
|
|
|
yield(buffered_delay, buffered_data.join)
|
|
|
|
buffered_delay = delay
|
|
|
|
buffered_data = [data]
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
yield(buffered_delay, buffered_data.join) unless buffered_data.empty?
|
|
|
|
end
|
|
|
|
|
|
|
|
end
|
|
|
|
|
|
|
|
end
|