Class: UnionStationHooks::MessageChannel
- Inherits:
-
Object
- Object
- UnionStationHooks::MessageChannel
- Defined in:
- lib/union_station_hooks_core/message_channel.rb
Overview
This class allows reading and writing structured messages over I/O channels. This is the Ruby implementation of Passenger’s src/cxx_supportlib/Utils/MessageIO.h; see that file for more information.
Defined Under Namespace
Classes: InvalidHashError
Constant Summary collapse
- HEADER_SIZE =
2
- DELIMITER =
"\0"
- DELIMITER_NAME =
'null byte'
- UINT16_PACK_FORMAT =
'n'
- UINT32_PACK_FORMAT =
'N'
Instance Attribute Summary collapse
-
#io ⇒ Object
The wrapped IO object.
Instance Method Summary collapse
-
#initialize(io = nil) ⇒ MessageChannel
constructor
Create a new MessageChannel by wrapping the given IO object.
-
#read ⇒ Object
Read an array message from the underlying file descriptor.
-
#write(name, *args) ⇒ Object
Send an array message, which consists of the given elements, over the underlying file descriptor.
-
#write_scalar(data) ⇒ Object
Send a scalar message over the underlying IO object.
Constructor Details
#initialize(io = nil) ⇒ MessageChannel
Create a new MessageChannel by wrapping the given IO object.
46 47 48 49 50 |
# File 'lib/union_station_hooks_core/message_channel.rb', line 46 def initialize(io = nil) @io = io # Make it binary just in case. @io.binmode if @io end |
Instance Attribute Details
#io ⇒ Object
The wrapped IO object.
43 44 45 |
# File 'lib/union_station_hooks_core/message_channel.rb', line 43 def io @io end |
Instance Method Details
#read ⇒ Object
Read an array message from the underlying file descriptor. Returns the array message as an array, or nil when end-of-stream has been reached.
Might raise SystemCallError, IOError or SocketError when something goes wrong.
61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 |
# File 'lib/union_station_hooks_core/message_channel.rb', line 61 def read buffer = new_buffer if !@io.read(HEADER_SIZE, buffer) return nil end while buffer.size < HEADER_SIZE tmp = @io.read(HEADER_SIZE - buffer.size) if tmp.empty? return nil else buffer << tmp end end chunk_size = buffer.unpack(UINT16_PACK_FORMAT)[0] if !@io.read(chunk_size, buffer) return nil end while buffer.size < chunk_size tmp = @io.read(chunk_size - buffer.size) if tmp.empty? return nil else buffer << tmp end end = [] offset = 0 delimiter_pos = buffer.index(DELIMITER, offset) while !delimiter_pos.nil? if delimiter_pos == 0 << '' else << buffer[offset..delimiter_pos - 1] end offset = delimiter_pos + 1 delimiter_pos = buffer.index(DELIMITER, offset) end rescue Errno::ECONNRESET nil end |
#write(name, *args) ⇒ Object
Send an array message, which consists of the given elements, over the underlying file descriptor. name is the first element in the message, and args are the other elements. These arguments will internally be converted to strings by calling to_s().
Might raise SystemCallError, IOError or SocketError when something goes wrong.
115 116 117 118 119 120 121 122 123 124 125 126 127 |
# File 'lib/union_station_hooks_core/message_channel.rb', line 115 def write(name, *args) check_argument(name) args.each do |arg| check_argument(arg) end = "#{name}#{DELIMITER}" args.each do |arg| << arg.to_s << DELIMITER end @io.write([.size].pack('n') << ) @io.flush end |
#write_scalar(data) ⇒ Object
Send a scalar message over the underlying IO object.
Might raise SystemCallError, IOError or SocketError when something goes wrong.
133 134 135 136 |
# File 'lib/union_station_hooks_core/message_channel.rb', line 133 def write_scalar(data) @io.write([data.size].pack('N') << data) @io.flush end |