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  }