| 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 |
| } |