bitbuffer/
read.rs

1use crate::endianness::{BigEndian, LittleEndian};
2use crate::{BitReadStream, Endianness, Result};
3use std::borrow::Cow;
4use std::cell::RefCell;
5use std::cmp::min;
6use std::collections::HashMap;
7use std::hash::Hash;
8use std::marker::PhantomData;
9use std::mem::{size_of, MaybeUninit};
10use std::rc::Rc;
11use std::sync::Arc;
12
13/// Trait for types that can be read from a stream without requiring the size to be configured
14///
15/// The `BitRead` trait can be used with `#[derive]` on structs and enums
16///
17/// # Structs
18///
19/// The implementation can be derived for a struct as long as every field in the struct implements `BitRead` or [`BitReadSized`]
20///
21/// The struct is read field by field in the order they are defined in, if the size for a field is set [`stream.read_sized()`][read_sized]
22/// will be used, otherwise [`stream_read()`][read] will be used.
23///
24/// The size for a field can be set using 3 different methods
25///  - set the size as an integer using the `size` attribute,
26///  - use a previously defined field as the size using the `size` attribute
27///  - read a set number of bits as an integer, using the resulting value as size using the `size_bits` attribute
28///
29/// ## Examples
30///
31/// ```
32/// # use bitbuffer::BitRead;
33/// #
34/// #[derive(BitRead)]
35/// struct TestStruct {
36///     foo: u8,
37///     str: String,
38///     #[size = 2] // when `size` is set, the attributed will be read using `read_sized`
39///     truncated: String,
40///     bar: u16,
41///     float: f32,
42///     #[size = 3]
43///     asd: u8,
44///     #[size_bits = 2] // first read 2 bits as unsigned integer, then use the resulting value as size for the read
45///     dynamic_length: u8,
46///     #[size = "asd"] // use a previously defined field as size
47///     previous_field: u8,
48/// }
49/// ```
50///
51/// # Enums
52///
53/// The implementation can be derived for an enum as long as every variant of the enum either has no field, or an unnamed field that implements `BitRead` or [`BitReadSized`]
54///
55/// The enum is read by first reading a set number of bits as the discriminant of the enum, then the variant for the read discriminant is read.
56///
57/// For details about setting the input size for fields implementing [`BitReadSized`] see the block about size in the `Structs` section above.
58///
59/// The discriminant for the variants defaults to incrementing by one for every field, starting with `0`.
60/// You can overwrite the discriminant for a field, which will also change the discriminant for every following field.
61///
62/// ## Examples
63///
64/// ```
65/// # use bitbuffer::BitRead;
66/// #
67/// #[derive(BitRead)]
68/// #[discriminant_bits = 2]
69/// enum TestBareEnum {
70///     Foo,
71///     Bar,
72///     Asd = 3, // manually set the discriminant value for a field
73/// }
74/// ```
75///
76/// ```
77/// # use bitbuffer::BitRead;
78/// #
79/// #[derive(BitRead)]
80/// #[discriminant_bits = 2]
81/// enum TestUnnamedFieldEnum {
82///     #[size = 5]
83///     Foo(i8),
84///     Bar(bool),
85///     #[discriminant = 3] // since rust only allows setting the discriminant on field-less enums, you can use an attribute instead
86///     Asd(u8),
87/// }
88/// ```
89///
90/// [read_sized]: BitReadStream::read_sized
91/// [read]: BitReadStream::read
92pub trait BitRead<'a, E: Endianness>: Sized {
93    /// Read the type from stream
94    fn read(stream: &mut BitReadStream<'a, E>) -> Result<Self>;
95
96    /// Note: only the bounds are unchecked
97    ///
98    /// any other validations (e.g. checking for valid utf8) still needs to be done
99    #[doc(hidden)]
100    #[inline]
101    unsafe fn read_unchecked(stream: &mut BitReadStream<'a, E>, _end: bool) -> Result<Self> {
102        Self::read(stream)
103    }
104
105    /// Skip the type
106    ///
107    /// This might be faster than reading it if the size is known beforehand
108    #[inline]
109    fn skip(stream: &mut BitReadStream<'a, E>) -> Result<()> {
110        match Self::bit_size() {
111            Some(size) => stream.skip_bits(size),
112            None => Self::read(stream).map(|_| ()),
113        }
114    }
115
116    /// The number of bits that will be read or None if the number of bits will change depending
117    /// on the bit stream
118    #[inline]
119    fn bit_size() -> Option<usize> {
120        None
121    }
122}
123
124macro_rules! impl_read_int {
125    ($type:ty) => {
126        impl<E: Endianness> BitRead<'_, E> for $type {
127            #[inline]
128            fn read(stream: &mut BitReadStream<E>) -> Result<$type> {
129                stream.read_int::<$type>(<$type>::BITS as usize)
130            }
131
132            #[inline]
133            unsafe fn read_unchecked(stream: &mut BitReadStream<E>, end: bool) -> Result<$type> {
134                Ok(stream.read_int_unchecked::<$type>(<$type>::BITS as usize, end))
135            }
136
137            #[inline]
138            fn bit_size() -> Option<usize> {
139                Some(<$type>::BITS as usize)
140            }
141        }
142    };
143}
144
145macro_rules! impl_read_int_nonzero {
146    ($type:ty) => {
147        impl BitRead<'_, LittleEndian> for Option<$type> {
148            #[inline]
149            fn read(stream: &mut BitReadStream<LittleEndian>) -> Result<Self> {
150                Ok(<$type>::new(stream.read()?))
151            }
152
153            #[inline]
154            unsafe fn read_unchecked(
155                stream: &mut BitReadStream<LittleEndian>,
156                end: bool,
157            ) -> Result<Self> {
158                Ok(<$type>::new(
159                    stream.read_int_unchecked(size_of::<$type>() * 8, end),
160                ))
161            }
162
163            #[inline]
164            fn bit_size() -> Option<usize> {
165                Some(size_of::<$type>() * 8)
166            }
167        }
168
169        impl BitRead<'_, BigEndian> for Option<$type> {
170            #[inline]
171            fn read(stream: &mut BitReadStream<BigEndian>) -> Result<Self> {
172                Ok(<$type>::new(stream.read()?))
173            }
174
175            #[inline]
176            unsafe fn read_unchecked(
177                stream: &mut BitReadStream<BigEndian>,
178                end: bool,
179            ) -> Result<Self> {
180                Ok(<$type>::new(
181                    stream.read_int_unchecked(size_of::<$type>() * 8, end),
182                ))
183            }
184
185            #[inline]
186            fn bit_size() -> Option<usize> {
187                Some(size_of::<$type>() * 8)
188            }
189        }
190    };
191}
192
193impl_read_int!(u8);
194impl_read_int!(u16);
195impl_read_int!(u32);
196impl_read_int!(u64);
197impl_read_int!(u128);
198impl_read_int!(i8);
199impl_read_int!(i16);
200impl_read_int!(i32);
201impl_read_int!(i64);
202impl_read_int!(i128);
203
204impl_read_int_nonzero!(std::num::NonZeroU8);
205impl_read_int_nonzero!(std::num::NonZeroU16);
206impl_read_int_nonzero!(std::num::NonZeroU32);
207impl_read_int_nonzero!(std::num::NonZeroU64);
208impl_read_int_nonzero!(std::num::NonZeroU128);
209
210impl<E: Endianness> BitRead<'_, E> for f32 {
211    #[inline]
212    fn read(stream: &mut BitReadStream<E>) -> Result<f32> {
213        stream.read_float::<f32>()
214    }
215
216    #[inline]
217    unsafe fn read_unchecked(stream: &mut BitReadStream<E>, end: bool) -> Result<f32> {
218        Ok(stream.read_float_unchecked::<f32>(end))
219    }
220
221    #[inline]
222    fn bit_size() -> Option<usize> {
223        Some(32)
224    }
225}
226
227impl<E: Endianness> BitRead<'_, E> for f64 {
228    #[inline]
229    fn read(stream: &mut BitReadStream<E>) -> Result<f64> {
230        stream.read_float::<f64>()
231    }
232
233    #[inline]
234    unsafe fn read_unchecked(stream: &mut BitReadStream<E>, end: bool) -> Result<f64> {
235        Ok(stream.read_float_unchecked::<f64>(end))
236    }
237
238    #[inline]
239    fn bit_size() -> Option<usize> {
240        Some(64)
241    }
242}
243
244impl<E: Endianness> BitRead<'_, E> for bool {
245    #[inline]
246    fn read(stream: &mut BitReadStream<E>) -> Result<bool> {
247        stream.read_bool()
248    }
249
250    #[inline]
251    unsafe fn read_unchecked(stream: &mut BitReadStream<E>, _end: bool) -> Result<bool> {
252        Ok(stream.read_bool_unchecked())
253    }
254
255    #[inline]
256    fn bit_size() -> Option<usize> {
257        Some(1)
258    }
259}
260
261impl<E: Endianness> BitRead<'_, E> for String {
262    #[inline]
263    fn read(stream: &mut BitReadStream<E>) -> Result<String> {
264        Ok(stream.read_string(None)?.into_owned())
265    }
266}
267
268impl<'a, E: Endianness> BitRead<'a, E> for Cow<'a, str> {
269    #[inline]
270    fn read(stream: &mut BitReadStream<'a, E>) -> Result<Cow<'a, str>> {
271        stream.read_string(None)
272    }
273}
274
275impl<'a, E: Endianness, T: BitRead<'a, E>> BitRead<'a, E> for Rc<T> {
276    #[inline]
277    fn read(stream: &mut BitReadStream<'a, E>) -> Result<Self> {
278        Ok(Rc::new(T::read(stream)?))
279    }
280
281    #[inline]
282    unsafe fn read_unchecked(stream: &mut BitReadStream<'a, E>, end: bool) -> Result<Self> {
283        Ok(Rc::new(T::read_unchecked(stream, end)?))
284    }
285
286    #[inline]
287    fn bit_size() -> Option<usize> {
288        T::bit_size()
289    }
290}
291
292impl<'a, E: Endianness, T: BitRead<'a, E>> BitRead<'a, E> for Arc<T> {
293    #[inline]
294    fn read(stream: &mut BitReadStream<'a, E>) -> Result<Self> {
295        Ok(Arc::new(T::read(stream)?))
296    }
297
298    #[inline]
299    unsafe fn read_unchecked(stream: &mut BitReadStream<'a, E>, end: bool) -> Result<Self> {
300        Ok(Arc::new(T::read_unchecked(stream, end)?))
301    }
302
303    #[inline]
304    fn bit_size() -> Option<usize> {
305        T::bit_size()
306    }
307}
308
309impl<'a, E: Endianness, T: BitRead<'a, E>> BitRead<'a, E> for Box<T> {
310    #[inline]
311    fn read(stream: &mut BitReadStream<'a, E>) -> Result<Self> {
312        Ok(Box::new(T::read(stream)?))
313    }
314
315    #[inline]
316    unsafe fn read_unchecked(stream: &mut BitReadStream<'a, E>, end: bool) -> Result<Self> {
317        Ok(Box::new(T::read_unchecked(stream, end)?))
318    }
319
320    #[inline]
321    fn bit_size() -> Option<usize> {
322        T::bit_size()
323    }
324}
325
326macro_rules! impl_read_tuple {
327    ($($type:ident),*) => {
328        impl<'a, E: Endianness, $($type: BitRead<'a, E>),*> BitRead<'a, E> for ($($type),*) {
329            #[inline]
330            fn read(stream: &mut BitReadStream<'a, E>) -> Result<Self> {
331                Ok(($(<$type>::read(stream)?),*))
332            }
333
334            #[inline]
335            unsafe fn read_unchecked(stream: &mut BitReadStream<'a, E>, end: bool) -> Result<Self> {
336                Ok(($(<$type>::read_unchecked(stream, end)?),*))
337            }
338
339            #[inline]
340            fn bit_size() -> Option<usize> {
341                Some(0)$(.and_then(|sum| <$type>::bit_size().map(|size| sum + size)))*
342            }
343        }
344    };
345}
346
347impl_read_tuple!(T1, T2);
348impl_read_tuple!(T1, T2, T3);
349impl_read_tuple!(T1, T2, T3, T4);
350
351impl<'a, E: Endianness, T: BitRead<'a, E>, const N: usize> BitRead<'a, E> for [T; N] {
352    #[inline]
353    fn read(stream: &mut BitReadStream<'a, E>) -> Result<Self> {
354        match T::bit_size() {
355            Some(bit_size) => {
356                let end = stream.check_read(bit_size * N)?;
357                unsafe { Self::read_unchecked(stream, end) }
358            }
359            None => {
360                // SAFETY: An uninitialized `[MaybeUninit<_>; LEN]` is valid.
361                let mut array =
362                    unsafe { MaybeUninit::<[MaybeUninit<T>; N]>::uninit().assume_init() };
363                for item in array.iter_mut() {
364                    unsafe {
365                        // length is already checked
366                        let val = stream.read()?;
367                        item.as_mut_ptr().write(val)
368                    }
369                }
370                unsafe { Ok((&array as *const _ as *const [T; N]).read()) }
371            }
372        }
373    }
374
375    #[inline]
376    unsafe fn read_unchecked(stream: &mut BitReadStream<'a, E>, end: bool) -> Result<Self> {
377        // SAFETY: An uninitialized `[MaybeUninit<_>; LEN]` is valid.
378        let mut array = MaybeUninit::<[MaybeUninit<T>; N]>::uninit().assume_init();
379
380        for item in array.iter_mut() {
381            // length is already checked
382            let val = stream.read_unchecked(end)?;
383            item.as_mut_ptr().write(val);
384        }
385
386        Ok((&array as *const _ as *const [T; N]).read())
387    }
388
389    #[inline]
390    fn bit_size() -> Option<usize> {
391        T::bit_size().map(|size| size * N)
392    }
393}
394
395/// Trait for types that can be read from a stream, requiring the size to be configured
396///
397/// The meaning of the set sized depends on the type being read (e.g, number of bits for integers,
398/// number of bytes for strings, number of items for Vec's, etc)
399///
400/// The `BitReadSized` trait can be used with `#[derive]` on structs
401///
402/// The implementation can be derived for a struct as long as every field in the struct implements [`BitRead`] or `BitReadSized`
403///
404/// The struct is read field by field in the order they are defined in, if the size for a field is set [`stream.read_sized()`][read_sized]
405/// will be used, otherwise [`stream_read()`][read] will be used.
406///
407/// The size for a field can be set using 4 different methods
408///  - set the size as an integer using the `size` attribute,
409///  - use a previously defined field as the size using the `size` attribute
410///  - based on the input size by setting `size` attribute to `"input_size"`
411///  - read a set number of bits as an integer, using the resulting value as size using the `size_bits` attribute
412///
413/// ## Examples
414///
415/// ```
416/// # use bitbuffer::BitReadSized;
417/// #
418/// #[derive(BitReadSized, PartialEq, Debug)]
419/// struct TestStructSized {
420///     foo: u8,
421///     #[size = "input_size"]
422///     string: String,
423///     #[size = "input_size"]
424///     int: u8,
425/// }
426/// ```
427///
428/// # Enums
429///
430/// The implementation can be derived for an enum as long as every variant of the enum either has no field, or an unnamed field that implements [`BitRead`] or `BitReadSized`
431///
432/// The enum is read by first reading a set number of bits as the discriminant of the enum, then the variant for the read discriminant is read.
433///
434/// For details about setting the input size for fields implementing `BitReadSized` see the block about size in the `Structs` section above.
435///
436/// The discriminant for the variants defaults to incrementing by one for every field, starting with `0`.
437/// You can overwrite the discriminant for a field, which will also change the discriminant for every following field.
438///
439/// ## Examples
440///
441/// ```
442/// # use bitbuffer::BitReadSized;
443/// #
444/// #[derive(BitReadSized)]
445/// #[discriminant_bits = 2]
446/// enum TestUnnamedFieldEnum {
447///     #[size = 5]
448///     Foo(i8),
449///     Bar(bool),
450///     #[discriminant = 3] // since rust only allows setting the discriminant on field-less enums, you can use an attribute instead
451///     #[size = "input_size"]
452///     Asd(u8),
453/// }
454/// ```
455///
456/// [read_sized]: BitReadStream::read_sized
457/// [read]: BitReadStream::read
458pub trait BitReadSized<'a, E: Endianness>: Sized {
459    /// Read the type from stream
460    fn read(stream: &mut BitReadStream<'a, E>, size: usize) -> Result<Self>;
461
462    #[doc(hidden)]
463    #[inline]
464    unsafe fn read_unchecked(
465        stream: &mut BitReadStream<'a, E>,
466        size: usize,
467        _end: bool,
468    ) -> Result<Self> {
469        Self::read(stream, size)
470    }
471
472    /// Skip the type
473    ///
474    /// This might be faster than reading it if the size is known beforehand
475    #[inline]
476    fn skip(stream: &mut BitReadStream<'a, E>, size: usize) -> Result<()> {
477        match Self::bit_size_sized(size) {
478            Some(size) => stream.skip_bits(size),
479            None => Self::read(stream, size).map(|_| ()),
480        }
481    }
482
483    /// The number of bits that will be read or None if the number of bits will change depending
484    /// on the bit stream
485    #[inline]
486    fn bit_size_sized(_size: usize) -> Option<usize> {
487        None
488    }
489}
490
491macro_rules! impl_read_int_sized {
492    ( $ type: ty) => {
493        impl<E: Endianness> BitReadSized<'_, E> for $type {
494            #[inline]
495            fn read(stream: &mut BitReadStream<E>, size: usize) -> Result<$type> {
496                stream.read_int::<$type>(size)
497            }
498
499            #[inline]
500            unsafe fn read_unchecked(
501                stream: &mut BitReadStream<E>,
502                size: usize,
503                end: bool,
504            ) -> Result<$type> {
505                Ok(stream.read_int_unchecked::<$type>(size, end))
506            }
507
508            #[inline]
509            fn bit_size_sized(size: usize) -> Option<usize> {
510                Some(size)
511            }
512        }
513    };
514}
515
516impl_read_int_sized!(u8);
517impl_read_int_sized!(u16);
518impl_read_int_sized!(u32);
519impl_read_int_sized!(u64);
520impl_read_int_sized!(u128);
521impl_read_int_sized!(i8);
522impl_read_int_sized!(i16);
523impl_read_int_sized!(i32);
524impl_read_int_sized!(i64);
525impl_read_int_sized!(i128);
526
527impl<E: Endianness> BitReadSized<'_, E> for String {
528    #[inline]
529    fn read(stream: &mut BitReadStream<E>, size: usize) -> Result<String> {
530        Ok(stream.read_string(Some(size))?.into_owned())
531    }
532
533    #[inline]
534    fn bit_size_sized(size: usize) -> Option<usize> {
535        Some(8 * size)
536    }
537}
538
539impl<'a, E: Endianness> BitReadSized<'a, E> for Cow<'a, str> {
540    #[inline]
541    fn read(stream: &mut BitReadStream<'a, E>, size: usize) -> Result<Cow<'a, str>> {
542        stream.read_string(Some(size))
543    }
544
545    #[inline]
546    fn bit_size_sized(size: usize) -> Option<usize> {
547        Some(8 * size)
548    }
549}
550
551impl<'a, E: Endianness> BitReadSized<'a, E> for Cow<'a, [u8]> {
552    #[inline]
553    fn read(stream: &mut BitReadStream<'a, E>, size: usize) -> Result<Cow<'a, [u8]>> {
554        stream.read_bytes(size)
555    }
556
557    #[inline]
558    fn bit_size_sized(size: usize) -> Option<usize> {
559        Some(8 * size)
560    }
561}
562
563/// Read a boolean, if true, read `T`, else return `None`
564impl<'a, E: Endianness, T: BitRead<'a, E>> BitRead<'a, E> for Option<T> {
565    fn read(stream: &mut BitReadStream<'a, E>) -> Result<Self> {
566        if stream.read()? {
567            Ok(Some(stream.read()?))
568        } else {
569            Ok(None)
570        }
571    }
572}
573
574impl<'a, E: Endianness, T: BitReadSized<'a, E>> BitReadSized<'a, E> for Option<T> {
575    fn read(stream: &mut BitReadStream<'a, E>, size: usize) -> Result<Self> {
576        if stream.read()? {
577            Ok(Some(stream.read_sized(size)?))
578        } else {
579            Ok(None)
580        }
581    }
582}
583
584impl<'a, E: Endianness> BitReadSized<'a, E> for BitReadStream<'a, E> {
585    #[inline]
586    fn read(stream: &mut BitReadStream<'a, E>, size: usize) -> Result<Self> {
587        stream.read_bits(size)
588    }
589
590    #[inline]
591    fn bit_size_sized(size: usize) -> Option<usize> {
592        Some(size)
593    }
594}
595
596/// Read `T` `size` times and return as `Vec<T>`
597impl<'a, E: Endianness, T: BitRead<'a, E>> BitReadSized<'a, E> for Vec<T> {
598    fn read(stream: &mut BitReadStream<'a, E>, size: usize) -> Result<Self> {
599        let mut vec = Vec::with_capacity(min(size, 128));
600        match T::bit_size() {
601            Some(bit_size) => {
602                if stream.check_read(bit_size * size)? {
603                    for _ in 0..size {
604                        vec.push(unsafe { stream.read_unchecked(true) }?)
605                    }
606                } else {
607                    for _ in 0..size {
608                        vec.push(unsafe { stream.read_unchecked(false) }?)
609                    }
610                }
611            }
612            _ => {
613                for _ in 0..size {
614                    vec.push(stream.read()?)
615                }
616            }
617        }
618        Ok(vec)
619    }
620
621    #[inline]
622    unsafe fn read_unchecked(
623        stream: &mut BitReadStream<'a, E>,
624        size: usize,
625        end: bool,
626    ) -> Result<Self> {
627        let mut vec = Vec::with_capacity(min(size, 128));
628        for _ in 0..size {
629            vec.push(stream.read_unchecked(end)?)
630        }
631        Ok(vec)
632    }
633
634    #[inline]
635    fn bit_size_sized(size: usize) -> Option<usize> {
636        T::bit_size().map(|element_size| size * element_size)
637    }
638}
639
640// Once we have something like https://github.com/rust-lang/rfcs/issues/1053 we can do this optimization
641//impl<E: Endianness> ReadSized<E> for Vec<u8> {
642//    #[inline]
643//    fn read(stream: &mut BitReadStream<E>, size: usize) -> Result<Self> {
644//        stream.read_bytes(size)
645//    }
646//}
647
648/// Read `K` and `T` `size` times and return as `HashMap<K, T>`
649#[allow(clippy::implicit_hasher)]
650impl<'a, E: Endianness, K: BitRead<'a, E> + Eq + Hash, T: BitRead<'a, E>> BitReadSized<'a, E>
651    for HashMap<K, T>
652{
653    fn read(stream: &mut BitReadStream<'a, E>, size: usize) -> Result<Self> {
654        let mut map = HashMap::with_capacity(min(size, 128));
655        for _ in 0..size {
656            let key = stream.read()?;
657            let value = stream.read()?;
658            map.insert(key, value);
659        }
660        Ok(map)
661    }
662
663    #[inline]
664    unsafe fn read_unchecked(
665        stream: &mut BitReadStream<'a, E>,
666        size: usize,
667        end: bool,
668    ) -> Result<Self> {
669        let mut map = HashMap::with_capacity(min(size, 128));
670        for _ in 0..size {
671            let key = stream.read_unchecked(end)?;
672            let value = stream.read_unchecked(end)?;
673            map.insert(key, value);
674        }
675        Ok(map)
676    }
677
678    #[inline]
679    fn bit_size_sized(size: usize) -> Option<usize> {
680        if let (Some(key_size), Some(value_size)) = (K::bit_size(), T::bit_size()) {
681            Some(size * (key_size + value_size))
682        } else {
683            None
684        }
685    }
686}
687
688#[derive(Clone, Debug, PartialEq)]
689/// Struct that lazily reads it's contents from the stream
690pub struct LazyBitRead<'a, T: BitRead<'a, E>, E: Endianness> {
691    source: BitReadStream<'a, E>,
692    inner_type: PhantomData<T>,
693}
694
695impl<'a, T: BitRead<'a, E>, E: Endianness> LazyBitRead<'a, T, E> {
696    #[inline]
697    /// Get the contents of the lazy struct
698    pub fn read(&self) -> Result<T> {
699        self.source.clone().read::<T>()
700    }
701}
702
703impl<'a, T: BitRead<'a, E>, E: Endianness> BitRead<'a, E> for LazyBitRead<'a, T, E> {
704    #[inline]
705    fn read(stream: &mut BitReadStream<'a, E>) -> Result<Self> {
706        match T::bit_size() {
707            Some(bit_size) => Ok(LazyBitRead {
708                source: stream.read_bits(bit_size)?,
709                inner_type: PhantomData,
710            }),
711            None => panic!(),
712        }
713    }
714
715    #[inline]
716    fn bit_size() -> Option<usize> {
717        T::bit_size()
718    }
719}
720
721#[derive(Clone, Debug)]
722/// Struct that lazily reads it's contents from the stream
723pub struct LazyBitReadSized<'a, T: BitReadSized<'a, E>, E: Endianness> {
724    source: RefCell<BitReadStream<'a, E>>,
725    size: usize,
726    inner_type: PhantomData<T>,
727}
728
729impl<'a, T: BitReadSized<'a, E>, E: Endianness> LazyBitReadSized<'a, T, E> {
730    #[inline]
731    /// Get the contents of the lazy struct
732    pub fn value(self) -> Result<T> {
733        self.source.borrow_mut().read_sized::<T>(self.size)
734    }
735}
736
737impl<'a, T: BitReadSized<'a, E>, E: Endianness> BitReadSized<'a, E> for LazyBitReadSized<'a, T, E> {
738    #[inline]
739    fn read(stream: &mut BitReadStream<'a, E>, size: usize) -> Result<Self> {
740        match T::bit_size_sized(size) {
741            Some(bit_size) => Ok(LazyBitReadSized {
742                source: RefCell::new(stream.read_bits(bit_size)?),
743                inner_type: PhantomData,
744                size,
745            }),
746            None => panic!(),
747        }
748    }
749
750    #[inline]
751    fn bit_size_sized(size: usize) -> Option<usize> {
752        T::bit_size_sized(size)
753    }
754}
755
756impl<'a, E: Endianness, T: BitReadSized<'a, E>> BitReadSized<'a, E> for Arc<T> {
757    #[inline]
758    fn read(stream: &mut BitReadStream<'a, E>, size: usize) -> Result<Self> {
759        Ok(Arc::new(T::read(stream, size)?))
760    }
761
762    #[inline]
763    unsafe fn read_unchecked(
764        stream: &mut BitReadStream<'a, E>,
765        size: usize,
766        end: bool,
767    ) -> Result<Self> {
768        Ok(Arc::new(T::read_unchecked(stream, size, end)?))
769    }
770
771    #[inline]
772    fn bit_size_sized(size: usize) -> Option<usize> {
773        T::bit_size_sized(size)
774    }
775}
776
777impl<'a, E: Endianness, T: BitReadSized<'a, E>> BitReadSized<'a, E> for Rc<T> {
778    #[inline]
779    fn read(stream: &mut BitReadStream<'a, E>, size: usize) -> Result<Self> {
780        Ok(Rc::new(T::read(stream, size)?))
781    }
782
783    #[inline]
784    unsafe fn read_unchecked(
785        stream: &mut BitReadStream<'a, E>,
786        size: usize,
787        end: bool,
788    ) -> Result<Self> {
789        Ok(Rc::new(T::read_unchecked(stream, size, end)?))
790    }
791
792    #[inline]
793    fn bit_size_sized(size: usize) -> Option<usize> {
794        T::bit_size_sized(size)
795    }
796}
797
798impl<'a, E: Endianness, T: BitReadSized<'a, E>> BitReadSized<'a, E> for Box<T> {
799    #[inline]
800    fn read(stream: &mut BitReadStream<'a, E>, size: usize) -> Result<Self> {
801        Ok(Box::new(T::read(stream, size)?))
802    }
803
804    #[inline]
805    unsafe fn read_unchecked(
806        stream: &mut BitReadStream<'a, E>,
807        size: usize,
808        end: bool,
809    ) -> Result<Self> {
810        Ok(Box::new(T::read_unchecked(stream, size, end)?))
811    }
812
813    #[inline]
814    fn bit_size_sized(size: usize) -> Option<usize> {
815        T::bit_size_sized(size)
816    }
817}
818
819impl<'a, E: Endianness, T: BitReadSized<'a, E>, const N: usize> BitReadSized<'a, E> for [T; N] {
820    #[inline]
821    fn read(stream: &mut BitReadStream<'a, E>, size: usize) -> Result<Self> {
822        match T::bit_size_sized(size) {
823            Some(bit_size) => {
824                let end = stream.check_read(bit_size * N)?;
825                unsafe { Self::read_unchecked(stream, size, end) }
826            }
827            None => {
828                // SAFETY: An uninitialized `[MaybeUninit<_>; LEN]` is valid.
829                let mut array =
830                    unsafe { MaybeUninit::<[MaybeUninit<T>; N]>::uninit().assume_init() };
831                for item in array.iter_mut() {
832                    unsafe {
833                        // length is already checked
834                        let val = stream.read_sized(size)?;
835                        item.as_mut_ptr().write(val)
836                    }
837                }
838                unsafe { Ok((&array as *const _ as *const [T; N]).read()) }
839            }
840        }
841    }
842
843    #[inline]
844    unsafe fn read_unchecked(
845        stream: &mut BitReadStream<'a, E>,
846        size: usize,
847        end: bool,
848    ) -> Result<Self> {
849        // SAFETY: An uninitialized `[MaybeUninit<_>; LEN]` is valid.
850        let mut array = MaybeUninit::<[MaybeUninit<T>; N]>::uninit().assume_init();
851
852        for item in array.iter_mut() {
853            // length is already checked
854            let val = stream.read_sized_unchecked(size, end)?;
855            item.as_mut_ptr().write(val);
856        }
857
858        Ok((&array as *const _ as *const [T; N]).read())
859    }
860
861    #[inline]
862    fn bit_size_sized(size: usize) -> Option<usize> {
863        T::bit_size_sized(size).map(|size| size * N)
864    }
865}
866
867#[test]
868fn test_array_sizes() {
869    assert_eq!(None, <[String; 16] as BitRead<LittleEndian>>::bit_size());
870    assert_eq!(
871        Some(3 * 8 * 16),
872        <[String; 16] as BitReadSized<LittleEndian>>::bit_size_sized(3)
873    );
874
875    assert_eq!(
876        Some(16 * 8),
877        <[u8; 16] as BitRead<LittleEndian>>::bit_size()
878    );
879
880    assert_eq!(
881        Some(8 * 16),
882        <Cow<[u8]> as BitReadSized<LittleEndian>>::bit_size_sized(16)
883    );
884    assert_eq!(
885        Some(8 * 16),
886        <Cow<str> as BitReadSized<LittleEndian>>::bit_size_sized(16)
887    );
888    assert_eq!(
889        Some(16),
890        <BitReadStream<LittleEndian> as BitReadSized<LittleEndian>>::bit_size_sized(16)
891    );
892
893    assert_eq!(
894        Some(8 * 16),
895        <Vec<u8> as BitReadSized<LittleEndian>>::bit_size_sized(16)
896    );
897    assert_eq!(
898        Some(8 * 16 + 16 * 16),
899        <HashMap<u8, u16> as BitReadSized<LittleEndian>>::bit_size_sized(16)
900    );
901}
902
903#[test]
904fn test_wrapper_sizes() {
905    fn test_bit_size_le<'a, T: BitRead<'a, LittleEndian>, U: BitRead<'a, LittleEndian>>() {
906        assert_eq!(T::bit_size(), U::bit_size());
907    }
908
909    fn test_bit_size_sized_le<
910        'a,
911        T: BitReadSized<'a, LittleEndian>,
912        U: BitReadSized<'a, LittleEndian>,
913    >() {
914        assert_eq!(T::bit_size_sized(3), U::bit_size_sized(3));
915    }
916    test_bit_size_le::<String, Arc<String>>();
917
918    test_bit_size_sized_le::<String, Arc<String>>();
919    test_bit_size_sized_le::<String, Rc<String>>();
920    test_bit_size_sized_le::<String, Box<String>>();
921    test_bit_size_sized_le::<String, LazyBitReadSized<String, LittleEndian>>();
922
923    test_bit_size_le::<u8, Arc<u8>>();
924    test_bit_size_le::<u8, Rc<u8>>();
925    test_bit_size_le::<u8, Box<u8>>();
926    test_bit_size_le::<u8, LazyBitRead<u8, LittleEndian>>();
927}
928
929#[test]
930fn test_unsized_sizes() {
931    fn test_bit_size_none<'a, T: BitRead<'a, LittleEndian>>() {
932        assert_eq!(None, T::bit_size());
933    }
934    fn test_bit_size_sized_none<'a, T: BitReadSized<'a, LittleEndian>>() {
935        assert_eq!(None, T::bit_size_sized(3));
936    }
937    fn test_bit_size_sized_some<'a, T: BitReadSized<'a, LittleEndian>>() {
938        assert!(T::bit_size_sized(3).is_some());
939    }
940    test_bit_size_none::<String>();
941    test_bit_size_none::<Cow<str>>();
942    test_bit_size_sized_none::<Option<String>>();
943
944    test_bit_size_none::<Option<u8>>();
945
946    test_bit_size_sized_some::<Cow<[u8]>>();
947    test_bit_size_sized_some::<String>();
948    test_bit_size_sized_some::<String>();
949}
950
951#[test]
952fn test_primitive_sizes() {
953    fn test_bit_size<'a, T: BitRead<'a, LittleEndian>>() {
954        assert_eq!(Some(size_of::<T>() * 8), T::bit_size());
955    }
956    test_bit_size::<u8>();
957    test_bit_size::<u16>();
958    test_bit_size::<u32>();
959    test_bit_size::<u64>();
960    test_bit_size::<u128>();
961    test_bit_size::<i8>();
962    test_bit_size::<i16>();
963    test_bit_size::<i32>();
964    test_bit_size::<i64>();
965    test_bit_size::<i128>();
966    test_bit_size::<f32>();
967    test_bit_size::<f64>();
968
969    assert_eq!(Some(1), <bool as BitRead<LittleEndian>>::bit_size());
970}