1#[inline]
2pub fn write_uint8(buf: &mut Vec<u8>, u: u8) -> usize {
3 buf.push(u);
4 1
5}
6
7#[inline]
8pub fn write_uint16(buf: &mut Vec<u8>, u: u16) -> usize {
9 let mut size = 0;
10 size += write_uint8(buf, (u & 0xff) as u8);
11 size += write_uint8(buf, ((u >> 8) & 0xff) as u8);
12 size
13}
14
15#[inline]
16pub fn write_uint32(buf: &mut Vec<u8>, u: u32) -> usize {
17 let mut size = 0;
18 size += write_uint16(buf, (u & 0xffff) as u16);
19 size += write_uint16(buf, ((u >> 16) & 0xffff) as u16);
20 size
21}
22
23#[inline]
24pub fn write_uint64(buf: &mut Vec<u8>, u: u64) -> usize {
25 let mut size = 0;
26 size += write_uint32(buf, (u & 0xffffffff) as u32);
27 size += write_uint32(buf, ((u >> 32) & 0xffffffff) as u32);
28 size
29}
30
31#[inline]
32pub fn write_varuint1(buf: &mut Vec<u8>, u: u8) -> usize {
33 write_uint8(buf, u)
34}
35
36#[allow(dead_code)]
37#[inline]
38pub fn write_varuint7(buf: &mut Vec<u8>, u: u8) -> usize {
39 write_uint8(buf, u)
40}
41
42#[inline]
43pub fn write_varint7(buf: &mut Vec<u8>, i: i8) -> usize {
44 write_uint8(buf, (i as u8) ^ 0x80)
45}
46
47macro_rules! gen_write_var_unsigned {
48 ($name: ident, $ty: ty) => {
49 #[inline]
50 #[allow(unused_comparisons)]
51 #[allow(overflowing_literals)]
52 pub fn $name(buf: &mut Vec<u8>, mut u: $ty) -> usize {
53 let end: i8 = if u < 0 { 0xff } else { 0 };
54
55 let mut size = 0;
56 let bit7 = 0b01111111;
57 let mut cur: u8 = (u & bit7) as u8;
58 u >>= 7;
60 while u != (end as $ty) {
61 size += write_uint8(buf, cur | 0x80);
62 cur = (u & bit7) as u8;
63 u >>= 7;
64 }
65 size += write_uint8(buf, cur);
66 size
67 }
68 };
69}
70
71macro_rules! gen_write_var_signed {
72 ($name: ident, $ty: ty) => {
73 #[inline]
74 pub fn $name(buf: &mut Vec<u8>, mut u: $ty) -> usize {
75 let mut size = 0;
76 let bit7 = 0b0111_1111;
77 let mut cur: u8 = (u & bit7) as u8;
78 let upper = 64 as $ty;
79 let lower = -64 as $ty;
80 while u < lower || upper <= u {
81 size += write_uint8(buf, cur | 0x80);
82 u >>= 7;
83 cur = (u & bit7) as u8;
84 }
85 size += write_uint8(buf, cur);
86 size
87 }
88 };
89}
90
91gen_write_var_unsigned!(write_varuint32, u32);
92gen_write_var_signed!(write_varint32, i32);
93gen_write_var_signed!(write_varint64, i64);
94
95#[cfg(test)]
96mod test {
97 use super::*;
98
99 #[test]
100 fn test_write_varint32() {
101 let mut buf = vec![];
102 let size = write_varint32(&mut buf, 0b0110_0001);
103 assert_eq!(size, 2);
104 assert_eq!(buf, &[0b1110_0001, 0b0000_0000]);
105 }
106
107 #[test]
108 fn test_write_varint32_edge1() {
109 let mut buf = vec![];
110 let size = write_varint32(&mut buf, 63);
111 assert_eq!(size, 1);
112 assert_eq!(buf, &[0b0011_1111]);
113 }
114
115 #[test]
116 fn test_write_varint32_edge2() {
117 let mut buf = vec![];
118 let size = write_varint32(&mut buf, 64);
119 assert_eq!(size, 2);
120 assert_eq!(buf, &[0b1100_0000, 0b0000_0000]);
121 }
122
123 #[test]
124 fn test_write_varint32_edge3() {
125 let mut buf = vec![];
126 let size = write_varint32(&mut buf, -64);
127 assert_eq!(size, 1);
128 assert_eq!(buf, &[0b0100_0000]);
129 }
130
131 #[test]
132 fn test_write_varint32_edge4() {
133 let mut buf = vec![];
134 let size = write_varint32(&mut buf, -65);
135 assert_eq!(size, 2);
136 assert_eq!(buf, &[0b1011_1111, 0b0111_1111]);
137 }
138}
139
140#[inline]
141pub fn write_slice(buf: &mut Vec<u8>, u: &[u8]) -> usize {
142 buf.extend_from_slice(u);
143 u.len()
144}