blob: 241c6c6468375304373514c85762fd639de14657 [file] [log] [blame]
Abhay Kumara2ae5992025-11-10 14:02:24 +00001package sarama
2
3import (
4 "time"
5
6 "github.com/rcrowley/go-metrics"
7)
8
9type taggedFieldDecoderFunc func(pd packetDecoder) error
10type taggedFieldDecoders map[uint64]taggedFieldDecoderFunc
11
12// PacketDecoder is the interface providing helpers for reading with Kafka's encoding rules.
13// Types implementing Decoder only need to worry about calling methods like GetString,
14// not about how a string is represented in Kafka.
15type packetDecoder interface {
16 // Primitives
17 getInt8() (int8, error)
18 getInt16() (int16, error)
19 getInt32() (int32, error)
20 getInt64() (int64, error)
21 getVarint() (int64, error)
22 getUVarint() (uint64, error)
23 getFloat64() (float64, error)
24 getArrayLength() (int, error)
25 getBool() (bool, error)
26 getKError() (KError, error)
27 getDurationMs() (time.Duration, error)
28 getEmptyTaggedFieldArray() (int, error)
29 getTaggedFieldArray(taggedFieldDecoders) error
30
31 // Collections
32 getBytes() ([]byte, error)
33 getVarintBytes() ([]byte, error)
34 getRawBytes(length int) ([]byte, error)
35 getString() (string, error)
36 getNullableString() (*string, error)
37 getInt32Array() ([]int32, error)
38 getInt64Array() ([]int64, error)
39 getStringArray() ([]string, error)
40
41 // Subsets
42 remaining() int
43 getSubset(length int) (packetDecoder, error)
44 peek(offset, length int) (packetDecoder, error) // similar to getSubset, but it doesn't advance the offset
45 peekInt8(offset int) (int8, error) // similar to peek, but just one byte
46
47 // Stacks, see PushDecoder
48 push(in pushDecoder) error
49 pop() error
50
51 // To record metrics when provided
52 metricRegistry() metrics.Registry
53}
54
55// PushDecoder is the interface for decoding fields like CRCs and lengths where the validity
56// of the field depends on what is after it in the packet. Start them with PacketDecoder.Push() where
57// the actual value is located in the packet, then PacketDecoder.Pop() them when all the bytes they
58// depend upon have been decoded.
59type pushDecoder interface {
60 // Saves the offset into the input buffer as the location to actually read the calculated value when able.
61 saveOffset(in int)
62
63 // Returns the length of data to reserve for the input of this encoder (e.g. 4 bytes for a CRC32).
64 reserveLength() int
65
66 // Indicates that all required data is now available to calculate and check the field.
67 // SaveOffset is guaranteed to have been called first. The implementation should read ReserveLength() bytes
68 // of data from the saved offset, and verify it based on the data between the saved offset and curOffset.
69 check(curOffset int, buf []byte) error
70}
71
72// dynamicPushDecoder extends the interface of pushDecoder for uses cases where the length of the
73// fields itself is unknown until its value was decoded (for instance varint encoded length
74// fields).
75// During push, dynamicPushDecoder.decode() method will be called instead of reserveLength()
76type dynamicPushDecoder interface {
77 pushDecoder
78 decoder
79}