blob: b633cd151113cdd98cbec5b6cbae3184b4c63d5a [file] [log] [blame]
khenaidooac637102019-01-14 15:44:34 -05001package sarama
2
3import (
4 "encoding/binary"
5 "fmt"
6 "math"
7
8 "github.com/rcrowley/go-metrics"
9)
10
11type prepEncoder struct {
12 stack []pushEncoder
13 length int
14}
15
16// primitives
17
18func (pe *prepEncoder) putInt8(in int8) {
19 pe.length++
20}
21
22func (pe *prepEncoder) putInt16(in int16) {
23 pe.length += 2
24}
25
26func (pe *prepEncoder) putInt32(in int32) {
27 pe.length += 4
28}
29
30func (pe *prepEncoder) putInt64(in int64) {
31 pe.length += 8
32}
33
34func (pe *prepEncoder) putVarint(in int64) {
35 var buf [binary.MaxVarintLen64]byte
36 pe.length += binary.PutVarint(buf[:], in)
37}
38
39func (pe *prepEncoder) putArrayLength(in int) error {
40 if in > math.MaxInt32 {
41 return PacketEncodingError{fmt.Sprintf("array too long (%d)", in)}
42 }
43 pe.length += 4
44 return nil
45}
46
47func (pe *prepEncoder) putBool(in bool) {
48 pe.length++
49}
50
51// arrays
52
53func (pe *prepEncoder) putBytes(in []byte) error {
54 pe.length += 4
55 if in == nil {
56 return nil
57 }
58 return pe.putRawBytes(in)
59}
60
61func (pe *prepEncoder) putVarintBytes(in []byte) error {
62 if in == nil {
63 pe.putVarint(-1)
64 return nil
65 }
66 pe.putVarint(int64(len(in)))
67 return pe.putRawBytes(in)
68}
69
70func (pe *prepEncoder) putRawBytes(in []byte) error {
71 if len(in) > math.MaxInt32 {
72 return PacketEncodingError{fmt.Sprintf("byteslice too long (%d)", len(in))}
73 }
74 pe.length += len(in)
75 return nil
76}
77
78func (pe *prepEncoder) putNullableString(in *string) error {
79 if in == nil {
80 pe.length += 2
81 return nil
82 }
83 return pe.putString(*in)
84}
85
86func (pe *prepEncoder) putString(in string) error {
87 pe.length += 2
88 if len(in) > math.MaxInt16 {
89 return PacketEncodingError{fmt.Sprintf("string too long (%d)", len(in))}
90 }
91 pe.length += len(in)
92 return nil
93}
94
95func (pe *prepEncoder) putStringArray(in []string) error {
96 err := pe.putArrayLength(len(in))
97 if err != nil {
98 return err
99 }
100
101 for _, str := range in {
102 if err := pe.putString(str); err != nil {
103 return err
104 }
105 }
106
107 return nil
108}
109
110func (pe *prepEncoder) putInt32Array(in []int32) error {
111 err := pe.putArrayLength(len(in))
112 if err != nil {
113 return err
114 }
115 pe.length += 4 * len(in)
116 return nil
117}
118
119func (pe *prepEncoder) putInt64Array(in []int64) error {
120 err := pe.putArrayLength(len(in))
121 if err != nil {
122 return err
123 }
124 pe.length += 8 * len(in)
125 return nil
126}
127
128func (pe *prepEncoder) offset() int {
129 return pe.length
130}
131
132// stackable
133
134func (pe *prepEncoder) push(in pushEncoder) {
135 in.saveOffset(pe.length)
136 pe.length += in.reserveLength()
137 pe.stack = append(pe.stack, in)
138}
139
140func (pe *prepEncoder) pop() error {
141 in := pe.stack[len(pe.stack)-1]
142 pe.stack = pe.stack[:len(pe.stack)-1]
143 if dpe, ok := in.(dynamicPushEncoder); ok {
144 pe.length += dpe.adjustLength(pe.length)
145 }
146
147 return nil
148}
149
150// we do not record metrics during the prep encoder pass
151func (pe *prepEncoder) metricRegistry() metrics.Registry {
152 return nil
153}