blob: d30f6e587ad3015eb3186ba196c6e0caf7629f62 [file] [log] [blame]
Abhay Kumara2ae5992025-11-10 14:02:24 +00001package sarama
2
3import (
4 "encoding/binary"
5 "errors"
6 "fmt"
7 "math"
8 "time"
9
10 "github.com/rcrowley/go-metrics"
11)
12
13type prepEncoder struct {
14 stack []pushEncoder
15 length int
16}
17
18type prepFlexibleEncoder struct {
19 *prepEncoder
20}
21
22// primitives
23
24func (pe *prepEncoder) putInt8(in int8) {
25 pe.length++
26}
27
28func (pe *prepEncoder) putInt16(in int16) {
29 pe.length += 2
30}
31
32func (pe *prepEncoder) putInt32(in int32) {
33 pe.length += 4
34}
35
36func (pe *prepEncoder) putInt64(in int64) {
37 pe.length += 8
38}
39
40func (pe *prepEncoder) putVarint(in int64) {
41 var buf [binary.MaxVarintLen64]byte
42 pe.length += binary.PutVarint(buf[:], in)
43}
44
45func (pe *prepEncoder) putUVarint(in uint64) {
46 var buf [binary.MaxVarintLen64]byte
47 pe.length += binary.PutUvarint(buf[:], in)
48}
49
50func (pe *prepEncoder) putFloat64(in float64) {
51 pe.length += 8
52}
53
54func (pe *prepEncoder) putArrayLength(in int) error {
55 if in > math.MaxInt32 {
56 return PacketEncodingError{fmt.Sprintf("array too long (%d)", in)}
57 }
58 pe.length += 4
59 return nil
60}
61
62func (pe *prepEncoder) putBool(in bool) {
63 pe.length++
64}
65
66func (pe *prepEncoder) putKError(in KError) {
67 pe.length += 2
68}
69
70func (pe *prepEncoder) putDurationMs(in time.Duration) {
71 pe.length += 4
72}
73
74// arrays
75
76func (pe *prepEncoder) putBytes(in []byte) error {
77 pe.length += 4
78 if in == nil {
79 return nil
80 }
81 return pe.putRawBytes(in)
82}
83
84func (pe *prepEncoder) putVarintBytes(in []byte) error {
85 if in == nil {
86 pe.putVarint(-1)
87 return nil
88 }
89 pe.putVarint(int64(len(in)))
90 return pe.putRawBytes(in)
91}
92
93func (pe *prepEncoder) putRawBytes(in []byte) error {
94 if len(in) > math.MaxInt32 {
95 return PacketEncodingError{fmt.Sprintf("byteslice too long (%d)", len(in))}
96 }
97 pe.length += len(in)
98 return nil
99}
100
101func (pe *prepEncoder) putNullableString(in *string) error {
102 if in == nil {
103 pe.length += 2
104 return nil
105 }
106 return pe.putString(*in)
107}
108
109func (pe *prepEncoder) putString(in string) error {
110 pe.length += 2
111 if len(in) > math.MaxInt16 {
112 return PacketEncodingError{fmt.Sprintf("string too long (%d)", len(in))}
113 }
114 pe.length += len(in)
115 return nil
116}
117
118func (pe *prepEncoder) putStringArray(in []string) error {
119 err := pe.putArrayLength(len(in))
120 if err != nil {
121 return err
122 }
123
124 for _, str := range in {
125 if err := pe.putString(str); err != nil {
126 return err
127 }
128 }
129
130 return nil
131}
132
133func (pe *prepEncoder) putInt32Array(in []int32) error {
134 err := pe.putArrayLength(len(in))
135 if err != nil {
136 return err
137 }
138 pe.length += 4 * len(in)
139 return nil
140}
141
142func (pe *prepEncoder) putNullableInt32Array(in []int32) error {
143 if in == nil {
144 pe.length += 4
145 return nil
146 }
147 err := pe.putArrayLength(len(in))
148 if err != nil {
149 return err
150 }
151 pe.length += 4 * len(in)
152 return nil
153}
154
155func (pe *prepEncoder) putInt64Array(in []int64) error {
156 err := pe.putArrayLength(len(in))
157 if err != nil {
158 return err
159 }
160 pe.length += 8 * len(in)
161 return nil
162}
163
164func (pe *prepEncoder) putEmptyTaggedFieldArray() {
165}
166
167func (pe *prepEncoder) offset() int {
168 return pe.length
169}
170
171// stackable
172
173func (pe *prepEncoder) push(in pushEncoder) {
174 in.saveOffset(pe.length)
175 pe.length += in.reserveLength()
176 pe.stack = append(pe.stack, in)
177}
178
179func (pe *prepEncoder) pop() error {
180 in := pe.stack[len(pe.stack)-1]
181 pe.stack = pe.stack[:len(pe.stack)-1]
182 if dpe, ok := in.(dynamicPushEncoder); ok {
183 pe.length += dpe.adjustLength(pe.length)
184 }
185
186 return nil
187}
188
189// we do not record metrics during the prep encoder pass
190func (pe *prepEncoder) metricRegistry() metrics.Registry {
191 return nil
192}
193
194func (pe *prepFlexibleEncoder) putArrayLength(in int) error {
195 pe.putUVarint(uint64(in + 1))
196 return nil
197}
198
199func (pe *prepFlexibleEncoder) putBytes(in []byte) error {
200 pe.putUVarint(uint64(len(in) + 1))
201 return pe.putRawBytes(in)
202}
203
204func (pe *prepFlexibleEncoder) putString(in string) error {
205 if err := pe.putArrayLength(len(in)); err != nil {
206 return err
207 }
208 return pe.putRawBytes([]byte(in))
209}
210
211func (pe *prepFlexibleEncoder) putNullableString(in *string) error {
212 if in == nil {
213 pe.putUVarint(0)
214 return nil
215 } else {
216 return pe.putString(*in)
217 }
218}
219
220func (pe *prepFlexibleEncoder) putStringArray(in []string) error {
221 err := pe.putArrayLength(len(in))
222 if err != nil {
223 return err
224 }
225
226 for _, str := range in {
227 if err := pe.putString(str); err != nil {
228 return err
229 }
230 }
231
232 return nil
233}
234
235func (pe *prepFlexibleEncoder) putInt32Array(in []int32) error {
236 if in == nil {
237 return errors.New("expected int32 array to be non null")
238 }
239
240 pe.putUVarint(uint64(len(in)) + 1)
241 pe.length += 4 * len(in)
242 return nil
243}
244
245func (pe *prepFlexibleEncoder) putNullableInt32Array(in []int32) error {
246 if in == nil {
247 pe.putUVarint(0)
248 return nil
249 }
250
251 pe.putUVarint(uint64(len(in)) + 1)
252 pe.length += 4 * len(in)
253 return nil
254}
255
256func (pe *prepFlexibleEncoder) putEmptyTaggedFieldArray() {
257 pe.putUVarint(0)
258}