Class: ScripTTY::Util::Transcript::Reader
- Inherits:
-
Object
- Object
- ScripTTY::Util::Transcript::Reader
- Defined in:
- lib/scriptty/util/transcript/reader.rb
Overview
Reader for transcript files
Example
File.open("transcript", "r") do |file|
reader = ScripTTY::Util::Transcript::Reader.new
file.each_line do |line|
, type, args = reader.parse_line(line)
# ... do stuff here ...
end
end
Constant Summary collapse
- OP_TYPES =
{ "Copen" => :client_open, # client connection opened "Sopen" => :server_open, # server connection opened "C" => :from_client, # bytes from client "S" => :from_server, # bytes from server "*" => :info, # informational message "Sx" => :server_close, # server closed connection "Cx" => :client_close, # server closed connection "Sp" => :server_parsed, # parsed escape sequence from server "Cp" => :client_parsed, # parsed escape sequence from client "EXC" => :exception_head, # Exception header - exception class & message "EX+" => :exception_backtrace, # Exception backtrace - single line of a backtrace }
Instance Method Summary collapse
- #close ⇒ Object
-
#initialize(io = nil) ⇒ Reader
constructor
A new instance of Reader.
- #next_entry ⇒ Object
- #parse_line(line) ⇒ Object
Constructor Details
#initialize(io = nil) ⇒ Reader
Returns a new instance of Reader.
52 53 54 55 |
# File 'lib/scriptty/util/transcript/reader.rb', line 52 def initialize(io=nil) @current_line = 0 @io = io end |
Instance Method Details
#close ⇒ Object
65 66 67 |
# File 'lib/scriptty/util/transcript/reader.rb', line 65 def close @io.close if @io end |
#next_entry ⇒ Object
57 58 59 60 61 62 63 |
# File 'lib/scriptty/util/transcript/reader.rb', line 57 def next_entry raise TypeError.new("no I/O object associated with this reader") unless @io return nil if @io.eof? line = @io.readline return nil unless line parse_line(line) end |
#parse_line(line) ⇒ Object
69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 |
# File 'lib/scriptty/util/transcript/reader.rb', line 69 def parse_line(line) @current_line += 1 unless line =~ /^\[([\d]+(?:\.[\d]+)?)\] (\S+)((?: "(?:[\x20-\x21\x23-\x5b\x5d-\x7e]|\\[0-3][0-7][0-7])*")*)$/ raise ArgumentError.new("line #{@current_line}: Unable to parse basic structure") end , op, raw_args = [$1, $2, $3] = .to_f args = [] s = StringScanner.new(raw_args.strip) until s.eos? m = s.scan(/ +/) # skip whitespace between args next if m m = s.scan /"[^"]*"/ raise ArgumentError.new("line #{@current_line}: Unable to parse arguments") unless m arg = m[1..-2].gsub(/\\[0-7][0-7][0-7]/) { |m| [m[1..-1].to_i(8)].pack("C*") } # strip quotes and unescape string args << arg end type = OP_TYPES[op] raise ArgumentError.new("line #{@current_line}: Unrecognized opcode #{op}") unless type if [:client_open, :server_open].include?(type) raise ArgumentError.new("line #{@current_line}: Bad port #{args[1].inspect}") unless args[1] =~ /\A(\d+)\Z/m args[1] = args[1].to_i end [, type, args] end |