diff --git a/src/lib.rs b/src/lib.rs index eba7ff0..4086fa8 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -574,7 +574,7 @@ impl Endianness for LittleEndian { /// A queue for efficiently pushing bits onto a value /// and popping them off a value. -#[derive(Default)] +#[derive(Clone, Default)] pub struct BitQueue { phantom: PhantomData, value: N, diff --git a/src/read.rs b/src/read.rs index 289dda0..e1cf2df 100644 --- a/src/read.rs +++ b/src/read.rs @@ -201,6 +201,7 @@ pub trait HuffmanRead { /// This will read exactly as many whole bytes needed to return /// the requested number of bits. It may cache up to a single partial byte /// but no more. +#[derive(Clone)] pub struct BitReader { reader: R, bitqueue: BitQueue, diff --git a/tests/read.rs b/tests/read.rs index 24af71d..626b63e 100644 --- a/tests/read.rs +++ b/tests/read.rs @@ -617,3 +617,31 @@ fn test_reader_bits_errors() { ErrorKind::InvalidInput ); } + +#[test] +fn test_clone() { + use bitstream_io::{BigEndian, BitRead, BitReader}; + + // Reading unsigned examples, cloning while unaligned. + let actual_data: [u8; 4] = [0xB1, 0xED, 0x3B, 0xC1]; + let mut r = BitReader::endian(Cursor::new(&actual_data), BigEndian); + assert!(r.byte_aligned()); + assert_eq!(r.read::(4).unwrap(), 0xB); + let mut r2 = r.clone(); + assert!(!r.byte_aligned()); + assert_eq!(r.read::(4).unwrap(), 0x1); + assert_eq!(r.read::(8).unwrap(), 0xED); + assert!(!r2.byte_aligned()); + assert_eq!(r2.read::(4).unwrap(), 0x1); + assert_eq!(r2.read::(8).unwrap(), 0xED); + + // Can still instantiate a BitReader when the backing std::io::Read is + // !Clone. + struct NotCloneRead<'a>(&'a [u8]); + impl<'a> std::io::Read for NotCloneRead<'a> { + fn read(&mut self, buf: &mut [u8]) -> std::io::Result { + self.0.read(buf) + } + } + let _r = BitReader::endian(NotCloneRead(&actual_data[..]), BigEndian); +}