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
- MaxLineLength =
16*1024
- MaxBinaryLength =
32*1024*1024
Instance Attribute Summary
Attributes inherited from Connection
Instance Method Summary (collapse)
-
- (LineAndTextProtocol) initialize(*args)
constructor
A new instance of LineAndTextProtocol.
-
- (Object) receive_data(data)
-
- (Object) set_binary_mode(size = nil)
Set up to read the supplied number of binary bytes.
-
- (Object) unbind
Methods inherited from Connection
#close_connection, #close_connection_after_writing, #comm_inactivity_timeout, #comm_inactivity_timeout=, #connection_completed, #detach, #error?, #get_idle_time, #get_peer_cert, #get_peername, #get_pid, #get_proxied_bytes, #get_sock_opt, #get_sockname, #get_status, #notify_readable=, #notify_readable?, #notify_writable=, #notify_writable?, #pause, #paused?, #pending_connect_timeout=, #post_init, #proxy_completed, #proxy_incoming_to, #proxy_target_unbound, #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
- (LineAndTextProtocol) initialize(*args)
A new instance of LineAndTextProtocol
38 39 40 41 |
# File 'lib/em/protocols/line_and_text.rb', line 38 def initialize *args super lbp_init_line_state end |
Instance Method Details
- (Object) receive_data(data)
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 Exception 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 |
- (Object) set_binary_mode(size = nil)
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 |
- (Object) unbind
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 |