dotcloud/docker

View on GitHub
libnetwork/networkdb/message.go

Summary

Maintainability
A
0 mins
Test Coverage
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
}