Class: IB::Messages::Incoming::AbstractMessage
- Inherits:
-
AbstractMessage
- Object
- AbstractMessage
- IB::Messages::Incoming::AbstractMessage
- Defined in:
- lib/ib/messages/incoming/abstract_message.rb
Direct Known Subclasses
Instance Attribute Summary collapse
-
#socket ⇒ Object
Returns the value of attribute socket.
Attributes inherited from AbstractMessage
Instance Method Summary collapse
- #check_version(actual, expected) ⇒ Object
-
#initialize(source) ⇒ AbstractMessage
constructor
Create incoming message from a given source (IB Socket or data Hash).
-
#load ⇒ Object
Every message loads received message version first Override the load method in your subclass to do actual reading into @data.
-
#load_map(*map) ⇒ Object
Load @data from the socket according to the given data map.
-
#version ⇒ Object
Per message, received messages may have the different versions.
Methods inherited from AbstractMessage
data_map, message_id, #message_id, message_type, #message_type, #to_human, version
Constructor Details
#initialize(source) ⇒ AbstractMessage
Create incoming message from a given source (IB Socket or data Hash)
25 26 27 28 29 30 31 32 33 34 |
# File 'lib/ib/messages/incoming/abstract_message.rb', line 25 def initialize source @created_at = Time.now if source.is_a?(Hash) # Source is a @data Hash @data = source else # Source is a Socket @socket = source @data = Hash.new self.load end end |
Instance Attribute Details
#socket ⇒ Object
Returns the value of attribute socket.
12 13 14 |
# File 'lib/ib/messages/incoming/abstract_message.rb', line 12 def socket @socket end |
Instance Method Details
#check_version(actual, expected) ⇒ Object
18 19 20 21 22 |
# File 'lib/ib/messages/incoming/abstract_message.rb', line 18 def check_version actual, expected unless actual == expected || expected.is_a?(Array) && expected.include?(actual) error "Unsupported version #{actual} received, expected #{expected}" end end |
#load ⇒ Object
Every message loads received message version first Override the load method in your subclass to do actual reading into @data.
38 39 40 41 42 43 44 45 46 47 48 49 50 51 |
# File 'lib/ib/messages/incoming/abstract_message.rb', line 38 def load if socket @data[:version] = socket.read_int check_version @data[:version], self.class.version load_map *self.class.data_map else raise "Unable to load, no socket" end rescue => e error "Reading #{self.class}: #{e.class}: #{e.}", :load, e.backtrace end |
#load_map(*map) ⇒ Object
Load @data from the socket according to the given data map.
map is a series of Arrays in the format of
[ :name, :type ], [ :group, :name, :type]
type identifiers must have a corresponding read_type method on socket (read_int, etc.). group is used to lump together aggregates, such as Contract or Order fields
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 |
# File 'lib/ib/messages/incoming/abstract_message.rb', line 59 def load_map(*map) map.each do |instruction| # We determine the function of the first element head = instruction.first case head when Integer # >= Version condition: [ min_version, [map]] load_map *instruction.drop(1) if version >= head when Proc # Callable condition: [ condition, [map]] load_map *instruction.drop(1) if head.call when true # Pre-condition already succeeded! load_map *instruction.drop(1) when nil, false # Pre-condition already failed! Do nothing... when Symbol # Normal map group, name, type, block = if instruction[2].nil? || instruction[2].is_a?(Proc) [nil] + instruction # No group, [ :name, :type, (:block) ] else instruction # [ :group, :name, :type, (:block)] end data = socket.__send__("read_#{type}", &block) if group @data[group] ||= {} @data[group][name] = data else @data[name] = data end else error "Unrecognized instruction #{instruction}" end end end |
#version ⇒ Object
Per message, received messages may have the different versions
14 15 16 |
# File 'lib/ib/messages/incoming/abstract_message.rb', line 14 def version # Per message, received messages may have the different versions @data[:version] end |