blob: 1602fcb3f6b872c4ce45adb0f06105f265349550 [file] [log] [blame]
kesavand2cde6582020-06-22 04:56:23 -04001package sarama
2
3import (
4 "encoding/binary"
kesavandc71914f2022-03-25 11:19:03 +05305 "errors"
kesavand2cde6582020-06-22 04:56:23 -04006 "fmt"
7 "math"
8
9 "github.com/rcrowley/go-metrics"
10)
11
12type prepEncoder struct {
13 stack []pushEncoder
14 length int
15}
16
17// primitives
18
19func (pe *prepEncoder) putInt8(in int8) {
20 pe.length++
21}
22
23func (pe *prepEncoder) putInt16(in int16) {
24 pe.length += 2
25}
26
27func (pe *prepEncoder) putInt32(in int32) {
28 pe.length += 4
29}
30
31func (pe *prepEncoder) putInt64(in int64) {
32 pe.length += 8
33}
34
35func (pe *prepEncoder) putVarint(in int64) {
36 var buf [binary.MaxVarintLen64]byte
37 pe.length += binary.PutVarint(buf[:], in)
38}
39
kesavandc71914f2022-03-25 11:19:03 +053040func (pe *prepEncoder) putUVarint(in uint64) {
41 var buf [binary.MaxVarintLen64]byte
42 pe.length += binary.PutUvarint(buf[:], in)
43}
44
45func (pe *prepEncoder) putFloat64(in float64) {
46 pe.length += 8
47}
48
kesavand2cde6582020-06-22 04:56:23 -040049func (pe *prepEncoder) putArrayLength(in int) error {
50 if in > math.MaxInt32 {
51 return PacketEncodingError{fmt.Sprintf("array too long (%d)", in)}
52 }
53 pe.length += 4
54 return nil
55}
56
kesavandc71914f2022-03-25 11:19:03 +053057func (pe *prepEncoder) putCompactArrayLength(in int) {
58 pe.putUVarint(uint64(in + 1))
59}
60
kesavand2cde6582020-06-22 04:56:23 -040061func (pe *prepEncoder) putBool(in bool) {
62 pe.length++
63}
64
65// arrays
66
67func (pe *prepEncoder) putBytes(in []byte) error {
68 pe.length += 4
69 if in == nil {
70 return nil
71 }
72 return pe.putRawBytes(in)
73}
74
75func (pe *prepEncoder) putVarintBytes(in []byte) error {
76 if in == nil {
77 pe.putVarint(-1)
78 return nil
79 }
80 pe.putVarint(int64(len(in)))
81 return pe.putRawBytes(in)
82}
83
kesavandc71914f2022-03-25 11:19:03 +053084func (pe *prepEncoder) putCompactBytes(in []byte) error {
85 pe.putUVarint(uint64(len(in) + 1))
86 return pe.putRawBytes(in)
87}
88
89func (pe *prepEncoder) putCompactString(in string) error {
90 pe.putCompactArrayLength(len(in))
91 return pe.putRawBytes([]byte(in))
92}
93
94func (pe *prepEncoder) putNullableCompactString(in *string) error {
95 if in == nil {
96 pe.putUVarint(0)
97 return nil
98 } else {
99 return pe.putCompactString(*in)
100 }
101}
102
kesavand2cde6582020-06-22 04:56:23 -0400103func (pe *prepEncoder) putRawBytes(in []byte) error {
104 if len(in) > math.MaxInt32 {
105 return PacketEncodingError{fmt.Sprintf("byteslice too long (%d)", len(in))}
106 }
107 pe.length += len(in)
108 return nil
109}
110
111func (pe *prepEncoder) putNullableString(in *string) error {
112 if in == nil {
113 pe.length += 2
114 return nil
115 }
116 return pe.putString(*in)
117}
118
119func (pe *prepEncoder) putString(in string) error {
120 pe.length += 2
121 if len(in) > math.MaxInt16 {
122 return PacketEncodingError{fmt.Sprintf("string too long (%d)", len(in))}
123 }
124 pe.length += len(in)
125 return nil
126}
127
128func (pe *prepEncoder) putStringArray(in []string) error {
129 err := pe.putArrayLength(len(in))
130 if err != nil {
131 return err
132 }
133
134 for _, str := range in {
135 if err := pe.putString(str); err != nil {
136 return err
137 }
138 }
139
140 return nil
141}
142
kesavandc71914f2022-03-25 11:19:03 +0530143func (pe *prepEncoder) putCompactInt32Array(in []int32) error {
144 if in == nil {
145 return errors.New("expected int32 array to be non null")
146 }
147
148 pe.putUVarint(uint64(len(in)) + 1)
149 pe.length += 4 * len(in)
150 return nil
151}
152
153func (pe *prepEncoder) putNullableCompactInt32Array(in []int32) error {
154 if in == nil {
155 pe.putUVarint(0)
156 return nil
157 }
158
159 pe.putUVarint(uint64(len(in)) + 1)
160 pe.length += 4 * len(in)
161 return nil
162}
163
kesavand2cde6582020-06-22 04:56:23 -0400164func (pe *prepEncoder) putInt32Array(in []int32) error {
165 err := pe.putArrayLength(len(in))
166 if err != nil {
167 return err
168 }
169 pe.length += 4 * len(in)
170 return nil
171}
172
173func (pe *prepEncoder) putInt64Array(in []int64) error {
174 err := pe.putArrayLength(len(in))
175 if err != nil {
176 return err
177 }
178 pe.length += 8 * len(in)
179 return nil
180}
181
kesavandc71914f2022-03-25 11:19:03 +0530182func (pe *prepEncoder) putEmptyTaggedFieldArray() {
183 pe.putUVarint(0)
184}
185
kesavand2cde6582020-06-22 04:56:23 -0400186func (pe *prepEncoder) offset() int {
187 return pe.length
188}
189
190// stackable
191
192func (pe *prepEncoder) push(in pushEncoder) {
193 in.saveOffset(pe.length)
194 pe.length += in.reserveLength()
195 pe.stack = append(pe.stack, in)
196}
197
198func (pe *prepEncoder) pop() error {
199 in := pe.stack[len(pe.stack)-1]
200 pe.stack = pe.stack[:len(pe.stack)-1]
201 if dpe, ok := in.(dynamicPushEncoder); ok {
202 pe.length += dpe.adjustLength(pe.length)
203 }
204
205 return nil
206}
207
208// we do not record metrics during the prep encoder pass
209func (pe *prepEncoder) metricRegistry() metrics.Registry {
210 return nil
211}