Module: Zerg::Support::Protocols::FrameProtocol

Included in:
ObjectProtocol
Defined in:
lib/zerg_support/protocols/frame_protocol.rb

Overview

Protocol for sending and receiving discrete-sized frames over TCP streams.

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.decode_natural(string) ⇒ Object

:nodoc: Decodes a natural (non-negative) integer from a string.



62
63
64
65
66
67
68
69
70
71
72
# File 'lib/zerg_support/protocols/frame_protocol.rb', line 62

def self.decode_natural(string)
  number = 0
  multiplier = 1
  string.each_byte do |byte|
    more, number_bits = byte.divmod 0x80
    number += number_bits * multiplier
    break if more == 0
    multiplier *= 0x80
  end
  return number
end

.encode_frame(frame_data) ⇒ Object

:nodoc: Encodes frame data into data to be sent across a TCP wire.



45
46
47
48
# File 'lib/zerg_support/protocols/frame_protocol.rb', line 45

def self.encode_frame(frame_data)
  encoded_length = FrameProtocol.encode_natural(frame_data.length)
  encoded_length + frame_data
end

.encode_natural(number) ⇒ Object

:nodoc: Encodes a natural (non-negative) integer into a string.



51
52
53
54
55
56
57
58
59
# File 'lib/zerg_support/protocols/frame_protocol.rb', line 51

def self.encode_natural(number)
  string = ''
  loop do
    number, byte = number.divmod(0x80)
    string << (byte | ((number > 0) ? 0x80 : 0x00))
    break if number == 0
  end
  string
end

Instance Method Details

#received_bytes(data) ⇒ Object

Called when data is available from the TCP stream.



7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
# File 'lib/zerg_support/protocols/frame_protocol.rb', line 7

def received_bytes(data)
  @frame_protocol_varsize ||= ''
  @frame_protocol_buffer = nil unless defined?(@frame_protocol_buffer)

  i = 0
  loop do
    while @frame_protocol_buffer.nil? and i < data.length
      @frame_protocol_varsize << data[i]
      if (data[i].ord & 0x80) == 0
        @frame_protocol_bytes_left =
            FrameProtocol.decode_natural @frame_protocol_varsize
        @frame_protocol_buffer = ''
      end
      i += 1
    end

    return if @frame_protocol_buffer.nil?
    break if @frame_protocol_bytes_left > data.length - i

    received_frame @frame_protocol_buffer +
                   data[i, @frame_protocol_bytes_left]
    @frame_protocol_varsize, @frame_protocol_buffer = '', nil
    i += @frame_protocol_bytes_left
  end

  @frame_protocol_buffer << data[i..-1]
  @frame_protocol_bytes_left -= data.length - i
end

#received_frame(frame_data) ⇒ Object

Override to process incoming frames.



37
# File 'lib/zerg_support/protocols/frame_protocol.rb', line 37

def received_frame(frame_data); end

#send_frame(frame_data) ⇒ Object

Sends a frame via the underlying TCP stream.



40
41
42
# File 'lib/zerg_support/protocols/frame_protocol.rb', line 40

def send_frame(frame_data)
  send_bytes FrameProtocol.encode_frame(frame_data)
end