class Andromeda::Cmd::Cmd
Attributes
cmd[R]
data[R]
time[R]
Public Class Methods
from_json(json)
click to toggle source
# File lib/andromeda/cmd.rb, line 42 def self.from_json(json) Cmd.new json['cmd'].to_sym, json['data'], (json['time'] rescue nil) end
new(cmd, data = {}, cmd_time = nil)
click to toggle source
# File lib/andromeda/cmd.rb, line 10 def initialize(cmd, data = {}, cmd_time = nil) raise ArgumentError unless cmd.kind_of?(Symbol) @cmd = cmd @data = data @time = if cmd_time then cmd_time else Time.now.to_i end @comment = nil end
new_input(cmd, data = {}, cmd_time = nil)
click to toggle source
# File lib/andromeda/cmd.rb, line 37 def self.new_input(cmd, data = {}, cmd_time = nil) inner = Cmd.new cmd, data, cmd_time Cmd.new :input, inner, cmd_time end
Public Instance Methods
as_json()
click to toggle source
# File lib/andromeda/cmd.rb, line 23 def as_json h = { cmd: cmd, data: (data.as_json rescue data), time: time } c = @comment h[:comment] = c if c h end
comment()
click to toggle source
# File lib/andromeda/cmd.rb, line 18 def comment ; @comment || '' end
comment=(str = nil)
click to toggle source
# File lib/andromeda/cmd.rb, line 19 def comment=(str = nil) ; @comment = str end
if_cmd(sym) { |data else seld end end| ... }
click to toggle source
# File lib/andromeda/cmd.rb, line 21 def if_cmd(sym) ; if sym == cmd then yield data else seld end end def as_json h = { cmd: cmd, data: (data.as_json rescue data), time: time } c = @comment h[:comment] = c if c h end def to_s ; as_json.to_json end def with_comment(str = nil) @comment = str self end def self.new_input(cmd, data = {}, cmd_time = nil) inner = Cmd.new cmd, data, cmd_time Cmd.new :input, inner, cmd_time end def self.from_json(json) Cmd.new json['cmd'].to_sym, json['data'], (json['time'] rescue nil) end end class FileCmdPlan < Kit::InlineKeyRouter attr_reader :path attr_reader :mode attr_reader :file spot_meth :open spot_meth :sync spot_meth :close spot_meth :input signal_spot :open signal_spot :close signal_spot :sync def data_map(name, data) if data.is_a?(Cmd) then data else Cmd.new(data) end end def data_key(name, data) ; data.cmd end def data_val(name, data) ; data.data end def data_tag(name, key, val, tags_in) tags_out = super if name == :input tags_out[:time] = val.time tags_out[:comment] = val.comment end tags_out end def on_open(key, val) if @file signal_error ArgumentError.new("associated file already open") else @path = val[:path] if val[:path] @mode = val[:mode] if val[:mode] @mode ||= init_mode @file = File.open @path, @mode end end def on_input(key, val) exit << val if exit end def on_sync(key, val) f = @file ; sync_file f if f end def on_close(key, val) if @file begin close_file(@file) ensure @file = nil end else signal_error ArgumentError.new("associated file not open") end end protected def close_file(f) begin sync_file f ensure f.close end end def sync_file(f) ; end end class Writer < FileCmdPlan def init_mode ; 'w' end def on_input(key, val) signal_error ArgumentError.new("associated filed not open") unless file cmd = val.cmd raise ArgumentError, "invalid cmd" unless cmd.kind_of?(Symbol) data = val.data str = if data then data.to_json else '' end len = str.length + 1 tim = val.time if val.time tim = Time.now unless tim tim = tim.to_i unless tim.kind_of?(Fixnum) new_str = '' str.each_line { |line| new_str << "... #{line}\n" } str = nil len = new_str.length val = tags[:comment] val.each_line { |line| file.write "\# #{line}\n" } if val file.write "<<< ANDROMEDA START :#{cmd} TIME #{tim} LEN #{len} >>>\n" file.write new_str file.write "<<< ANDROMEDA END :#{cmd} >>>\n" super key, val end protected def sync_file(f) f.sync f.fsync rescue nil end end class Reader < Kit::FileReader attr_reader :start_matcher, :end_matcher, :comment_matcher, :line_matcher def initialize(config = {}) super config @start_matcher = /<<< ANDROMEDA START :(\w+) TIME (\d+) LEN (\d+) >>>/ @end_matcher = /<<< ANDROMEDA END :(\w+) >>>/ @comment_matcher = /#(.*)/ # remember to change the offset for :line, too whenever you change this @line_matcher = /... (.*)/ end def match_line(state, line) m = @start_matcher.match line return yield :start, state, ({ cmd: m[1].to_sym, tim: m[2].to_i, len: m[3].to_i }) if m m = @end_matcher.match line return yield :end, state, m[1].to_sym if m m = @comment_matcher.match line return yield :comment, state, m[1] if m m = @line_matcher.match line return yield :line, state, m[1] if m yield :garbage, state, line end def on_enter(key, val) super key, val do |file| fst = tags[:first] lst = tags[:last] state = { :comment => true, :start => true, :cont => true } while (line = file.gets) && state[:cont] line = line.chomp match_line(state, line) do |token, state, parts| signal_error ArgumentError.new("Skipping unexpected token #{token} in line '#{line}' (state: #{state})") unless state[token] case token when :comment if state[:comment_str] then state[:comment_str] << parts else state[:comment_str] = parts end when :start state.delete :comment state.delete :start state[:line] = true state[:end] = true parts[:data] = '' state[:len] = 0 state[:cur] = parts parts[:comment] = state[:comment_str] state.delete :comment_str when :line state[:len] += parts.length + 5 state[:cur][:data] << "#{parts}\n" when :end state.delete :line state.delete :end state[:start] = true state[:comment] = true cur = state[:cur] data = cur[:data] signal_error ArgumentError.new("Start (#{cur[:cmd]}) and end (#{parts})cmd mismatch") unless cur[:cmd] == parts signal_error ArgumentError.new("Length mismatch (expected: #{cur[:len]}, found: #{state[:len]})") unless cur[:len] == state[:len] exit << cur if exit state[:cont] = false unless file.pos <= lst else signal_error ArgumentError.new("Garbage encountered (line: '#{line}')") return end end end end end end class Parser < Plan def on_enter(key, val) data = val[:data].chomp data = JSON::parse(data) cmd = Cmd.new val[:cmd], data, val[:time] rem = val[:comment] rescue nil cmd.with_comment rem if rem exit << cmd if cmd end end end
to_s()
click to toggle source
# File lib/andromeda/cmd.rb, line 30 def to_s ; as_json.to_json end
with_comment(str = nil)
click to toggle source
# File lib/andromeda/cmd.rb, line 32 def with_comment(str = nil) @comment = str self end