Crystal bindings: (typed|untyped) message serialization.
parent
7904d5eef6
commit
d2ab260255
|
@ -1,25 +1,69 @@
|
||||||
# TODO:
|
# TODO: tests.
|
||||||
|
|
||||||
|
# Serialization (and deserialization) doesn't refer to IPC format.
|
||||||
|
# IPC serialization format: 'length + value'
|
||||||
|
# IPCMessage serialization: 'value'
|
||||||
|
# 'Value' is:
|
||||||
|
# - simply the message payload for UntypedMessage
|
||||||
|
# - type (u8) + payload for TypedMessage
|
||||||
module IPCMessage
|
module IPCMessage
|
||||||
class UntypedMessage
|
class UntypedMessage
|
||||||
@fd : Int32
|
property payload : Bytes
|
||||||
@payload : Bytes
|
def initialize(string : String)
|
||||||
def initialize(@fd, string : String)
|
|
||||||
@payload = Bytes.new string.to_unsafe, string.size
|
@payload = Bytes.new string.to_unsafe, string.size
|
||||||
end
|
end
|
||||||
def initialize(@fd, @payload)
|
def initialize(@payload)
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.deserialize(payload) : UntypedMessage
|
||||||
|
IPCMessage::UntypedMessage.new payload
|
||||||
|
end
|
||||||
|
|
||||||
|
def serialize
|
||||||
|
@payload
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# WARNING: you can only have up to 256 types.
|
||||||
class TypedMessage < UntypedMessage
|
class TypedMessage < UntypedMessage
|
||||||
@type : UInt8? = nil
|
property type : UInt8? = nil
|
||||||
def initialize(fd, @type, string : String)
|
def initialize(@type, string : String)
|
||||||
super fd, string
|
super string
|
||||||
end
|
end
|
||||||
def initialize(fd, @type, payload)
|
def initialize(@type, payload)
|
||||||
super fd, payload
|
super payload
|
||||||
end
|
end
|
||||||
def initialize(fd, payload)
|
def initialize(payload)
|
||||||
super fd, payload
|
super payload
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.deserialize(bytes : Bytes) : TypedMessage?
|
||||||
|
if bytes.size == 0
|
||||||
|
nil
|
||||||
|
else
|
||||||
|
type = bytes[0]
|
||||||
|
IPCMessage::TypedMessage.new type, bytes[1..]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def serialize
|
||||||
|
bytes = Bytes.new (1 + @payload.size)
|
||||||
|
type = @type
|
||||||
|
bytes[0] = type.nil? ? 0 : type
|
||||||
|
bytes[1..].copy_from @payload
|
||||||
|
bytes
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Send both typed and untyped messages.
|
||||||
|
class IPC
|
||||||
|
def schedule(fd : Int32, m : (IPCMessage::TypedMessage | IPCMessage::UntypedMessage))
|
||||||
|
payload = m.serialize
|
||||||
|
schedule fd, payload, payload.size
|
||||||
|
end
|
||||||
|
def write(fd : Int32, m : (IPCMessage::TypedMessage | IPCMessage::UntypedMessage))
|
||||||
|
payload = m.serialize
|
||||||
|
write fd, payload, payload.size
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
Reference in New Issue