Class: PDTP::LengthPrefixProtocol

Inherits:
EventMachine::Connection
  • Object
show all
Defined in:
lib/pdtp/common/length_prefix_protocol.rb

Overview

EventMachine connection adapter for length prefix framing

Direct Known Subclasses

Protocol

Defined Under Namespace

Classes: Prefix

Instance Method Summary collapse

Constructor Details

#initialize(*args) ⇒ LengthPrefixProtocol

Returns a new instance of LengthPrefixProtocol.



76
77
78
79
80
81
# File 'lib/pdtp/common/length_prefix_protocol.rb', line 76

def initialize *args
  super
  
  @prefix = Prefix.new
  @buffer = ''
end

Instance Method Details

#prefix_size=(size) ⇒ Object



83
84
85
86
87
# File 'lib/pdtp/common/length_prefix_protocol.rb', line 83

def prefix_size=(size)
  data = @prefix.data << @buffer
  @prefix = Prefix.new size
  receive_data data
end

#receive_data(data) ⇒ Object

Callback for processing incoming frames



90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
# File 'lib/pdtp/common/length_prefix_protocol.rb', line 90

def receive_data(data)
  begin
    # Read data and append it to the size prefix unless it's already been read
    data = @prefix.append(data) unless @prefix.read?
    return if data.nil?
    
    # If we've read the prefix, append the data
    @buffer << data
    
    # Don't do anything until we receive the specified amount of data
    return unless @buffer.size >= @prefix.payload_length
    
    # Extract the specified amount of data and process it
    data = @buffer[0..(@prefix.payload_length - 1)]
    
    # Store any remaining data
    remainder = @buffer[@prefix.payload_length..@buffer.length]
    
    # Invoke receive_packet and allow the user to process the data
    receive_packet data
    
    # Reset the prefix and buffer since we've received a whole frame
    @prefix.reset!
    @buffer = ''

    # Store data for next iteration of the loop
    data = remainder
  end until data.nil? or data.empty?
end

#receive_packet(packet) ⇒ Object

Stub for receiving a frame



121
122
# File 'lib/pdtp/common/length_prefix_protocol.rb', line 121

def receive_packet(packet)
end

#send_packet(data) ⇒ Object

Send a packet with a specified size prefix

Raises:

  • (ArgumentError)


125
126
127
128
# File 'lib/pdtp/common/length_prefix_protocol.rb', line 125

def send_packet(data)
  raise ArgumentError, 'packet too long for prefix length' if data.size >= 256**@prefix.size
  send_data [data.size].pack(@prefix.size == 2 ? 'n' : 'N') << data
end