package networkdb import "github.com/gogo/protobuf/proto" const ( // Compound message header overhead 1 byte(message type) + 4 // bytes (num messages) compoundHeaderOverhead = 5 // Overhead for each embedded message in a compound message 4 // bytes (len of embedded message) compoundOverhead = 4 ) 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 } func encodeMessage(t MessageType, msg interface{}) ([]byte, error) { buf, err := proto.Marshal(msg.(proto.Message)) if err != nil { return nil, err } 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 } // makeCompoundMessage takes a list of messages and generates // a single compound message containing all of them func makeCompoundMessage(msgs [][]byte) []byte { cMsg := CompoundMessage{} cMsg.Messages = make([]*CompoundMessage_SimpleMessage, 0, len(msgs)) for _, m := range msgs { cMsg.Messages = append(cMsg.Messages, &CompoundMessage_SimpleMessage{ Payload: m, }) } buf, err := proto.Marshal(&cMsg) if err != nil { return nil } gMsg := GossipMessage{ Type: MessageTypeCompound, Data: buf, } buf, err = proto.Marshal(&gMsg) if err != nil { return nil } return buf } // decodeCompoundMessage splits a compound message and returns // 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 } parts := make([][]byte, 0, len(cMsg.Messages)) for _, m := range cMsg.Messages { parts = append(parts, m.Payload) } return parts, nil }