github.com/philpearl/plenc@v0.0.15/plenccore/varints.go (about) 1 package plenccore 2 3 import ( 4 "encoding/binary" 5 "math/bits" 6 ) 7 8 // ReadVarUint reads a varint from data and returns it 9 func ReadVarUint(data []byte) (v uint64, n int) { 10 return binary.Uvarint(data) 11 } 12 13 // SizeVarUint determines how many bytes it would take to encode the int v 14 func SizeVarUint(v uint64) int { 15 if v < 0x80 { 16 return 1 17 } 18 bits := bits.Len64(v) 19 return (bits + 6) / 7 20 } 21 22 // AppendVarUint appends a varint encoding of v to data. It returns the resulting slice 23 func AppendVarUint(data []byte, v uint64) []byte { 24 for v >= 0x80 { 25 data = append(data, byte(v)|0x80) 26 v >>= 7 27 } 28 return append(data, byte(v)) 29 } 30 31 // ZigZag performs zig-zag encoding of an int into a uint. 0->0 -1->1 1->2, etc. So positive numbers are 32 // doubled 33 func ZigZag(v int64) uint64 { 34 return uint64((v << 1) ^ (v >> 63)) 35 } 36 37 // ZagZig reverses ZigZag 38 func ZagZig(v uint64) int64 { 39 return int64(v>>1) ^ -int64(v&1) 40 } 41 42 // ReadVarInt reads a signed int value from data 43 func ReadVarInt(data []byte) (v int64, n int) { 44 u, n := ReadVarUint(data) 45 return ZagZig(u), n 46 } 47 48 // SizeVarInt returns the number of bytes needed to encode v 49 func SizeVarInt(v int64) int { 50 return SizeVarUint(ZigZag(v)) 51 } 52 53 // AppendVarInt encodes v as a varint and appends the result to data 54 func AppendVarInt(data []byte, v int64) []byte { 55 return AppendVarUint(data, ZigZag(v)) 56 }