You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
153 lines
2.7 KiB
153 lines
2.7 KiB
package sarama |
|
|
|
import ( |
|
"encoding/binary" |
|
"fmt" |
|
"math" |
|
|
|
"github.com/rcrowley/go-metrics" |
|
) |
|
|
|
type prepEncoder struct { |
|
stack []pushEncoder |
|
length int |
|
} |
|
|
|
// primitives |
|
|
|
func (pe *prepEncoder) putInt8(in int8) { |
|
pe.length++ |
|
} |
|
|
|
func (pe *prepEncoder) putInt16(in int16) { |
|
pe.length += 2 |
|
} |
|
|
|
func (pe *prepEncoder) putInt32(in int32) { |
|
pe.length += 4 |
|
} |
|
|
|
func (pe *prepEncoder) putInt64(in int64) { |
|
pe.length += 8 |
|
} |
|
|
|
func (pe *prepEncoder) putVarint(in int64) { |
|
var buf [binary.MaxVarintLen64]byte |
|
pe.length += binary.PutVarint(buf[:], in) |
|
} |
|
|
|
func (pe *prepEncoder) putArrayLength(in int) error { |
|
if in > math.MaxInt32 { |
|
return PacketEncodingError{fmt.Sprintf("array too long (%d)", in)} |
|
} |
|
pe.length += 4 |
|
return nil |
|
} |
|
|
|
func (pe *prepEncoder) putBool(in bool) { |
|
pe.length++ |
|
} |
|
|
|
// arrays |
|
|
|
func (pe *prepEncoder) putBytes(in []byte) error { |
|
pe.length += 4 |
|
if in == nil { |
|
return nil |
|
} |
|
return pe.putRawBytes(in) |
|
} |
|
|
|
func (pe *prepEncoder) putVarintBytes(in []byte) error { |
|
if in == nil { |
|
pe.putVarint(-1) |
|
return nil |
|
} |
|
pe.putVarint(int64(len(in))) |
|
return pe.putRawBytes(in) |
|
} |
|
|
|
func (pe *prepEncoder) putRawBytes(in []byte) error { |
|
if len(in) > math.MaxInt32 { |
|
return PacketEncodingError{fmt.Sprintf("byteslice too long (%d)", len(in))} |
|
} |
|
pe.length += len(in) |
|
return nil |
|
} |
|
|
|
func (pe *prepEncoder) putNullableString(in *string) error { |
|
if in == nil { |
|
pe.length += 2 |
|
return nil |
|
} |
|
return pe.putString(*in) |
|
} |
|
|
|
func (pe *prepEncoder) putString(in string) error { |
|
pe.length += 2 |
|
if len(in) > math.MaxInt16 { |
|
return PacketEncodingError{fmt.Sprintf("string too long (%d)", len(in))} |
|
} |
|
pe.length += len(in) |
|
return nil |
|
} |
|
|
|
func (pe *prepEncoder) putStringArray(in []string) error { |
|
err := pe.putArrayLength(len(in)) |
|
if err != nil { |
|
return err |
|
} |
|
|
|
for _, str := range in { |
|
if err := pe.putString(str); err != nil { |
|
return err |
|
} |
|
} |
|
|
|
return nil |
|
} |
|
|
|
func (pe *prepEncoder) putInt32Array(in []int32) error { |
|
err := pe.putArrayLength(len(in)) |
|
if err != nil { |
|
return err |
|
} |
|
pe.length += 4 * len(in) |
|
return nil |
|
} |
|
|
|
func (pe *prepEncoder) putInt64Array(in []int64) error { |
|
err := pe.putArrayLength(len(in)) |
|
if err != nil { |
|
return err |
|
} |
|
pe.length += 8 * len(in) |
|
return nil |
|
} |
|
|
|
func (pe *prepEncoder) offset() int { |
|
return pe.length |
|
} |
|
|
|
// stackable |
|
|
|
func (pe *prepEncoder) push(in pushEncoder) { |
|
in.saveOffset(pe.length) |
|
pe.length += in.reserveLength() |
|
pe.stack = append(pe.stack, in) |
|
} |
|
|
|
func (pe *prepEncoder) pop() error { |
|
in := pe.stack[len(pe.stack)-1] |
|
pe.stack = pe.stack[:len(pe.stack)-1] |
|
if dpe, ok := in.(dynamicPushEncoder); ok { |
|
pe.length += dpe.adjustLength(pe.length) |
|
} |
|
|
|
return nil |
|
} |
|
|
|
// we do not record metrics during the prep encoder pass |
|
func (pe *prepEncoder) metricRegistry() metrics.Registry { |
|
return nil |
|
}
|
|
|