zenith-foundation 0.1.0

Zenith 核心基础设施:统一错误类型、FrameToken 所有权令牌、FramePool、分层资源账本、恒定时间比较
Documentation
//! QUIC 变长整数编码(RFC 9000 §16 唯一实现)
//!
//! 全 workspace 唯一实现:zenith-http3(帧层)、zenith-net(QUIC 头构造)
//! 统一经 zenith-http3 re-export 本模块,禁止重复实现。
//!
//! # 编码格式
//! - 1 字节: 00xxxxxx (0-63)
//! - 2 字节: 01xxxxxx xxxxxxxx (64-16383)
//! - 4 字节: 10xxxxxx xxxxxxxx xxxxxxxx xxxxxxxx (16384-2^30-1)
//! - 8 字节: 11xxxxxx xxxxxxxx ... (2^30-2^62-1)
//!
//! # 边界保证
//! 当 value >= 2^62 时严格返回错误(fail-closed,禁止静默截断高位)。

/// RFC 9000 varint 最大编码长度(字节)
pub const MAX_VARINT_SIZE: usize = 8;

/// RFC 9000 varint 最大可编码值(2^62 - 1)
pub const MAX_VARINT_VALUE: u64 = (1u64 << 62) - 1;

/// 编码 QUIC 变长度整数到固定输出缓冲区(fail-closed)
///
/// # 返回
/// 写入的字节数,或缓冲区不足/值超界时返回错误。
#[inline]
pub fn encode_varint_buf(value: u64, out: &mut [u8]) -> Result<usize, &'static str> {
    if out.len() < MAX_VARINT_SIZE {
        return Err("buffer too small for varint encoding");
    }
    if value < 64 {
        out[0] = value as u8;
        Ok(1)
    } else if value < 16384 {
        out[0] = 0x40 | ((value >> 8) as u8);
        out[1] = (value & 0xFF) as u8;
        Ok(2)
    } else if value < (1u64 << 30) {
        out[0] = 0x80 | ((value >> 24) as u8);
        out[1] = ((value >> 16) & 0xFF) as u8;
        out[2] = ((value >> 8) & 0xFF) as u8;
        out[3] = (value & 0xFF) as u8;
        Ok(4)
    } else if value <= MAX_VARINT_VALUE {
        // 8 字节: 2 位长度标签 (11) + 6 位最高有效位
        out[0] = 0xC0 | (((value >> 56) & 0x3F) as u8);
        out[1] = ((value >> 48) & 0xFF) as u8;
        out[2] = ((value >> 40) & 0xFF) as u8;
        out[3] = ((value >> 32) & 0xFF) as u8;
        out[4] = ((value >> 24) & 0xFF) as u8;
        out[5] = ((value >> 16) & 0xFF) as u8;
        out[6] = ((value >> 8) & 0xFF) as u8;
        out[7] = (value & 0xFF) as u8;
        Ok(8)
    } else {
        // 值 >= 2^62 超过 RFC 9000 上限,严格 fail-closed
        Err("varint value exceeds maximum (2^62 - 1)")
    }
}

/// 编码 QUIC 变长度整数到 Vec(fail-closed 包装器)
///
/// # 错误
/// 值 >= 2^62(超出 RFC 9000 varint 上限)时返回错误,严格 fail-closed,
/// 禁止静默丢弃编码失败。
#[inline]
pub fn encode_varint(value: u64, out: &mut Vec<u8>) -> Result<(), &'static str> {
    let mut buf = [0u8; MAX_VARINT_SIZE];
    let len = encode_varint_buf(value, &mut buf)?;
    out.extend_from_slice(&buf[..len]);
    Ok(())
}

/// 解析 QUIC/HTTP/3 变长度整数 (RFC 9000 §16)
///
/// 返回 `(value, consumed_bytes)`;输入为空或不足时返回 `None`(fail-closed)。
/// 与 [`encode_varint_buf`] / [`encode_varint`] 共同覆盖 RFC 9000 §16 编解码,
/// 为全 workspace varint 解码的唯一实现(HTTP/3 帧层、QUIC 帧解析统一复用)。
#[inline]
pub fn parse_varint(input: &[u8]) -> Option<(u64, usize)> {
    if input.is_empty() {
        return None;
    }
    let first = input[0];
    let len_tag = first >> 6;
    let len = 1usize << len_tag;
    if input.len() < len {
        return None;
    }
    let mut v: u64 = (first & 0x3F) as u64;
    for &b in input.iter().take(len).skip(1) {
        v = (v << 8) | (b as u64);
    }
    Some((v, len))
}

#[cfg(test)]
mod tests {
    use super::*;

    /// RFC 9000 §A.1 Sample Variable-Length Integer Decoding 已知值(编码方向)
    #[test]
    fn test_rfc9000_appendix_a_known_values() {
        // (value, expected minimal-length encoding)
        let cases: &[(u64, &[u8])] = &[
            (37, &[0x25]),
            (63, &[0x3f]),
            (64, &[0x40, 0x40]),
            (83, &[0x40, 0x53]),
            (15_293, &[0x7b, 0xbd]),
            (16_383, &[0x7f, 0xff]),
            (16_384, &[0x80, 0x00, 0x40, 0x00]),
            (494_878_333, &[0x9d, 0x7f, 0x3e, 0x7d]),
            (1_073_741_823, &[0xbf, 0xff, 0xff, 0xff]),
            (1_073_741_824, &[0xc0, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00]),
            // RFC 9000 §A.1 样例字节:0xc2197c5eff14e88c → 151,288,809,941,952,652
            (151_288_809_941_952_652, &[0xc2, 0x19, 0x7c, 0x5e, 0xff, 0x14, 0xe8, 0x8c]),
            ((1u64 << 62) - 1, &[0xff; 8]),
        ];
        for (value, expected) in cases {
            let mut buf = [0u8; MAX_VARINT_SIZE];
            let n = encode_varint_buf(*value, &mut buf).unwrap();
            assert_eq!(&buf[..n], *expected, "encode({value}) mismatch");
            let mut v = Vec::new();
            encode_varint(*value, &mut v).unwrap();
            assert_eq!(v.as_slice(), *expected, "encode_vec({value}) mismatch");
        }
    }

    #[test]
    fn test_over_max_rejected() {
        let mut buf = [0u8; MAX_VARINT_SIZE];
        assert!(encode_varint_buf(1u64 << 62, &mut buf).is_err());
        let mut v = Vec::new();
        assert!(encode_varint(u64::MAX, &mut v).is_err());
        assert!(v.is_empty(), "fail-closed: 拒绝时不得写入任何字节");
    }

    #[test]
    fn test_small_buffer_rejected() {
        let mut buf = [0u8; 4];
        assert!(encode_varint_buf(37, &mut buf).is_err());
    }
}