class Ramp::Command
Base class for an AMP protocol command. Any user command should subclassed from this class and define a command name, arguments, reponses and any exceptions or callback method if needed.
Attributes
Public Class Methods
Defines all the arguments of the command. arguments should define in a hash and each one value should be a class that have both to_s instance method and to_o class method.
- args
-
is the hash that contains the arguments defination
# File lib/ramp/command.rb, line 45 def arguments args @arguments_hash = args end
Define the command name. Remote server will recognize this command this this name.
- name
-
Command
name
# File lib/ramp/command.rb, line 37 def command name @command_name = name end
Construct a hash from given data and return it. data should be a packed amp packet.
# File lib/ramp/command.rb, line 59 def loads(data) buffer = data.to_s.bytes.to_a pos = 0 result = {} while 1 do # Parse the next key length key_length = 0 buffer[pos..pos + 1].each {|x| key_length += x} if key_length > 255 raise TypeError, "malform packet." end if key_length == 0 # key length of 0 means end of package. break end pos += 2 # Read the key key = buffer[pos..pos + key_length - 1].pack("c*") # Parse next value length pos += key_length value_length = 0 buffer[pos..pos + 1].each {|x| value_length += x} # Read the value pos += 2 value = buffer[pos..pos + value_length - 1].pack("c*") pos += value_length result[key.to_sym] = value end result end
Inizilize a new command using the args parameter, The args parameter should conatain the exact keys as the hash that specify in arguments
# File lib/ramp/command.rb, line 110 def initialize (args) # Initialize an object with provided values for fields defined in # @arguments using argument class method @values = {} @buffer = [] @_args = args kwargs = Hash[args.map{|k, v|[k.to_sym, v]}] if kwargs.include? :_ask or kwargs.include? :_command raise ArgumentError, "':_ask' and ':_command' should not be in arguments" end kwargs.each do |key, value| # Check for key validation if not self.class.arguments_hash.include? key raise ArgumentError, "'#{key}' is not defined in '#{self.class}'." end # Construct the values ivar @values[key.to_sym] = self.class.arguments_hash[key.to_sym].new value end # Build a AMP packet data from kwargs hash for more information about # amp protocol structure take a look at: # http://www.amp-protocol.net @values[:_command] = self.class.command_name while 1 do # TODO: is it safe in logic ? ask = rand(999999) if not @@ask_seqs.include? ask @@ask_seqs << ask break end end @values[:_ask] = ask # Generate the packet data and store it into @buffer generate_packet end
Defines all the possible responses of the command. Responses should define in a hash and each one value should be a class that have both to_s instance method and to_o class method.
- args
-
is the hash that contains the reponses defination
# File lib/ramp/command.rb, line 53 def responses args @responses_hash = args end
Public Instance Methods
Return the current command _ask value
# File lib/ramp/command.rb, line 167 def ask @values[:_ask] end
Each subclass may override this method to have a callback when any answer recieved.
# File lib/ramp/command.rb, line 178 def callback (*) nil end
Duplicat the current command with new _ask value
# File lib/ramp/command.rb, line 172 def dup self.class.new @_args end
# File lib/ramp/command.rb, line 162 def to_a @buffer end
# File lib/ramp/command.rb, line 157 def to_s @buffer.pack("c*") end
Private Instance Methods
# File lib/ramp/command.rb, line 193 def generate_packet() @values.each do |key, value| if key.length > 255 raise KeyLenError, "AMP keys should have 255 byte max kength" end [0, key.to_s.bytes.to_a.length].each {|x| @buffer << x} key.to_s.bytes.to_a.each {|x| @buffer << x} value_lenght = split_bytes "%04x" % value.to_s.bytes.to_a.length.to_s(16) @buffer << value_lenght[0].to_i @buffer << value_lenght[1].to_i value.to_s.bytes.to_a.each {|x| @buffer << x} end [0x00, 0x00].each {|x| @buffer << x} end
Private definations —————————————
# File lib/ramp/command.rb, line 189 def split_bytes (hex) hex.each_char.each_slice(2).map {|x| x.join} end