1use crate::conversion::force_to_u32;
2use crate::prelude::*;
3
4#[allow(dead_code)] pub fn decode_sections2(data: Vec<u8>) -> (Vec<u8>, Vec<u8>) {
7 let (rest, second) = split_tail(data);
8 let (_, first) = split_tail(rest);
9 (first, second)
10}
11
12#[allow(dead_code)] pub fn encode_sections(sections: &[&[u8]]) -> Vec<u8> {
26 let mut out_len: usize = sections.iter().map(|section| section.len()).sum();
27 out_len += 4 * sections.len();
28 let mut out_data = Vec::with_capacity(out_len);
29 for §ion in sections {
30 let section_len = force_to_u32(section.len()).to_be_bytes();
31 out_data.extend(section);
32 out_data.extend_from_slice(§ion_len);
33 }
34 debug_assert_eq!(out_data.len(), out_len);
35 debug_assert_eq!(out_data.capacity(), out_len);
36 out_data
37}
38
39fn split_tail(data: Vec<u8>) -> (Vec<u8>, Vec<u8>) {
48 let tail_len: usize = if data.len() >= 4 {
49 u32::from_be_bytes([
50 data[data.len() - 4],
51 data[data.len() - 3],
52 data[data.len() - 2],
53 data[data.len() - 1],
54 ]) as usize
55 } else {
56 panic!("Cannot read section length");
57 };
58 let rest_len_end = data.len() - 4 - tail_len;
59
60 let (rest, mut tail) = if rest_len_end == 0 {
61 (Vec::new(), data)
63 } else {
64 let mut rest = data;
65 let tail = rest.split_off(rest_len_end);
66 (rest, tail)
67 };
68 tail.truncate(tail_len); (rest, tail)
70}
71
72#[cfg(test)]
73mod tests {
74 use super::*;
75
76 #[test]
77 fn decode_sections2_works() {
78 let data = b"\xAA\0\0\0\x01\xBB\xCC\0\0\0\x02".to_vec();
79 assert_eq!(decode_sections2(data), (vec![0xAA], vec![0xBB, 0xCC]));
80
81 let data = b"\xDE\xEF\x62\0\0\0\x03\0\0\0\0".to_vec();
82 assert_eq!(decode_sections2(data), (vec![0xDE, 0xEF, 0x62], vec![]));
83
84 let data = b"\0\0\0\0\xDE\xEF\x62\0\0\0\x03".to_vec();
85 assert_eq!(decode_sections2(data), (vec![], vec![0xDE, 0xEF, 0x62]));
86
87 let data = b"\0\0\0\0\0\0\0\0".to_vec();
88 assert_eq!(decode_sections2(data), (vec![], vec![]));
89
90 let data = b"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\0\0\0\x13\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\0\0\x01\x15".to_vec();
91 assert_eq!(decode_sections2(data), (vec![0xFF; 19], vec![0x9D; 277]));
92 }
93
94 #[test]
95 fn decode_sections2_preserved_first_vector() {
96 let original = b"\xAA\0\0\0\x01\xBB\xCC\0\0\0\x02".to_vec();
97 let original_capacity = original.capacity();
98 let original_ptr = original.as_ptr();
99 let (first, second) = decode_sections2(original);
100
101 assert_eq!(first.capacity(), original_capacity);
103 assert_eq!(first.as_ptr(), original_ptr);
104
105 assert_ne!(second.capacity(), original_capacity);
107 assert_ne!(second.as_ptr(), original_ptr);
108 }
109
110 #[test]
111 fn encode_sections_works_for_empty_sections() {
112 let enc = encode_sections(&[]);
113 assert_eq!(enc, b"" as &[u8]);
114 let enc = encode_sections(&[&[]]);
115 assert_eq!(enc, b"\0\0\0\0" as &[u8]);
116 let enc = encode_sections(&[&[], &[]]);
117 assert_eq!(enc, b"\0\0\0\0\0\0\0\0" as &[u8]);
118 let enc = encode_sections(&[&[], &[], &[]]);
119 assert_eq!(enc, b"\0\0\0\0\0\0\0\0\0\0\0\0" as &[u8]);
120 }
121
122 #[test]
123 fn encode_sections_works_for_one_element() {
124 let enc = encode_sections(&[]);
125 assert_eq!(enc, b"" as &[u8]);
126 let enc = encode_sections(&[&[0xAA]]);
127 assert_eq!(enc, b"\xAA\0\0\0\x01" as &[u8]);
128 let enc = encode_sections(&[&[0xAA, 0xBB]]);
129 assert_eq!(enc, b"\xAA\xBB\0\0\0\x02" as &[u8]);
130 let enc = encode_sections(&[&[0x9D; 277]]);
131 assert_eq!(enc, b"\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\0\0\x01\x15" as &[u8]);
132 }
133
134 #[test]
135 fn encode_sections_works_for_multiple_elements() {
136 let enc = encode_sections(&[&[0xAA]]);
137 assert_eq!(enc, b"\xAA\0\0\0\x01" as &[u8]);
138 let enc = encode_sections(&[&[0xAA], &[0xDE, 0xDE]]);
139 assert_eq!(enc, b"\xAA\0\0\0\x01\xDE\xDE\0\0\0\x02" as &[u8]);
140 let enc = encode_sections(&[&[0xAA], &[0xDE, 0xDE], &[]]);
141 assert_eq!(enc, b"\xAA\0\0\0\x01\xDE\xDE\0\0\0\x02\0\0\0\0" as &[u8]);
142 let enc = encode_sections(&[&[0xAA], &[0xDE, 0xDE], &[], &[0xFF; 19]]);
143 assert_eq!(enc, b"\xAA\0\0\0\x01\xDE\xDE\0\0\0\x02\0\0\0\0\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\0\0\0\x13" as &[u8]);
144 }
145}