github.com/segmentio/kafka-go@v0.4.48-0.20240318174348-3f6244eb34fd/message.go (about)

     1  package kafka
     2  
     3  import (
     4  	"time"
     5  )
     6  
     7  // Message is a data structure representing kafka messages.
     8  type Message struct {
     9  	// Topic indicates which topic this message was consumed from via Reader.
    10  	//
    11  	// When being used with Writer, this can be used to configure the topic if
    12  	// not already specified on the writer itself.
    13  	Topic string
    14  
    15  	// Partition is read-only and MUST NOT be set when writing messages
    16  	Partition     int
    17  	Offset        int64
    18  	HighWaterMark int64
    19  	Key           []byte
    20  	Value         []byte
    21  	Headers       []Header
    22  
    23  	// This field is used to hold arbitrary data you wish to include, so it
    24  	// will be available when handle it on the Writer's `Completion` method,
    25  	// this support the application can do any post operation on each message.
    26  	WriterData interface{}
    27  
    28  	// If not set at the creation, Time will be automatically set when
    29  	// writing the message.
    30  	Time time.Time
    31  }
    32  
    33  func (msg Message) message(cw *crc32Writer) message {
    34  	m := message{
    35  		MagicByte: 1,
    36  		Key:       msg.Key,
    37  		Value:     msg.Value,
    38  		Timestamp: timestamp(msg.Time),
    39  	}
    40  	if cw != nil {
    41  		m.CRC = m.crc32(cw)
    42  	}
    43  	return m
    44  }
    45  
    46  const timestampSize = 8
    47  
    48  func (msg *Message) size() int32 {
    49  	return 4 + 1 + 1 + sizeofBytes(msg.Key) + sizeofBytes(msg.Value) + timestampSize
    50  }
    51  
    52  func (msg *Message) headerSize() int {
    53  	return varArrayLen(len(msg.Headers), func(i int) int {
    54  		h := &msg.Headers[i]
    55  		return varStringLen(h.Key) + varBytesLen(h.Value)
    56  	})
    57  }
    58  
    59  func (msg *Message) totalSize() int32 {
    60  	return int32(msg.headerSize()) + msg.size()
    61  }
    62  
    63  type message struct {
    64  	CRC        int32
    65  	MagicByte  int8
    66  	Attributes int8
    67  	Timestamp  int64
    68  	Key        []byte
    69  	Value      []byte
    70  }
    71  
    72  func (m message) crc32(cw *crc32Writer) int32 {
    73  	cw.crc32 = 0
    74  	cw.writeInt8(m.MagicByte)
    75  	cw.writeInt8(m.Attributes)
    76  	if m.MagicByte != 0 {
    77  		cw.writeInt64(m.Timestamp)
    78  	}
    79  	cw.writeBytes(m.Key)
    80  	cw.writeBytes(m.Value)
    81  	return int32(cw.crc32)
    82  }
    83  
    84  func (m message) size() int32 {
    85  	size := 4 + 1 + 1 + sizeofBytes(m.Key) + sizeofBytes(m.Value)
    86  	if m.MagicByte != 0 {
    87  		size += timestampSize
    88  	}
    89  	return size
    90  }
    91  
    92  func (m message) writeTo(wb *writeBuffer) {
    93  	wb.writeInt32(m.CRC)
    94  	wb.writeInt8(m.MagicByte)
    95  	wb.writeInt8(m.Attributes)
    96  	if m.MagicByte != 0 {
    97  		wb.writeInt64(m.Timestamp)
    98  	}
    99  	wb.writeBytes(m.Key)
   100  	wb.writeBytes(m.Value)
   101  }
   102  
   103  type messageSetItem struct {
   104  	Offset      int64
   105  	MessageSize int32
   106  	Message     message
   107  }
   108  
   109  func (m messageSetItem) size() int32 {
   110  	return 8 + 4 + m.Message.size()
   111  }
   112  
   113  func (m messageSetItem) writeTo(wb *writeBuffer) {
   114  	wb.writeInt64(m.Offset)
   115  	wb.writeInt32(m.MessageSize)
   116  	m.Message.writeTo(wb)
   117  }
   118  
   119  type messageSet []messageSetItem
   120  
   121  func (s messageSet) size() (size int32) {
   122  	for _, m := range s {
   123  		size += m.size()
   124  	}
   125  	return
   126  }
   127  
   128  func (s messageSet) writeTo(wb *writeBuffer) {
   129  	for _, m := range s {
   130  		m.writeTo(wb)
   131  	}
   132  }