2016-03-28 20:28:57 -04:00
|
|
|
package networkdb
|
|
|
|
|
2016-05-17 00:42:35 -04:00
|
|
|
import "github.com/gogo/protobuf/proto"
|
2016-03-28 20:28:57 -04:00
|
|
|
|
|
|
|
const (
|
|
|
|
// Compound message header overhead 1 byte(message type) + 4
|
|
|
|
// bytes (num messages)
|
|
|
|
compoundHeaderOverhead = 5
|
|
|
|
|
2016-05-17 00:42:35 -04:00
|
|
|
// Overhead for each embedded message in a compound message 4
|
2016-03-28 20:28:57 -04:00
|
|
|
// bytes (len of embedded message)
|
2016-05-17 00:42:35 -04:00
|
|
|
compoundOverhead = 4
|
2016-03-28 20:28:57 -04:00
|
|
|
)
|
|
|
|
|
2016-05-17 00:42:35 -04:00
|
|
|
func encodeRawMessage(t MessageType, raw []byte) ([]byte, error) {
|
|
|
|
gMsg := GossipMessage{
|
|
|
|
Type: t,
|
|
|
|
Data: raw,
|
|
|
|
}
|
|
|
|
|
|
|
|
buf, err := proto.Marshal(&gMsg)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
return buf, nil
|
2016-03-28 20:28:57 -04:00
|
|
|
}
|
|
|
|
|
2016-05-17 00:42:35 -04:00
|
|
|
func encodeMessage(t MessageType, msg interface{}) ([]byte, error) {
|
|
|
|
buf, err := proto.Marshal(msg.(proto.Message))
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
2016-03-28 20:28:57 -04:00
|
|
|
|
2016-05-17 00:42:35 -04:00
|
|
|
buf, err = encodeRawMessage(t, buf)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
return buf, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func decodeMessage(buf []byte) (MessageType, []byte, error) {
|
|
|
|
var gMsg GossipMessage
|
|
|
|
|
|
|
|
err := proto.Unmarshal(buf, &gMsg)
|
|
|
|
if err != nil {
|
|
|
|
return MessageTypeInvalid, nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
return gMsg.Type, gMsg.Data, nil
|
2016-03-28 20:28:57 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
// makeCompoundMessage takes a list of messages and generates
|
|
|
|
// a single compound message containing all of them
|
2016-05-17 00:42:35 -04:00
|
|
|
func makeCompoundMessage(msgs [][]byte) []byte {
|
|
|
|
cMsg := CompoundMessage{}
|
2016-03-28 20:28:57 -04:00
|
|
|
|
2016-05-17 00:42:35 -04:00
|
|
|
cMsg.Messages = make([]*CompoundMessage_SimpleMessage, 0, len(msgs))
|
|
|
|
for _, m := range msgs {
|
|
|
|
cMsg.Messages = append(cMsg.Messages, &CompoundMessage_SimpleMessage{
|
|
|
|
Payload: m,
|
|
|
|
})
|
|
|
|
}
|
2016-03-28 20:28:57 -04:00
|
|
|
|
2016-05-17 00:42:35 -04:00
|
|
|
buf, err := proto.Marshal(&cMsg)
|
|
|
|
if err != nil {
|
|
|
|
return nil
|
|
|
|
}
|
2016-03-28 20:28:57 -04:00
|
|
|
|
2016-05-17 00:42:35 -04:00
|
|
|
gMsg := GossipMessage{
|
|
|
|
Type: MessageTypeCompound,
|
|
|
|
Data: buf,
|
2016-03-28 20:28:57 -04:00
|
|
|
}
|
|
|
|
|
2016-05-17 00:42:35 -04:00
|
|
|
buf, err = proto.Marshal(&gMsg)
|
|
|
|
if err != nil {
|
|
|
|
return nil
|
2016-03-28 20:28:57 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
return buf
|
|
|
|
}
|
|
|
|
|
|
|
|
// decodeCompoundMessage splits a compound message and returns
|
2016-05-17 00:42:35 -04:00
|
|
|
// the slices of individual messages. Returns any potential error.
|
|
|
|
func decodeCompoundMessage(buf []byte) ([][]byte, error) {
|
|
|
|
var cMsg CompoundMessage
|
|
|
|
if err := proto.Unmarshal(buf, &cMsg); err != nil {
|
|
|
|
return nil, err
|
2016-03-28 20:28:57 -04:00
|
|
|
}
|
|
|
|
|
2016-05-17 00:42:35 -04:00
|
|
|
parts := make([][]byte, 0, len(cMsg.Messages))
|
|
|
|
for _, m := range cMsg.Messages {
|
|
|
|
parts = append(parts, m.Payload)
|
2016-03-28 20:28:57 -04:00
|
|
|
}
|
|
|
|
|
2016-05-17 00:42:35 -04:00
|
|
|
return parts, nil
|
2016-03-28 20:28:57 -04:00
|
|
|
}
|