message.go 2.0 KB

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