protobuf/varint/
encode.rs
1use std::mem::MaybeUninit;
2
3use crate::varint::MAX_VARINT_ENCODED_LEN;
4
5#[inline]
8pub(crate) fn encode_varint64(mut value: u64, buf: &mut [MaybeUninit<u8>]) -> usize {
9 assert!(buf.len() >= MAX_VARINT_ENCODED_LEN);
10
11 fn iter(value: &mut u64, byte: &mut MaybeUninit<u8>) -> bool {
12 if (*value & !0x7F) > 0 {
13 byte.write(((*value & 0x7F) | 0x80) as u8);
14 *value >>= 7;
15 true
16 } else {
17 byte.write(*value as u8);
18 false
19 }
20 }
21
22 if !iter(&mut value, &mut buf[0]) {
26 return 1;
27 };
28 if !iter(&mut value, &mut buf[1]) {
29 return 2;
30 };
31 if !iter(&mut value, &mut buf[2]) {
32 return 3;
33 };
34 if !iter(&mut value, &mut buf[3]) {
35 return 4;
36 };
37 if !iter(&mut value, &mut buf[4]) {
38 return 5;
39 };
40 if !iter(&mut value, &mut buf[5]) {
41 return 6;
42 };
43 if !iter(&mut value, &mut buf[6]) {
44 return 7;
45 };
46 if !iter(&mut value, &mut buf[7]) {
47 return 8;
48 };
49 if !iter(&mut value, &mut buf[8]) {
50 return 9;
51 };
52 buf[9].write(value as u8);
53 10
54}
55
56#[inline]
59pub(crate) fn encode_varint32(mut value: u32, buf: &mut [MaybeUninit<u8>]) -> usize {
60 assert!(buf.len() >= 5);
61
62 fn iter(value: &mut u32, byte: &mut MaybeUninit<u8>) -> bool {
63 if (*value & !0x7F) > 0 {
64 byte.write(((*value & 0x7F) | 0x80) as u8);
65 *value >>= 7;
66 true
67 } else {
68 byte.write(*value as u8);
69 false
70 }
71 }
72
73 if !iter(&mut value, &mut buf[0]) {
77 return 1;
78 };
79 if !iter(&mut value, &mut buf[1]) {
80 return 2;
81 };
82 if !iter(&mut value, &mut buf[2]) {
83 return 3;
84 };
85 if !iter(&mut value, &mut buf[3]) {
86 return 4;
87 };
88 buf[4].write(value as u8);
89 5
90}
91
92#[inline]
94pub(crate) fn encoded_varint64_len(value: u64) -> usize {
95 let significant_bits = 64 - (value | 1).leading_zeros();
98 (significant_bits + 6) as usize / 7
99}
100
101#[cfg(test)]
102mod 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}