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