Class: IB::RawMessageParser
Overview
Convert data passed in from a TCP socket stream, and convert into raw messages. The messages
Constant Summary collapse
- HEADER_LNGTH =
4
Instance Method Summary collapse
- #append_new_data ⇒ Object
- #each ⇒ Object
- #enough_data? ⇒ Boolean
-
#grab_message(length) ⇒ Object
extract message and convert to an array split by null characters.
-
#initialize(socket) ⇒ RawMessageParser
constructor
A new instance of RawMessageParser.
- #length_data? ⇒ Boolean
- #next_msg_length ⇒ Object
- #parse_message(raw, length) ⇒ Object
- #remove_message ⇒ Object
- #validate_data_header(length) ⇒ Object
- #validate_message_footer(msg, length) ⇒ Object
Constructor Details
#initialize(socket) ⇒ RawMessageParser
Returns a new instance of RawMessageParser.
8 9 10 11 |
# File 'lib/ib/raw_message.rb', line 8 def initialize(socket) @socket = socket @data = String.new end |
Instance Method Details
#append_new_data ⇒ Object
69 70 71 |
# File 'lib/ib/raw_message.rb', line 69 def append_new_data @data += @socket.recv_from end |
#each ⇒ Object
13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
# File 'lib/ib/raw_message.rb', line 13 def each while true append_new_data next unless length_data? next unless enough_data? length = next_msg_length validate_data_header(length) raw = (length) (raw, length) msg = (raw, length) yield msg end end |
#enough_data? ⇒ Boolean
51 52 53 54 55 56 |
# File 'lib/ib/raw_message.rb', line 51 def enough_data? actual_lngth = next_msg_length + HEADER_LNGTH echo 'too little data' if next_msg_length.nil? return false if next_msg_length.nil? @data.bytesize >= actual_lngth end |
#grab_message(length) ⇒ Object
extract message and convert to an array split by null characters.
33 34 35 |
# File 'lib/ib/raw_message.rb', line 33 def (length) @data.byteslice(HEADER_LNGTH, length) end |
#length_data? ⇒ Boolean
58 59 60 |
# File 'lib/ib/raw_message.rb', line 58 def length_data? @data.bytesize > HEADER_LNGTH end |
#next_msg_length ⇒ Object
62 63 64 65 66 67 |
# File 'lib/ib/raw_message.rb', line 62 def next_msg_length #can't check length if first 4 bytes don't exist length = @data.byteslice(0..3).unpack1('N') return 0 if length.nil? length end |
#parse_message(raw, length) ⇒ Object
37 38 39 |
# File 'lib/ib/raw_message.rb', line 37 def (raw, length) raw.unpack1("A#{length}").split("\0") end |
#remove_message ⇒ Object
41 42 43 44 45 46 47 48 49 |
# File 'lib/ib/raw_message.rb', line 41 def length = next_msg_length leftovers = @data.byteslice(length + HEADER_LNGTH..-1) @data = if leftovers.nil? String.new else leftovers end end |
#validate_data_header(length) ⇒ Object
80 81 82 83 |
# File 'lib/ib/raw_message.rb', line 80 def validate_data_header(length) return true if length <= 5000 raise 'Message is longer than sane max length' end |
#validate_message_footer(msg, length) ⇒ Object
73 74 75 76 77 78 |
# File 'lib/ib/raw_message.rb', line 73 def (msg,length) last = msg.bytesize last_byte = msg.byteslice(last-1,last) raise 'Could not validate last byte' if last_byte.nil? raise "Message has an invalid last byte. expecting \0, received: #{last_byte}" if last_byte != "\0" end |