mirror of
https://github.com/safing/structures
synced 2025-04-08 03:19:10 +00:00
97 lines
2.5 KiB
Go
97 lines
2.5 KiB
Go
package varint
|
|
|
|
import (
|
|
"encoding/binary"
|
|
"errors"
|
|
)
|
|
|
|
// ErrBufTooSmall is returned when there is not enough data for parsing a varint.
|
|
var ErrBufTooSmall = errors.New("varint: buf too small")
|
|
|
|
// Pack8 packs a uint8 into a VarInt.
|
|
func Pack8(n uint8) []byte {
|
|
if n < 128 {
|
|
return []byte{n}
|
|
}
|
|
return []byte{n, 0x01}
|
|
}
|
|
|
|
// Pack16 packs a uint16 into a VarInt.
|
|
func Pack16(n uint16) []byte {
|
|
buf := make([]byte, 3)
|
|
w := binary.PutUvarint(buf, uint64(n))
|
|
return buf[:w]
|
|
}
|
|
|
|
// Pack32 packs a uint32 into a VarInt.
|
|
func Pack32(n uint32) []byte {
|
|
buf := make([]byte, 5)
|
|
w := binary.PutUvarint(buf, uint64(n))
|
|
return buf[:w]
|
|
}
|
|
|
|
// Pack64 packs a uint64 into a VarInt.
|
|
func Pack64(n uint64) []byte {
|
|
buf := make([]byte, 10)
|
|
w := binary.PutUvarint(buf, n)
|
|
return buf[:w]
|
|
}
|
|
|
|
// Unpack8 unpacks a VarInt into a uint8. It returns the extracted int, how many bytes were used and an error.
|
|
func Unpack8(blob []byte) (uint8, int, error) {
|
|
if len(blob) < 1 {
|
|
return 0, 0, ErrBufTooSmall
|
|
}
|
|
if blob[0] < 128 {
|
|
return blob[0], 1, nil
|
|
}
|
|
if len(blob) < 2 {
|
|
return 0, 0, ErrBufTooSmall
|
|
}
|
|
if blob[1] != 0x01 {
|
|
return 0, 0, errors.New("varint: encoded integer greater than 255 (uint8)")
|
|
}
|
|
return blob[0], 1, nil
|
|
}
|
|
|
|
// Unpack16 unpacks a VarInt into a uint16. It returns the extracted int, how many bytes were used and an error.
|
|
func Unpack16(blob []byte) (uint16, int, error) {
|
|
n, r := binary.Uvarint(blob)
|
|
if r == 0 {
|
|
return 0, 0, ErrBufTooSmall
|
|
}
|
|
if r < 0 {
|
|
return 0, 0, errors.New("varint: encoded integer greater than 18446744073709551615 (uint64)")
|
|
}
|
|
if n > 65535 {
|
|
return 0, 0, errors.New("varint: encoded integer greater than 65535 (uint16)")
|
|
}
|
|
return uint16(n), r, nil
|
|
}
|
|
|
|
// Unpack32 unpacks a VarInt into a uint32. It returns the extracted int, how many bytes were used and an error.
|
|
func Unpack32(blob []byte) (uint32, int, error) {
|
|
n, r := binary.Uvarint(blob)
|
|
if r == 0 {
|
|
return 0, 0, ErrBufTooSmall
|
|
}
|
|
if r < 0 {
|
|
return 0, 0, errors.New("varint: encoded integer greater than 18446744073709551615 (uint64)")
|
|
}
|
|
if n > 4294967295 {
|
|
return 0, 0, errors.New("varint: encoded integer greater than 4294967295 (uint32)")
|
|
}
|
|
return uint32(n), r, nil
|
|
}
|
|
|
|
// Unpack64 unpacks a VarInt into a uint64. It returns the extracted int, how many bytes were used and an error.
|
|
func Unpack64(blob []byte) (uint64, int, error) {
|
|
n, r := binary.Uvarint(blob)
|
|
if r == 0 {
|
|
return 0, 0, ErrBufTooSmall
|
|
}
|
|
if r < 0 {
|
|
return 0, 0, errors.New("varint: encoded integer greater than 18446744073709551615 (uint64)")
|
|
}
|
|
return n, r, nil
|
|
}
|