blob: 7d864f6bf97a3354adc1e2a7a60ba31224cd290d [file] [log] [blame]
Scott Bakered4efab2020-01-13 19:12:25 -08001package sarama
2
3import (
4 "encoding/binary"
5 "sync"
6)
7
8// LengthField implements the PushEncoder and PushDecoder interfaces for calculating 4-byte lengths.
9type lengthField struct {
10 startOffset int
11 length int32
12}
13
14var lengthFieldPool = sync.Pool{}
15
16func acquireLengthField() *lengthField {
17 val := lengthFieldPool.Get()
18 if val != nil {
19 return val.(*lengthField)
20 }
21 return &lengthField{}
22}
23
24func releaseLengthField(m *lengthField) {
25 lengthFieldPool.Put(m)
26}
27
28func (l *lengthField) decode(pd packetDecoder) error {
29 var err error
30 l.length, err = pd.getInt32()
31 if err != nil {
32 return err
33 }
34 if l.length > int32(pd.remaining()) {
35 return ErrInsufficientData
36 }
37 return nil
38}
39
40func (l *lengthField) saveOffset(in int) {
41 l.startOffset = in
42}
43
44func (l *lengthField) reserveLength() int {
45 return 4
46}
47
48func (l *lengthField) run(curOffset int, buf []byte) error {
49 binary.BigEndian.PutUint32(buf[l.startOffset:], uint32(curOffset-l.startOffset-4))
50 return nil
51}
52
53func (l *lengthField) check(curOffset int, buf []byte) error {
54 if int32(curOffset-l.startOffset-4) != l.length {
55 return PacketDecodingError{"length field invalid"}
56 }
57
58 return nil
59}
60
61type varintLengthField struct {
62 startOffset int
63 length int64
64}
65
66func (l *varintLengthField) decode(pd packetDecoder) error {
67 var err error
68 l.length, err = pd.getVarint()
69 return err
70}
71
72func (l *varintLengthField) saveOffset(in int) {
73 l.startOffset = in
74}
75
76func (l *varintLengthField) adjustLength(currOffset int) int {
77 oldFieldSize := l.reserveLength()
78 l.length = int64(currOffset - l.startOffset - oldFieldSize)
79
80 return l.reserveLength() - oldFieldSize
81}
82
83func (l *varintLengthField) reserveLength() int {
84 var tmp [binary.MaxVarintLen64]byte
85 return binary.PutVarint(tmp[:], l.length)
86}
87
88func (l *varintLengthField) run(curOffset int, buf []byte) error {
89 binary.PutVarint(buf[l.startOffset:], l.length)
90 return nil
91}
92
93func (l *varintLengthField) check(curOffset int, buf []byte) error {
94 if int64(curOffset-l.startOffset-l.reserveLength()) != l.length {
95 return PacketDecodingError{"length field invalid"}
96 }
97
98 return nil
99}