Skip to main content

moqtap_codec/
varint.rs

1use bytes::{Buf, BufMut};
2
3/// Maximum varint value: 2^62 - 1 (RFC 9000 Section 16)
4pub const MAX_VARINT: u64 = 4_611_686_018_427_387_903;
5
6/// A QUIC variable-length integer (RFC 9000 Section 16).
7///
8/// Uses 2-bit prefix encoding:
9/// - 00: 1 byte, values 0-63
10/// - 01: 2 bytes, values 0-16383
11/// - 10: 4 bytes, values 0-1073741823
12/// - 11: 8 bytes, values 0-4611686018427387903
13#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
14pub struct VarInt(u64);
15
16/// Errors produced when encoding or decoding a variable-length integer.
17#[derive(Debug, thiserror::Error, PartialEq, Eq, Clone)]
18pub enum VarIntError {
19    /// Value exceeds the maximum varint value (2^62 - 1).
20    #[error("value {0} exceeds maximum varint value (2^62 - 1)")]
21    Overflow(u64),
22    /// Not enough bytes in the buffer to decode a varint.
23    #[error("insufficient bytes for varint decoding")]
24    UnexpectedEnd,
25}
26
27impl VarInt {
28    /// Create a VarInt from a u64, returning an error if it exceeds the maximum.
29    #[inline]
30    pub fn from_u64(v: u64) -> Result<Self, VarIntError> {
31        if v > MAX_VARINT {
32            Err(VarIntError::Overflow(v))
33        } else {
34            Ok(VarInt(v))
35        }
36    }
37
38    /// Get the inner u64 value.
39    #[inline]
40    pub fn into_inner(self) -> u64 {
41        self.0
42    }
43
44    /// Return the number of bytes needed to encode this varint.
45    #[inline]
46    pub fn encoded_len(&self) -> usize {
47        if self.0 <= 63 {
48            1
49        } else if self.0 <= 16383 {
50            2
51        } else if self.0 <= 1073741823 {
52            4
53        } else {
54            8
55        }
56    }
57
58    /// Encode this varint into the given buffer.
59    #[inline]
60    pub fn encode(&self, buf: &mut impl BufMut) {
61        match self.encoded_len() {
62            1 => {
63                buf.put_u8(self.0 as u8);
64            }
65            2 => {
66                buf.put_u16((self.0 as u16) | 0x4000);
67            }
68            4 => {
69                buf.put_u32((self.0 as u32) | 0x80000000);
70            }
71            8 => {
72                buf.put_u64(self.0 | 0xC000000000000000);
73            }
74            _ => unreachable!(),
75        }
76    }
77
78    /// Decode a varint from the given buffer.
79    #[inline]
80    pub fn decode(buf: &mut impl Buf) -> Result<Self, VarIntError> {
81        if buf.remaining() < 1 {
82            return Err(VarIntError::UnexpectedEnd);
83        }
84        let first = buf.chunk()[0];
85        let prefix = first >> 6;
86        let len = 1usize << prefix;
87        if buf.remaining() < len {
88            return Err(VarIntError::UnexpectedEnd);
89        }
90        let val = match len {
91            1 => {
92                buf.advance(1);
93                (first & 0x3F) as u64
94            }
95            2 => {
96                let v = buf.get_u16();
97                (v & 0x3FFF) as u64
98            }
99            4 => {
100                let v = buf.get_u32();
101                (v & 0x3FFFFFFF) as u64
102            }
103            8 => {
104                let v = buf.get_u64();
105                v & 0x3FFFFFFFFFFFFFFF
106            }
107            _ => unreachable!(),
108        };
109        Ok(VarInt(val))
110    }
111}
112
113impl TryFrom<u64> for VarInt {
114    type Error = VarIntError;
115    #[inline]
116    fn try_from(v: u64) -> Result<Self, Self::Error> {
117        Self::from_u64(v)
118    }
119}
120
121impl From<VarInt> for u64 {
122    #[inline]
123    fn from(v: VarInt) -> u64 {
124        v.0
125    }
126}
127
128impl VarInt {
129    /// Create a VarInt from a usize. Infallible because practical memory sizes
130    /// are always well below the 2^62 varint maximum.
131    #[inline]
132    pub fn from_usize(v: usize) -> Self {
133        VarInt(v as u64)
134    }
135}
136
137impl From<u32> for VarInt {
138    #[inline]
139    fn from(v: u32) -> Self {
140        VarInt(v as u64)
141    }
142}