Coverage Report

Created: 2026-02-14 06:16

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/rust/registry/src/index.crates.io-1949cf8c6b5b557f/protobuf-3.7.2/src/varint/encode.rs
Line
Count
Source
1
use std::mem::MaybeUninit;
2
3
use crate::varint::MAX_VARINT_ENCODED_LEN;
4
5
/// Encode u64 as varint.
6
/// Panics if buffer length is less than 10.
7
#[inline]
8
0
pub(crate) fn encode_varint64(mut value: u64, buf: &mut [MaybeUninit<u8>]) -> usize {
9
0
    assert!(buf.len() >= MAX_VARINT_ENCODED_LEN);
10
11
0
    fn iter(value: &mut u64, byte: &mut MaybeUninit<u8>) -> bool {
12
0
        if (*value & !0x7F) > 0 {
13
0
            byte.write(((*value & 0x7F) | 0x80) as u8);
14
0
            *value >>= 7;
15
0
            true
16
        } else {
17
0
            byte.write(*value as u8);
18
0
            false
19
        }
20
0
    }
21
22
    // Explicitly unroll loop to avoid either
23
    // unsafe code or bound checking when writing to `buf`
24
25
0
    if !iter(&mut value, &mut buf[0]) {
26
0
        return 1;
27
0
    };
28
0
    if !iter(&mut value, &mut buf[1]) {
29
0
        return 2;
30
0
    };
31
0
    if !iter(&mut value, &mut buf[2]) {
32
0
        return 3;
33
0
    };
34
0
    if !iter(&mut value, &mut buf[3]) {
35
0
        return 4;
36
0
    };
37
0
    if !iter(&mut value, &mut buf[4]) {
38
0
        return 5;
39
0
    };
40
0
    if !iter(&mut value, &mut buf[5]) {
41
0
        return 6;
42
0
    };
43
0
    if !iter(&mut value, &mut buf[6]) {
44
0
        return 7;
45
0
    };
46
0
    if !iter(&mut value, &mut buf[7]) {
47
0
        return 8;
48
0
    };
49
0
    if !iter(&mut value, &mut buf[8]) {
50
0
        return 9;
51
0
    };
52
0
    buf[9].write(value as u8);
53
0
    10
54
0
}
55
56
/// Encode u32 value as varint.
57
/// Panics if buffer length is less than 5.
58
#[inline]
59
0
pub(crate) fn encode_varint32(mut value: u32, buf: &mut [MaybeUninit<u8>]) -> usize {
60
0
    assert!(buf.len() >= 5);
61
62
0
    fn iter(value: &mut u32, byte: &mut MaybeUninit<u8>) -> bool {
63
0
        if (*value & !0x7F) > 0 {
64
0
            byte.write(((*value & 0x7F) | 0x80) as u8);
65
0
            *value >>= 7;
66
0
            true
67
        } else {
68
0
            byte.write(*value as u8);
69
0
            false
70
        }
71
0
    }
72
73
    // Explicitly unroll loop to avoid either
74
    // unsafe code or bound checking when writing to `buf`
75
76
0
    if !iter(&mut value, &mut buf[0]) {
77
0
        return 1;
78
0
    };
79
0
    if !iter(&mut value, &mut buf[1]) {
80
0
        return 2;
81
0
    };
82
0
    if !iter(&mut value, &mut buf[2]) {
83
0
        return 3;
84
0
    };
85
0
    if !iter(&mut value, &mut buf[3]) {
86
0
        return 4;
87
0
    };
88
0
    buf[4].write(value as u8);
89
0
    5
90
0
}
91
92
/// Encoded size of u64 value.
93
#[inline]
94
0
pub(crate) fn encoded_varint64_len(value: u64) -> usize {
95
    // Bitwise-or'ing by 1 allows the `value = zero` case to work without
96
    // affecting other cases.
97
0
    let significant_bits = 64 - (value | 1).leading_zeros();
98
0
    (significant_bits + 6) as usize / 7
99
0
}
Unexecuted instantiation: protobuf::varint::encode::encoded_varint64_len
Unexecuted instantiation: protobuf::varint::encode::encoded_varint64_len
100
101
#[cfg(test)]
102
mod test {
103
    use std::mem::MaybeUninit;
104
105
    use crate::varint::encode::encode_varint64;
106
    use crate::varint::encode::encoded_varint64_len;
107
108
    #[test]
109
    fn test_encoded_varint64_len() {
110
        fn test(n: u64) {
111
            let mut buf = [MaybeUninit::uninit(); 10];
112
            let expected = encode_varint64(n, &mut buf);
113
            assert_eq!(expected, encoded_varint64_len(n), "n={}", n);
114
        }
115
116
        for n in 0..1000 {
117
            test(n);
118
        }
119
120
        for p in 0.. {
121
            match 2u64.checked_pow(p) {
122
                Some(n) => test(n),
123
                None => break,
124
            }
125
        }
126
127
        for p in 0.. {
128
            match 3u64.checked_pow(p) {
129
                Some(n) => test(n),
130
                None => break,
131
            }
132
        }
133
134
        test(u64::MAX);
135
        test(u64::MAX - 1);
136
        test((i64::MAX as u64) + 1);
137
        test(i64::MAX as u64);
138
        test((i64::MAX as u64) - 1);
139
        test((u32::MAX as u64) + 1);
140
        test(u32::MAX as u64);
141
        test((u32::MAX as u64) - 1);
142
        test((i32::MAX as u64) + 1);
143
        test(i32::MAX as u64);
144
        test((i32::MAX as u64) - 1);
145
    }
146
}