package proto
import (
"encoding/binary"
"io"
"unsafe"
)
// EncodeTag encodes a pair of field number and wire type into a protobuf tag.
func EncodeTag(f FieldNumber, t WireType) uint64 {
return uint64(f)<<3 | uint64(t)
}
// EncodeZigZag returns v as a zig-zag encoded value.
func EncodeZigZag(v int64) uint64 {
return encodeZigZag64(v)
}
func encodeZigZag64(v int64) uint64 {
return (uint64(v) << 1) ^ uint64(v>>63)
}
func encodeZigZag32(v int32) uint32 {
return (uint32(v) << 1) ^ uint32(v>>31)
}
type encodeFunc = func([]byte, unsafe.Pointer, flags) (int, error)
func encodeVarint(b []byte, v uint64) (int, error) {
n := sizeOfVarint(v)
if len(b) < n {
return 0, io.ErrShortBuffer
}
switch n {
case 1:
b[0] = byte(v)
case 2:
b[0] = byte(v) | 0x80
b[1] = byte(v >> 7)
case 3:
b[0] = byte(v) | 0x80
b[1] = byte(v>>7) | 0x80
b[2] = byte(v >> 14)
case 4:
b[0] = byte(v) | 0x80
b[1] = byte(v>>7) | 0x80
b[2] = byte(v>>14) | 0x80
b[3] = byte(v >> 21)
case 5:
b[0] = byte(v) | 0x80
b[1] = byte(v>>7) | 0x80
b[2] = byte(v>>14) | 0x80
b[3] = byte(v>>21) | 0x80
b[4] = byte(v >> 28)
case 6:
b[0] = byte(v) | 0x80
b[1] = byte(v>>7) | 0x80
b[2] = byte(v>>14) | 0x80
b[3] = byte(v>>21) | 0x80
b[4] = byte(v>>28) | 0x80
b[5] = byte(v >> 35)
case 7:
b[0] = byte(v) | 0x80
b[1] = byte(v>>7) | 0x80
b[2] = byte(v>>14) | 0x80
b[3] = byte(v>>21) | 0x80
b[4] = byte(v>>28) | 0x80
b[5] = byte(v>>35) | 0x80
b[6] = byte(v >> 42)
case 8:
b[0] = byte(v) | 0x80
b[1] = byte(v>>7) | 0x80
b[2] = byte(v>>14) | 0x80
b[3] = byte(v>>21) | 0x80
b[4] = byte(v>>28) | 0x80
b[5] = byte(v>>35) | 0x80
b[6] = byte(v>>42) | 0x80
b[7] = byte(v >> 49)
case 9:
b[0] = byte(v) | 0x80
b[1] = byte(v>>7) | 0x80
b[2] = byte(v>>14) | 0x80
b[3] = byte(v>>21) | 0x80
b[4] = byte(v>>28) | 0x80
b[5] = byte(v>>35) | 0x80
b[6] = byte(v>>42) | 0x80
b[7] = byte(v>>49) | 0x80
b[8] = byte(v >> 56)
case 10:
b[0] = byte(v) | 0x80
b[1] = byte(v>>7) | 0x80
b[2] = byte(v>>14) | 0x80
b[3] = byte(v>>21) | 0x80
b[4] = byte(v>>28) | 0x80
b[5] = byte(v>>35) | 0x80
b[6] = byte(v>>42) | 0x80
b[7] = byte(v>>49) | 0x80
b[8] = byte(v>>56) | 0x80
b[9] = byte(v >> 63)
}
return n, nil
}
func encodeVarintZigZag(b []byte, v int64) (int, error) {
return encodeVarint(b, encodeZigZag64(v))
}
func encodeLE32(b []byte, v uint32) (int, error) {
if len(b) < 4 {
return 0, io.ErrShortBuffer
}
binary.LittleEndian.PutUint32(b, v)
return 4, nil
}
func encodeLE64(b []byte, v uint64) (int, error) {
if len(b) < 8 {
return 0, io.ErrShortBuffer
}
binary.LittleEndian.PutUint64(b, v)
return 8, nil
}
func encodeTag(b []byte, f fieldNumber, t wireType) (int, error) {
return encodeVarint(b, uint64(f)<<3|uint64(t))
}