1use bitvec::{
18 vec::BitVec, store::BitStore, order::BitOrder, slice::BitSlice, boxed::BitBox, view::BitView,
19};
20use crate::{
21 EncodeLike, Encode, Decode, Input, Output, Error, Compact, codec::decode_vec_with_len,
22};
23
24impl<O: BitOrder, T: BitStore + Encode> Encode for BitSlice<T, O> {
25 fn encode_to<W: Output + ?Sized>(&self, dest: &mut W) {
26 let bits = self.len();
27 assert!(
28 bits <= ARCH32BIT_BITSLICE_MAX_BITS,
29 "Attempted to encode a BitSlice with too many bits.",
30 );
31 Compact(bits as u32).encode_to(dest);
32
33 for chunk in self.chunks(core::mem::size_of::<T>() * 8) {
35 let mut element = T::ZERO;
36 element.view_bits_mut::<O>()[..chunk.len()].copy_from_bitslice(chunk);
37 element.encode_to(dest);
38 }
39 }
40}
41
42impl<O: BitOrder, T: BitStore + Encode> Encode for BitVec<T, O> {
43 fn encode_to<W: Output + ?Sized>(&self, dest: &mut W) {
44 self.as_bitslice().encode_to(dest)
45 }
46}
47
48impl<O: BitOrder, T: BitStore + Encode> EncodeLike for BitVec<T, O> {}
49
50const ARCH32BIT_BITSLICE_MAX_BITS: usize = 0x1fff_ffff;
52
53impl<O: BitOrder, T: BitStore + Decode> Decode for BitVec<T, O> {
54 fn decode<I: Input>(input: &mut I) -> Result<Self, Error> {
55 <Compact<u32>>::decode(input).and_then(move |Compact(bits)| {
56 if bits as usize > ARCH32BIT_BITSLICE_MAX_BITS {
58 return Err("Attempt to decode a BitVec with too many bits".into());
59 }
60 let vec = decode_vec_with_len(input, bitvec::mem::elts::<T>(bits as usize))?;
61
62 let mut result = Self::try_from_vec(vec)
63 .map_err(|_| {
64 Error::from("UNEXPECTED ERROR: `bits` is less or equal to
65 `ARCH32BIT_BITSLICE_MAX_BITS`; So BitVec must be able to handle the number of
66 segment needed for `bits` to be represented; qed")
67 })?;
68
69 assert!(bits as usize <= result.len());
70 result.truncate(bits as usize);
71 Ok(result)
72 })
73 }
74}
75
76impl<O: BitOrder, T: BitStore + Encode> Encode for BitBox<T, O> {
77 fn encode_to<W: Output + ?Sized>(&self, dest: &mut W) {
78 self.as_bitslice().encode_to(dest)
79 }
80}
81
82impl<O: BitOrder, T: BitStore + Encode> EncodeLike for BitBox<T, O> {}
83
84impl<O: BitOrder, T: BitStore + Decode> Decode for BitBox<T, O> {
85 fn decode<I: Input>(input: &mut I) -> Result<Self, Error> {
86 Ok(BitVec::<T, O>::decode(input)?.into())
87 }
88}
89
90#[cfg(test)]
91mod tests {
92 use super::*;
93 use bitvec::{bitvec, order::{Msb0, Lsb0}};
94 use crate::{codec::MAX_PREALLOCATION, CompactLen};
95
96 macro_rules! test_data {
97 ($inner_type:ident) => (
98 [
99 BitVec::<$inner_type, Msb0>::new(),
100 bitvec![$inner_type, Msb0; 0],
101 bitvec![$inner_type, Msb0; 1],
102 bitvec![$inner_type, Msb0; 0, 0],
103 bitvec![$inner_type, Msb0; 1, 0],
104 bitvec![$inner_type, Msb0; 0, 1],
105 bitvec![$inner_type, Msb0; 1, 1],
106 bitvec![$inner_type, Msb0; 1, 0, 1],
107 bitvec![$inner_type, Msb0; 0, 1, 0, 1, 0, 1, 1],
108 bitvec![$inner_type, Msb0; 0, 1, 0, 1, 0, 1, 1, 0],
109 bitvec![$inner_type, Msb0; 1, 1, 0, 1, 0, 1, 1, 0, 1],
110 bitvec![$inner_type, Msb0; 1, 0, 1, 0, 1, 1, 0, 0, 1, 0, 1, 0, 1, 1, 0],
111 bitvec![$inner_type, Msb0; 0, 1, 0, 1, 0, 1, 1, 0, 0, 1, 0, 1, 0, 1, 1, 0],
112 bitvec![$inner_type, Msb0; 0, 1, 0, 1, 0, 1, 1, 0, 0, 1, 0, 1, 0, 1, 1, 0, 0],
113 bitvec![$inner_type, Msb0; 0; 15],
114 bitvec![$inner_type, Msb0; 1; 16],
115 bitvec![$inner_type, Msb0; 0; 17],
116 bitvec![$inner_type, Msb0; 1; 31],
117 bitvec![$inner_type, Msb0; 0; 32],
118 bitvec![$inner_type, Msb0; 1; 33],
119 bitvec![$inner_type, Msb0; 0; 63],
120 bitvec![$inner_type, Msb0; 1; 64],
121 bitvec![$inner_type, Msb0; 0; 65],
122 bitvec![$inner_type, Msb0; 1; MAX_PREALLOCATION * 8 + 1],
123 bitvec![$inner_type, Msb0; 0; MAX_PREALLOCATION * 9],
124 bitvec![$inner_type, Msb0; 1; MAX_PREALLOCATION * 32 + 1],
125 bitvec![$inner_type, Msb0; 0; MAX_PREALLOCATION * 33],
126 ]
127 )
128 }
129
130 #[test]
131 fn bitvec_u8() {
132 for v in &test_data!(u8) {
133 let encoded = v.encode();
134 assert_eq!(*v, BitVec::<u8, Msb0>::decode(&mut &encoded[..]).unwrap());
135
136 let elements = bitvec::mem::elts::<u8>(v.len());
137 let compact_len = Compact::compact_len(&(v.len() as u32));
138 assert_eq!(compact_len + elements, encoded.len(), "{}", v);
139 }
140 }
141
142 #[test]
143 fn bitvec_u16() {
144 for v in &test_data!(u16) {
145 let encoded = v.encode();
146 assert_eq!(*v, BitVec::<u16, Msb0>::decode(&mut &encoded[..]).unwrap());
147
148 let elements = bitvec::mem::elts::<u16>(v.len());
149 let compact_len = Compact::compact_len(&(v.len() as u32));
150 assert_eq!(compact_len + elements * 2, encoded.len(), "{}", v);
151 }
152 }
153
154 #[test]
155 fn bitvec_u32() {
156 for v in &test_data!(u32) {
157 let encoded = v.encode();
158 assert_eq!(*v, BitVec::<u32, Msb0>::decode(&mut &encoded[..]).unwrap());
159
160 let elements = bitvec::mem::elts::<u32>(v.len());
161 let compact_len = Compact::compact_len(&(v.len() as u32));
162 assert_eq!(compact_len + elements * 4, encoded.len(), "{}", v);
163 }
164 }
165
166 #[test]
167 fn bitvec_u64() {
168 for v in &test_data!(u64) {
169 let encoded = v.encode();
170 assert_eq!(*v, BitVec::<u64, Msb0>::decode(&mut &encoded[..]).unwrap());
171
172 let elements = bitvec::mem::elts::<u64>(v.len());
173 let compact_len = Compact::compact_len(&(v.len() as u32));
174 assert_eq!(compact_len + elements * 8, encoded.len(), "{}", v);
175 }
176 }
177
178 #[test]
179 fn bitslice() {
180 let data: &[u8] = &[0x69];
181 let slice = BitSlice::<u8, Msb0>::from_slice(data);
182 let encoded = slice.encode();
183 let decoded = BitVec::<u8, Msb0>::decode(&mut &encoded[..]).unwrap();
184 assert_eq!(slice, decoded.as_bitslice());
185 }
186
187 #[test]
188 fn bitbox() {
189 let data: &[u8] = &[5, 10];
190 let slice = BitSlice::<u8, Msb0>::from_slice(data);
191 let bb = BitBox::<u8, Msb0>::from_bitslice(slice);
192 let encoded = bb.encode();
193 let decoded = BitBox::<u8, Msb0>::decode(&mut &encoded[..]).unwrap();
194 assert_eq!(bb, decoded);
195 }
196
197 #[test]
198 fn bitvec_u8_encodes_as_expected() {
199 let cases = vec![
200 (bitvec![u8, Lsb0; 0, 0, 1, 1].encode(), (Compact(4u32), 0b00001100u8).encode()),
201 (bitvec![u8, Lsb0; 0, 1, 1, 1].encode(), (Compact(4u32), 0b00001110u8).encode()),
202 (bitvec![u8, Lsb0; 1, 1, 1, 1].encode(), (Compact(4u32), 0b00001111u8).encode()),
203 (bitvec![u8, Lsb0; 1, 1, 1, 1, 1].encode(), (Compact(5u32), 0b00011111u8).encode()),
204 (bitvec![u8, Lsb0; 1, 1, 1, 1, 1, 0].encode(), (Compact(6u32), 0b00011111u8).encode()),
205 (bitvec![u8, Lsb0; 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 0, 1].encode(), (Compact(12u32), 0b00011111u8, 0b00001011u8).encode()),
206 ];
207
208 for (idx, (actual, expected)) in cases.into_iter().enumerate() {
209 assert_eq!(actual, expected, "case at index {} failed; encodings differ", idx);
210 }
211 }
212}