github.com/Heebron/moby@v0.0.0-20221111184709-6eab4f55faf7/libnetwork/networkdb/message.go (about)

     1  package networkdb
     2  
     3  import "github.com/gogo/protobuf/proto"
     4  
     5  const (
     6  	// Compound message header overhead 1 byte(message type) + 4
     7  	// bytes (num messages)
     8  	compoundHeaderOverhead = 5
     9  
    10  	// Overhead for each embedded message in a compound message 4
    11  	// bytes (len of embedded message)
    12  	compoundOverhead = 4
    13  )
    14  
    15  func encodeRawMessage(t MessageType, raw []byte) ([]byte, error) {
    16  	gMsg := GossipMessage{
    17  		Type: t,
    18  		Data: raw,
    19  	}
    20  
    21  	buf, err := proto.Marshal(&gMsg)
    22  	if err != nil {
    23  		return nil, err
    24  	}
    25  
    26  	return buf, nil
    27  }
    28  
    29  func encodeMessage(t MessageType, msg interface{}) ([]byte, error) {
    30  	buf, err := proto.Marshal(msg.(proto.Message))
    31  	if err != nil {
    32  		return nil, err
    33  	}
    34  
    35  	buf, err = encodeRawMessage(t, buf)
    36  	if err != nil {
    37  		return nil, err
    38  	}
    39  
    40  	return buf, nil
    41  }
    42  
    43  func decodeMessage(buf []byte) (MessageType, []byte, error) {
    44  	var gMsg GossipMessage
    45  
    46  	err := proto.Unmarshal(buf, &gMsg)
    47  	if err != nil {
    48  		return MessageTypeInvalid, nil, err
    49  	}
    50  
    51  	return gMsg.Type, gMsg.Data, nil
    52  }
    53  
    54  // makeCompoundMessage takes a list of messages and generates
    55  // a single compound message containing all of them
    56  func makeCompoundMessage(msgs [][]byte) []byte {
    57  	cMsg := CompoundMessage{}
    58  
    59  	cMsg.Messages = make([]*CompoundMessage_SimpleMessage, 0, len(msgs))
    60  	for _, m := range msgs {
    61  		cMsg.Messages = append(cMsg.Messages, &CompoundMessage_SimpleMessage{
    62  			Payload: m,
    63  		})
    64  	}
    65  
    66  	buf, err := proto.Marshal(&cMsg)
    67  	if err != nil {
    68  		return nil
    69  	}
    70  
    71  	gMsg := GossipMessage{
    72  		Type: MessageTypeCompound,
    73  		Data: buf,
    74  	}
    75  
    76  	buf, err = proto.Marshal(&gMsg)
    77  	if err != nil {
    78  		return nil
    79  	}
    80  
    81  	return buf
    82  }
    83  
    84  // decodeCompoundMessage splits a compound message and returns
    85  // the slices of individual messages. Returns any potential error.
    86  func decodeCompoundMessage(buf []byte) ([][]byte, error) {
    87  	var cMsg CompoundMessage
    88  	if err := proto.Unmarshal(buf, &cMsg); err != nil {
    89  		return nil, err
    90  	}
    91  
    92  	parts := make([][]byte, 0, len(cMsg.Messages))
    93  	for _, m := range cMsg.Messages {
    94  		parts = append(parts, m.Payload)
    95  	}
    96  
    97  	return parts, nil
    98  }