Class: EventMachine::Protocols::LineAndTextProtocol
- Inherits:
-
Connection
- Object
- Connection
- EventMachine::Protocols::LineAndTextProtocol
- Defined in:
- lib/em/protocols/line_and_text.rb
Overview
A protocol that handles line-oriented data with interspersed binary text.
This version is optimized for performance. See EventMachine::Protocols::LineText2 for a version which is optimized for correctness with regard to binary text blocks that can switch back to line mode.
Constant Summary collapse
- MaxBinaryLength =
32*1024*1024
Instance Attribute Summary
Attributes inherited from Connection
Instance Method Summary collapse
-
#initialize(*args) ⇒ LineAndTextProtocol
constructor
A new instance of LineAndTextProtocol.
- #receive_data(data) ⇒ Object
-
#set_binary_mode(size = nil) ⇒ Object
Set up to read the supplied number of binary bytes.
- #unbind ⇒ Object
Methods inherited from Connection
#associate_callback_target, #close_connection, #close_connection_after_writing, #comm_inactivity_timeout, #comm_inactivity_timeout=, #connection_completed, #detach, #error?, #get_cipher_bits, #get_cipher_name, #get_cipher_protocol, #get_idle_time, #get_outbound_data_size, #get_peer_cert, #get_peername, #get_pid, #get_proxied_bytes, #get_sni_hostname, #get_sock_opt, #get_sockname, #get_status, new, #notify_readable=, #notify_readable?, #notify_writable=, #notify_writable?, #pause, #paused?, #pending_connect_timeout, #pending_connect_timeout=, #post_init, #proxy_completed, #proxy_incoming_to, #proxy_target_unbound, #reconnect, #resume, #send_data, #send_datagram, #send_file_data, #set_sock_opt, #ssl_handshake_completed, #ssl_verify_peer, #start_tls, #stop_proxying, #stream_file_data
Constructor Details
#initialize(*args) ⇒ LineAndTextProtocol
Returns a new instance of LineAndTextProtocol.
37 38 39 40 |
# File 'lib/em/protocols/line_and_text.rb', line 37 def initialize *args super lbp_init_line_state end |
Instance Method Details
#receive_data(data) ⇒ Object
42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 |
# File 'lib/em/protocols/line_and_text.rb', line 42 def receive_data data if @lbp_mode == :lines begin @lpb_buffer.extract(data).each do |line| receive_line(line.chomp) if respond_to?(:receive_line) end rescue receive_error('overlength line') if respond_to?(:receive_error) close_connection return end else if @lbp_binary_limit > 0 wanted = @lbp_binary_limit - @lbp_binary_bytes_received chunk = nil if data.length > wanted chunk = data.slice!(0...wanted) else chunk = data data = "" end @lbp_binary_buffer[@lbp_binary_bytes_received...(@lbp_binary_bytes_received+chunk.length)] = chunk @lbp_binary_bytes_received += chunk.length if @lbp_binary_bytes_received == @lbp_binary_limit receive_binary_data(@lbp_binary_buffer) if respond_to?(:receive_binary_data) lbp_init_line_state end receive_data(data) if data.length > 0 else receive_binary_data(data) if respond_to?(:receive_binary_data) data = "" end end end |
#set_binary_mode(size = nil) ⇒ Object
Set up to read the supplied number of binary bytes. This recycles all the data currently waiting in the line buffer, if any. If the limit is nil, then ALL subsequent data will be treated as binary data and passed to the upstream protocol handler as we receive it. If a limit is given, we'll hold the incoming binary data and not pass it upstream until we've seen it all, or until there is an unbind (in which case we'll pass up a partial). Specifying nil for the limit (the default) means there is no limit. Specifiyng zero for the limit will cause an immediate transition back to line mode.
95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 |
# File 'lib/em/protocols/line_and_text.rb', line 95 def set_binary_mode size = nil if @lbp_mode == :lines if size == 0 receive_binary_data("") if respond_to?(:receive_binary_data) # Do no more work here. Stay in line mode and keep consuming data. else @lbp_binary_limit = size.to_i # (nil will be stored as zero) if @lbp_binary_limit > 0 raise "Overlength" if @lbp_binary_limit > MaxBinaryLength # arbitrary sanity check @lbp_binary_buffer = "\0" * @lbp_binary_limit @lbp_binary_bytes_received = 0 end @lbp_mode = :binary receive_data @lpb_buffer.flush end else raise "invalid operation" end end |
#unbind ⇒ Object
77 78 79 80 81 82 83 |
# File 'lib/em/protocols/line_and_text.rb', line 77 def unbind if @lbp_mode == :binary and @lbp_binary_limit > 0 if respond_to?(:receive_binary_data) receive_binary_data( @lbp_binary_buffer[0...@lbp_binary_bytes_received] ) end end end |