github.com/safing/portbase@v0.19.5/formats/varint/varint.go (about)

     1  package varint
     2  
     3  import (
     4  	"encoding/binary"
     5  	"errors"
     6  )
     7  
     8  // ErrBufTooSmall is returned when there is not enough data for parsing a varint.
     9  var ErrBufTooSmall = errors.New("varint: buf too small")
    10  
    11  // Pack8 packs a uint8 into a VarInt.
    12  func Pack8(n uint8) []byte {
    13  	if n < 128 {
    14  		return []byte{n}
    15  	}
    16  	return []byte{n, 0x01}
    17  }
    18  
    19  // Pack16 packs a uint16 into a VarInt.
    20  func Pack16(n uint16) []byte {
    21  	buf := make([]byte, 3)
    22  	w := binary.PutUvarint(buf, uint64(n))
    23  	return buf[:w]
    24  }
    25  
    26  // Pack32 packs a uint32 into a VarInt.
    27  func Pack32(n uint32) []byte {
    28  	buf := make([]byte, 5)
    29  	w := binary.PutUvarint(buf, uint64(n))
    30  	return buf[:w]
    31  }
    32  
    33  // Pack64 packs a uint64 into a VarInt.
    34  func Pack64(n uint64) []byte {
    35  	buf := make([]byte, 10)
    36  	w := binary.PutUvarint(buf, n)
    37  	return buf[:w]
    38  }
    39  
    40  // Unpack8 unpacks a VarInt into a uint8. It returns the extracted int, how many bytes were used and an error.
    41  func Unpack8(blob []byte) (uint8, int, error) {
    42  	if len(blob) < 1 {
    43  		return 0, 0, ErrBufTooSmall
    44  	}
    45  	if blob[0] < 128 {
    46  		return blob[0], 1, nil
    47  	}
    48  	if len(blob) < 2 {
    49  		return 0, 0, ErrBufTooSmall
    50  	}
    51  	if blob[1] != 0x01 {
    52  		return 0, 0, errors.New("varint: encoded integer greater than 255 (uint8)")
    53  	}
    54  	return blob[0], 1, nil
    55  }
    56  
    57  // Unpack16 unpacks a VarInt into a uint16. It returns the extracted int, how many bytes were used and an error.
    58  func Unpack16(blob []byte) (uint16, int, error) {
    59  	n, r := binary.Uvarint(blob)
    60  	if r == 0 {
    61  		return 0, 0, ErrBufTooSmall
    62  	}
    63  	if r < 0 {
    64  		return 0, 0, errors.New("varint: encoded integer greater than 18446744073709551615 (uint64)")
    65  	}
    66  	if n > 65535 {
    67  		return 0, 0, errors.New("varint: encoded integer greater than 65535 (uint16)")
    68  	}
    69  	return uint16(n), r, nil
    70  }
    71  
    72  // Unpack32 unpacks a VarInt into a uint32. It returns the extracted int, how many bytes were used and an error.
    73  func Unpack32(blob []byte) (uint32, int, error) {
    74  	n, r := binary.Uvarint(blob)
    75  	if r == 0 {
    76  		return 0, 0, ErrBufTooSmall
    77  	}
    78  	if r < 0 {
    79  		return 0, 0, errors.New("varint: encoded integer greater than 18446744073709551615 (uint64)")
    80  	}
    81  	if n > 4294967295 {
    82  		return 0, 0, errors.New("varint: encoded integer greater than 4294967295 (uint32)")
    83  	}
    84  	return uint32(n), r, nil
    85  }
    86  
    87  // Unpack64 unpacks a VarInt into a uint64. It returns the extracted int, how many bytes were used and an error.
    88  func Unpack64(blob []byte) (uint64, int, error) {
    89  	n, r := binary.Uvarint(blob)
    90  	if r == 0 {
    91  		return 0, 0, ErrBufTooSmall
    92  	}
    93  	if r < 0 {
    94  		return 0, 0, errors.New("varint: encoded integer greater than 18446744073709551615 (uint64)")
    95  	}
    96  	return n, r, nil
    97  }