Class: Mikrotik::Protocol::Parser
- Inherits:
-
Object
- Object
- Mikrotik::Protocol::Parser
- Defined in:
- lib/mikrotik/protocol/parser.rb
Overview
Responsible for extracting replies from API sentence data
Constant Summary
- PAIR =
/^(.+)=(.+)$/
Instance Method Summary (collapse)
-
- (Object) <<(data)
Adds data to the parser buffer and runs the parser.
- - (Object) bytes(bits)
- - (Object) get_length
-
- (Object) get_length_size
Indentifies the size of the length field in bits.
- - (Object) get_sentence
- - (Object) get_word
-
- (Parser) initialize
constructor
A new instance of Parser.
-
- (Object) reset!
Discards the sentence currently being parsed.
-
- (Object) sentence {|Mikrotik::Protocol::Sentence| ... }
Fired when the parser extracts a complete API sentence.
Constructor Details
- (Parser) initialize
A new instance of Parser
9 10 11 12 13 |
# File 'lib/mikrotik/protocol/parser.rb', line 9 def initialize @data = '' @data.force_encoding(Encoding::BINARY) if RUBY_VERSION > '1.9' reset! end |
Instance Method Details
- (Object) <<(data)
Adds data to the parser buffer and runs the parser
21 22 23 24 25 |
# File 'lib/mikrotik/protocol/parser.rb', line 21 def <<(data) @data << data success = true success = get_sentence while success end |
- (Object) bytes(bits)
122 123 124 |
# File 'lib/mikrotik/protocol/parser.rb', line 122 def bytes(bits) (bits / 8.0).ceil end |
- (Object) get_length
54 55 56 57 58 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 |
# File 'lib/mikrotik/protocol/parser.rb', line 54 def get_length size = get_length_size return false unless size need = bytes(size + 1) return false unless @data.size >= need length = nil field = @data[0, need].unpack('C*') case size when 7 length = field[0] & 0x7f when 14 length = ((field[0] & 0x3f) << 8) | field[1] when 21 length = ((field[0] & 0x1f) << 16) | field[1] << 8 | field[2] when 28 length = ((field[0] & 0x0f) << 24) | field[1] << 16 | field[2] << 8 | field[3] when 32 length = field[1..4].pack('C4').unpack('N').first end if length return length else raise ArgumentError, "Invalid word length" end end |
- (Object) get_length_size
Indentifies the size of the length field in bits
31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 |
# File 'lib/mikrotik/protocol/parser.rb', line 31 def get_length_size return false if @data.empty? # High bits used for length type # Low bits used as first bits of length # 0xxxxxxx = 7 bit length # 10xxxxxx = 14 bit length # 110xxxxx = 21 bit length # 1110xxxx = 28 bit length # 11110000 = 32 bit length follows t = @data.unpack('C').first return 7 if t & 0b10000000 == 0 return 14 if t & 0b01000000 == 0 return 21 if t & 0b00100000 == 0 return 28 if t & 0b00010000 == 0 return 32 if t == 0b11110000 raise ArgumentError, "Invalid length type encoding" end |
- (Object) get_sentence
102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 |
# File 'lib/mikrotik/protocol/parser.rb', line 102 def get_sentence while word = get_word if word.empty? Mikrotik.debug [:parser, :got_sentence, @sentence] on_sentence(@sentence) reset! return true else if word =~ PAIR key, value = word.scan(PAIR).flatten @sentence[key] = value else @sentence[word] = nil end end end return false end |
- (Object) get_word
85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 |
# File 'lib/mikrotik/protocol/parser.rb', line 85 def get_word return false if @data.empty? length_size = bytes(get_length_size + 1) length = get_length total_size = length_size + length if length && @data.size >= total_size @data.slice!(0, length_size) word = @data.slice!(0, length) Mikrotik.debug [:parser, :got_word, word] return word end return false end |
- (Object) reset!
Discards the sentence currently being parsed
16 17 18 |
# File 'lib/mikrotik/protocol/parser.rb', line 16 def reset! @sentence = Mikrotik::Protocol::Sentence.new end |
- (Object) sentence {|Mikrotik::Protocol::Sentence| ... }
Fired when the parser extracts a complete API sentence
7 |
# File 'lib/mikrotik/protocol/parser.rb', line 7 has_event :sentence |