Class: Ramp::Command

Inherits:
Object
  • Object
show all
Defined in:
lib/ramp/command.rb

Overview

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.

Defined Under Namespace

Classes: KeyLenError

Constant Summary collapse

@@ask_seqs =

A Class variable (static attribute) to hold the asks sequences

[]

Class Attribute Summary collapse

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(args) ⇒ Command

Inizilize a new command using the args parameter, The args parameter should conatain the exact keys as the hash that specify in arguments



110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
# 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

Class Attribute Details

.arguments_hashObject

Returns the value of attribute arguments_hash.



32
33
34
# File 'lib/ramp/command.rb', line 32

def arguments_hash
  @arguments_hash
end

.command_nameObject

Returns the value of attribute command_name.



32
33
34
# File 'lib/ramp/command.rb', line 32

def command_name
  @command_name
end

.responses_hashObject

Returns the value of attribute responses_hash.



32
33
34
# File 'lib/ramp/command.rb', line 32

def responses_hash
  @responses_hash
end

Instance Attribute Details

#valuesObject (readonly)

Returns the value of attribute values.



106
107
108
# File 'lib/ramp/command.rb', line 106

def values
  @values
end

Class Method Details

.arguments(args) ⇒ Object

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



45
46
47
# File 'lib/ramp/command.rb', line 45

def arguments args
  @arguments_hash = args
end

.command(name) ⇒ Object

Define the command name. Remote server will recognize this command this this name.

name

Command name



37
38
39
# File 'lib/ramp/command.rb', line 37

def command name
  @command_name = name
end

.loads(data) ⇒ Object

Construct a hash from given data and return it. data should be a packed amp packet.



59
60
61
62
63
64
65
66
67
68
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
94
95
96
97
98
# 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

.responses(args) ⇒ Object

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



53
54
55
# File 'lib/ramp/command.rb', line 53

def responses args
  @responses_hash = args
end

Instance Method Details

#askObject

Return the current command _ask value



167
168
169
# File 'lib/ramp/command.rb', line 167

def ask
  @values[:_ask]
end

#callbackObject

Each subclass may override this method to have a callback when any answer recieved.



178
179
180
# File 'lib/ramp/command.rb', line 178

def callback (*)
  nil
end

#dupObject

Duplicat the current command with new _ask value



172
173
174
# File 'lib/ramp/command.rb', line 172

def dup
  self.class.new @_args
end

#to_aObject



162
163
164
# File 'lib/ramp/command.rb', line 162

def to_a
  @buffer
end

#to_sObject



157
158
159
160
# File 'lib/ramp/command.rb', line 157

def to_s
 
  @buffer.pack("c*")      
end