Class: Cod::ProtocolBuffersSerializer
- Inherits:
-
Object
- Object
- Cod::ProtocolBuffersSerializer
- Defined in:
- lib/cod/protocol_buffers_serializer.rb
Overview
Serializes a protocol buffer (googles protobufs) message to the wire and reads it back. Protobufs are not self-delimited, this is why we store the messages in the following on-wire format:
LEN(class) BYTES(class) LEN() BYTES()
where LEN is a varint representation of the length of the contained item and BYTES are the binary bytes of said item.
This is not the most space efficient manner of representing things on the wire. It also assumes that you have defined the message classes on both sides (client and server).
For applications where this is a problem, you can always use this implementation as a guide for your own implementation. For example, message polymorphism could be coded as a single byte on the wire, allowing for one of 255 messages to be sent each time. For really efficient transfers, you could even send a fixed amount of bytes and one message, getting the most out of protobufs.
Please see examples/protocol-buffers/master_child.rb for information on how to use this.
Constant Summary collapse
- Varint =
ProtocolBuffers::Varint
Instance Method Summary collapse
Instance Method Details
#de(io) ⇒ Object
48 49 50 51 52 53 54 55 56 57 |
# File 'lib/cod/protocol_buffers_serializer.rb', line 48 def de(io) klass_size = Varint.decode(io) klass_name = io.read(klass_size) klass = self.class.const_get(klass_name) msg_size = Varint.decode(io) limited_io = LimitedIO.new(io, msg_size) klass.parse(limited_io) end |
#en(obj) ⇒ Object
31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 |
# File 'lib/cod/protocol_buffers_serializer.rb', line 31 def en(obj) sio = ProtocolBuffers.bin_sio # Assuming that obj is a protocol buffers message object, this should # work: klass_name = obj.class.name buffer = obj.to_s Varint.encode(sio, klass_name.size) sio.write(klass_name) Varint.encode(sio, buffer.size) sio.write(buffer) sio.string end |