Skip to main content

oximedia_io/bits/
reader.rs

1//! Bit-level reader for parsing binary formats.
2
3use oximedia_core::{OxiError, OxiResult};
4
5/// Bit-level reader for parsing binary formats.
6///
7/// `BitReader` allows reading individual bits and multi-bit values from
8/// a byte slice. It tracks both byte position and bit position within
9/// the current byte.
10///
11/// # Bit Ordering
12///
13/// Bits are read from MSB (most significant bit) to LSB (least significant bit)
14/// within each byte. This is the standard ordering used by most video codecs
15/// including H.264, HEVC, AV1, and VP9.
16///
17/// # Example
18///
19/// ```
20/// use oximedia_io::bits::BitReader;
21///
22/// let data = [0b10110100, 0b11001010];
23/// let mut reader = BitReader::new(&data);
24///
25/// // Read individual bits (from MSB to LSB)
26/// assert_eq!(reader.read_bit()?, 1);
27/// assert_eq!(reader.read_bit()?, 0);
28/// assert_eq!(reader.read_bit()?, 1);
29/// assert_eq!(reader.read_bit()?, 1);
30///
31/// // Read multiple bits as a value
32/// assert_eq!(reader.read_bits(4)?, 0b0100);
33/// # Ok::<(), oximedia_core::OxiError>(())
34/// ```
35#[derive(Debug, Clone)]
36pub struct BitReader<'a> {
37    /// The underlying byte slice
38    data: &'a [u8],
39    /// Current byte position
40    byte_pos: usize,
41    /// Current bit position within the byte (0-7, where 0 is MSB)
42    bit_pos: u8,
43}
44
45#[allow(clippy::elidable_lifetime_names)]
46impl<'a> BitReader<'a> {
47    /// Creates a new `BitReader` from a byte slice.
48    ///
49    /// # Example
50    ///
51    /// ```
52    /// use oximedia_io::bits::BitReader;
53    ///
54    /// let data = [0xFF, 0x00];
55    /// let reader = BitReader::new(&data);
56    /// assert!(reader.has_more_data());
57    /// ```
58    #[must_use]
59    pub const fn new(data: &'a [u8]) -> Self {
60        Self {
61            data,
62            byte_pos: 0,
63            bit_pos: 0,
64        }
65    }
66
67    /// Reads a single bit from the stream.
68    ///
69    /// Returns `0` or `1`.
70    ///
71    /// # Errors
72    ///
73    /// Returns [`OxiError::UnexpectedEof`] if there are no more bits to read.
74    ///
75    /// # Example
76    ///
77    /// ```
78    /// use oximedia_io::bits::BitReader;
79    ///
80    /// let data = [0b10000000];
81    /// let mut reader = BitReader::new(&data);
82    ///
83    /// assert_eq!(reader.read_bit()?, 1);
84    /// assert_eq!(reader.read_bit()?, 0);
85    /// # Ok::<(), oximedia_core::OxiError>(())
86    /// ```
87    pub fn read_bit(&mut self) -> OxiResult<u8> {
88        if self.byte_pos >= self.data.len() {
89            return Err(OxiError::UnexpectedEof);
90        }
91
92        // Read bit from MSB to LSB (bit_pos 0 = MSB)
93        let bit = (self.data[self.byte_pos] >> (7 - self.bit_pos)) & 1;
94        self.bit_pos += 1;
95
96        if self.bit_pos == 8 {
97            self.bit_pos = 0;
98            self.byte_pos += 1;
99        }
100
101        Ok(bit)
102    }
103
104    /// Reads up to 64 bits from the stream.
105    ///
106    /// # Arguments
107    ///
108    /// * `n` - Number of bits to read (0-64)
109    ///
110    /// # Errors
111    ///
112    /// Returns [`OxiError::InvalidData`] if `n > 64`.
113    /// Returns [`OxiError::UnexpectedEof`] if there are not enough bits.
114    ///
115    /// # Example
116    ///
117    /// ```
118    /// use oximedia_io::bits::BitReader;
119    ///
120    /// let data = [0b10110100, 0b11001010];
121    /// let mut reader = BitReader::new(&data);
122    ///
123    /// assert_eq!(reader.read_bits(4)?, 0b1011);
124    /// assert_eq!(reader.read_bits(4)?, 0b0100);
125    /// assert_eq!(reader.read_bits(8)?, 0b11001010);
126    /// # Ok::<(), oximedia_core::OxiError>(())
127    /// ```
128    pub fn read_bits(&mut self, n: u8) -> OxiResult<u64> {
129        if n > 64 {
130            return Err(OxiError::InvalidData(
131                "Cannot read more than 64 bits at once".to_string(),
132            ));
133        }
134
135        if n == 0 {
136            return Ok(0);
137        }
138
139        let mut value = 0u64;
140        for _ in 0..n {
141            value = (value << 1) | u64::from(self.read_bit()?);
142        }
143
144        Ok(value)
145    }
146
147    /// Reads an 8-bit unsigned integer.
148    ///
149    /// # Errors
150    ///
151    /// Returns [`OxiError::UnexpectedEof`] if there are not enough bits.
152    ///
153    /// # Example
154    ///
155    /// ```
156    /// use oximedia_io::bits::BitReader;
157    ///
158    /// let data = [0x12, 0x34];
159    /// let mut reader = BitReader::new(&data);
160    ///
161    /// assert_eq!(reader.read_u8()?, 0x12);
162    /// assert_eq!(reader.read_u8()?, 0x34);
163    /// # Ok::<(), oximedia_core::OxiError>(())
164    /// ```
165    #[allow(clippy::cast_possible_truncation)]
166    pub fn read_u8(&mut self) -> OxiResult<u8> {
167        Ok(self.read_bits(8)? as u8)
168    }
169
170    /// Reads a 16-bit unsigned integer in big-endian order.
171    ///
172    /// # Errors
173    ///
174    /// Returns [`OxiError::UnexpectedEof`] if there are not enough bits.
175    ///
176    /// # Example
177    ///
178    /// ```
179    /// use oximedia_io::bits::BitReader;
180    ///
181    /// let data = [0x12, 0x34];
182    /// let mut reader = BitReader::new(&data);
183    ///
184    /// assert_eq!(reader.read_u16()?, 0x1234);
185    /// # Ok::<(), oximedia_core::OxiError>(())
186    /// ```
187    #[allow(clippy::cast_possible_truncation)]
188    pub fn read_u16(&mut self) -> OxiResult<u16> {
189        Ok(self.read_bits(16)? as u16)
190    }
191
192    /// Reads a 32-bit unsigned integer in big-endian order.
193    ///
194    /// # Errors
195    ///
196    /// Returns [`OxiError::UnexpectedEof`] if there are not enough bits.
197    ///
198    /// # Example
199    ///
200    /// ```
201    /// use oximedia_io::bits::BitReader;
202    ///
203    /// let data = [0x12, 0x34, 0x56, 0x78];
204    /// let mut reader = BitReader::new(&data);
205    ///
206    /// assert_eq!(reader.read_u32()?, 0x12345678);
207    /// # Ok::<(), oximedia_core::OxiError>(())
208    /// ```
209    #[allow(clippy::cast_possible_truncation)]
210    pub fn read_u32(&mut self) -> OxiResult<u32> {
211        Ok(self.read_bits(32)? as u32)
212    }
213
214    /// Reads a 64-bit unsigned integer in big-endian order.
215    ///
216    /// # Errors
217    ///
218    /// Returns [`OxiError::UnexpectedEof`] if there are not enough bits.
219    ///
220    /// # Example
221    ///
222    /// ```
223    /// use oximedia_io::bits::BitReader;
224    ///
225    /// let data = [0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0];
226    /// let mut reader = BitReader::new(&data);
227    ///
228    /// assert_eq!(reader.read_u64()?, 0x123456789ABCDEF0);
229    /// # Ok::<(), oximedia_core::OxiError>(())
230    /// ```
231    pub fn read_u64(&mut self) -> OxiResult<u64> {
232        self.read_bits(64)
233    }
234
235    /// Reads a boolean flag (single bit).
236    ///
237    /// Returns `true` if the bit is 1, `false` if 0.
238    ///
239    /// # Errors
240    ///
241    /// Returns [`OxiError::UnexpectedEof`] if there are no more bits.
242    ///
243    /// # Example
244    ///
245    /// ```
246    /// use oximedia_io::bits::BitReader;
247    ///
248    /// let data = [0b10000000];
249    /// let mut reader = BitReader::new(&data);
250    ///
251    /// assert!(reader.read_flag()?);
252    /// assert!(!reader.read_flag()?);
253    /// # Ok::<(), oximedia_core::OxiError>(())
254    /// ```
255    pub fn read_flag(&mut self) -> OxiResult<bool> {
256        Ok(self.read_bit()? != 0)
257    }
258
259    /// Skips the specified number of bits.
260    ///
261    /// This method silently ignores attempts to skip past the end of data.
262    ///
263    /// # Example
264    ///
265    /// ```
266    /// use oximedia_io::bits::BitReader;
267    ///
268    /// let data = [0xFF, 0x00];
269    /// let mut reader = BitReader::new(&data);
270    ///
271    /// reader.skip_bits(4);
272    /// assert_eq!(reader.bits_read(), 4);
273    /// ```
274    pub fn skip_bits(&mut self, n: usize) {
275        for _ in 0..n {
276            if self.read_bit().is_err() {
277                break;
278            }
279        }
280    }
281
282    /// Aligns the reader to the next byte boundary.
283    ///
284    /// If the reader is already at a byte boundary, this is a no-op.
285    /// Otherwise, the remaining bits in the current byte are skipped.
286    ///
287    /// # Example
288    ///
289    /// ```
290    /// use oximedia_io::bits::BitReader;
291    ///
292    /// let data = [0xFF, 0x00];
293    /// let mut reader = BitReader::new(&data);
294    ///
295    /// reader.read_bits(3)?;  // Read 3 bits
296    /// reader.byte_align();           // Skip remaining 5 bits
297    /// assert_eq!(reader.bits_read(), 8);
298    /// # Ok::<(), oximedia_core::OxiError>(())
299    /// ```
300    pub fn byte_align(&mut self) {
301        if self.bit_pos != 0 {
302            self.bit_pos = 0;
303            self.byte_pos += 1;
304        }
305    }
306
307    /// Returns `true` if there is more data available to read.
308    ///
309    /// # Example
310    ///
311    /// ```
312    /// use oximedia_io::bits::BitReader;
313    ///
314    /// let data = [0xFF];
315    /// let mut reader = BitReader::new(&data);
316    ///
317    /// assert!(reader.has_more_data());
318    /// reader.read_bits(8)?;
319    /// assert!(!reader.has_more_data());
320    /// # Ok::<(), oximedia_core::OxiError>(())
321    /// ```
322    #[must_use]
323    pub fn has_more_data(&self) -> bool {
324        self.byte_pos < self.data.len()
325    }
326
327    /// Returns the number of complete bytes remaining.
328    ///
329    /// This does not count partial bytes at the current position.
330    ///
331    /// # Example
332    ///
333    /// ```
334    /// use oximedia_io::bits::BitReader;
335    ///
336    /// let data = [0xFF, 0x00, 0xFF];
337    /// let mut reader = BitReader::new(&data);
338    ///
339    /// assert_eq!(reader.remaining_bytes(), 3);
340    /// reader.read_bits(4)?;
341    /// assert_eq!(reader.remaining_bytes(), 2);  // Partial byte not counted
342    /// # Ok::<(), oximedia_core::OxiError>(())
343    /// ```
344    #[must_use]
345    pub fn remaining_bytes(&self) -> usize {
346        if self.byte_pos >= self.data.len() {
347            0
348        } else {
349            self.data.len() - self.byte_pos - usize::from(self.bit_pos > 0)
350        }
351    }
352
353    /// Returns the total number of bits read so far.
354    ///
355    /// # Example
356    ///
357    /// ```
358    /// use oximedia_io::bits::BitReader;
359    ///
360    /// let data = [0xFF, 0x00];
361    /// let mut reader = BitReader::new(&data);
362    ///
363    /// assert_eq!(reader.bits_read(), 0);
364    /// reader.read_bits(5)?;
365    /// assert_eq!(reader.bits_read(), 5);
366    /// reader.read_bits(3)?;
367    /// assert_eq!(reader.bits_read(), 8);
368    /// # Ok::<(), oximedia_core::OxiError>(())
369    /// ```
370    #[must_use]
371    pub fn bits_read(&self) -> usize {
372        self.byte_pos * 8 + self.bit_pos as usize
373    }
374
375    /// Returns the total number of remaining bits.
376    ///
377    /// # Example
378    ///
379    /// ```
380    /// use oximedia_io::bits::BitReader;
381    ///
382    /// let data = [0xFF, 0x00];
383    /// let mut reader = BitReader::new(&data);
384    ///
385    /// assert_eq!(reader.remaining_bits(), 16);
386    /// reader.read_bits(5)?;
387    /// assert_eq!(reader.remaining_bits(), 11);
388    /// # Ok::<(), oximedia_core::OxiError>(())
389    /// ```
390    #[must_use]
391    pub fn remaining_bits(&self) -> usize {
392        if self.byte_pos >= self.data.len() {
393            0
394        } else {
395            (self.data.len() - self.byte_pos) * 8 - self.bit_pos as usize
396        }
397    }
398
399    /// Peeks at the next bit without consuming it.
400    ///
401    /// # Errors
402    ///
403    /// Returns [`OxiError::UnexpectedEof`] if there are no more bits.
404    ///
405    /// # Example
406    ///
407    /// ```
408    /// use oximedia_io::bits::BitReader;
409    ///
410    /// let data = [0b10000000];
411    /// let mut reader = BitReader::new(&data);
412    ///
413    /// assert_eq!(reader.peek_bit()?, 1);
414    /// assert_eq!(reader.peek_bit()?, 1);  // Still 1, not consumed
415    /// assert_eq!(reader.read_bit()?, 1);  // Now consumed
416    /// assert_eq!(reader.peek_bit()?, 0);  // Next bit
417    /// # Ok::<(), oximedia_core::OxiError>(())
418    /// ```
419    pub fn peek_bit(&self) -> OxiResult<u8> {
420        if self.byte_pos >= self.data.len() {
421            return Err(OxiError::UnexpectedEof);
422        }
423
424        Ok((self.data[self.byte_pos] >> (7 - self.bit_pos)) & 1)
425    }
426
427    /// Returns the underlying byte slice.
428    #[must_use]
429    pub const fn data(&self) -> &'a [u8] {
430        self.data
431    }
432
433    /// Returns the current byte position.
434    #[must_use]
435    pub const fn byte_position(&self) -> usize {
436        self.byte_pos
437    }
438
439    /// Returns the current bit position within the current byte (0-7).
440    #[must_use]
441    pub const fn bit_position(&self) -> u8 {
442        self.bit_pos
443    }
444}
445
446#[cfg(test)]
447mod tests {
448    use super::*;
449
450    #[test]
451    fn test_new() {
452        let data = [0xFF, 0x00];
453        let reader = BitReader::new(&data);
454        assert_eq!(reader.byte_position(), 0);
455        assert_eq!(reader.bit_position(), 0);
456        assert!(reader.has_more_data());
457    }
458
459    #[test]
460    fn test_read_bit() {
461        let data = [0b10110100];
462        let mut reader = BitReader::new(&data);
463
464        assert_eq!(reader.read_bit().expect("read_bit should succeed"), 1);
465        assert_eq!(reader.read_bit().expect("read_bit should succeed"), 0);
466        assert_eq!(reader.read_bit().expect("read_bit should succeed"), 1);
467        assert_eq!(reader.read_bit().expect("read_bit should succeed"), 1);
468        assert_eq!(reader.read_bit().expect("read_bit should succeed"), 0);
469        assert_eq!(reader.read_bit().expect("read_bit should succeed"), 1);
470        assert_eq!(reader.read_bit().expect("read_bit should succeed"), 0);
471        assert_eq!(reader.read_bit().expect("read_bit should succeed"), 0);
472    }
473
474    #[test]
475    fn test_read_bits() {
476        let data = [0b10110100, 0b11001010];
477        let mut reader = BitReader::new(&data);
478
479        assert_eq!(
480            reader.read_bits(4).expect("read_bits should succeed"),
481            0b1011
482        );
483        assert_eq!(
484            reader.read_bits(4).expect("read_bits should succeed"),
485            0b0100
486        );
487        assert_eq!(
488            reader.read_bits(8).expect("read_bits should succeed"),
489            0b11001010
490        );
491    }
492
493    #[test]
494    fn test_read_bits_across_bytes() {
495        let data = [0b10110100, 0b11001010];
496        let mut reader = BitReader::new(&data);
497
498        assert_eq!(
499            reader.read_bits(12).expect("read_bits should succeed"),
500            0b101101001100
501        );
502        assert_eq!(
503            reader.read_bits(4).expect("read_bits should succeed"),
504            0b1010
505        );
506    }
507
508    #[test]
509    fn test_read_bits_zero() {
510        let data = [0xFF];
511        let mut reader = BitReader::new(&data);
512        assert_eq!(reader.read_bits(0).expect("read_bits should succeed"), 0);
513        assert_eq!(reader.bits_read(), 0);
514    }
515
516    #[test]
517    fn test_read_bits_too_many() {
518        let data = [0xFF];
519        let mut reader = BitReader::new(&data);
520        let result = reader.read_bits(65);
521        assert!(result.is_err());
522    }
523
524    #[test]
525    fn test_read_u8() {
526        let data = [0x12, 0x34];
527        let mut reader = BitReader::new(&data);
528        assert_eq!(reader.read_u8().expect("read_u8 should succeed"), 0x12);
529        assert_eq!(reader.read_u8().expect("read_u8 should succeed"), 0x34);
530    }
531
532    #[test]
533    fn test_read_u16() {
534        let data = [0x12, 0x34];
535        let mut reader = BitReader::new(&data);
536        assert_eq!(reader.read_u16().expect("read_u16 should succeed"), 0x1234);
537    }
538
539    #[test]
540    fn test_read_u32() {
541        let data = [0x12, 0x34, 0x56, 0x78];
542        let mut reader = BitReader::new(&data);
543        assert_eq!(
544            reader.read_u32().expect("read_u32 should succeed"),
545            0x1234_5678
546        );
547    }
548
549    #[test]
550    fn test_read_u64() {
551        let data = [0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0];
552        let mut reader = BitReader::new(&data);
553        assert_eq!(
554            reader.read_u64().expect("read_u64 should succeed"),
555            0x1234_5678_9ABC_DEF0
556        );
557    }
558
559    #[test]
560    fn test_read_flag() {
561        let data = [0b10100000];
562        let mut reader = BitReader::new(&data);
563        assert!(reader.read_flag().expect("read_flag should succeed"));
564        assert!(!reader.read_flag().expect("read_flag should succeed"));
565        assert!(reader.read_flag().expect("read_flag should succeed"));
566    }
567
568    #[test]
569    fn test_skip_bits() {
570        let data = [0xFF, 0x12];
571        let mut reader = BitReader::new(&data);
572        reader.skip_bits(8);
573        assert_eq!(reader.read_u8().expect("read_u8 should succeed"), 0x12);
574    }
575
576    #[test]
577    fn test_byte_align() {
578        let data = [0xFF, 0x12];
579        let mut reader = BitReader::new(&data);
580        reader.read_bits(3).expect("read_bits should succeed");
581        reader.byte_align();
582        assert_eq!(reader.bits_read(), 8);
583        assert_eq!(reader.read_u8().expect("read_u8 should succeed"), 0x12);
584    }
585
586    #[test]
587    fn test_byte_align_already_aligned() {
588        let data = [0xFF, 0x12];
589        let mut reader = BitReader::new(&data);
590        reader.byte_align();
591        assert_eq!(reader.bits_read(), 0);
592    }
593
594    #[test]
595    fn test_has_more_data() {
596        let data = [0xFF];
597        let mut reader = BitReader::new(&data);
598        assert!(reader.has_more_data());
599        reader.read_bits(8).expect("read_bits should succeed");
600        assert!(!reader.has_more_data());
601    }
602
603    #[test]
604    fn test_remaining_bytes() {
605        let data = [0xFF, 0x00, 0xFF];
606        let mut reader = BitReader::new(&data);
607        assert_eq!(reader.remaining_bytes(), 3);
608        reader.read_bits(4).expect("read_bits should succeed");
609        assert_eq!(reader.remaining_bytes(), 2);
610        reader.read_bits(4).expect("read_bits should succeed");
611        assert_eq!(reader.remaining_bytes(), 2);
612    }
613
614    #[test]
615    fn test_bits_read() {
616        let data = [0xFF, 0x00];
617        let mut reader = BitReader::new(&data);
618        assert_eq!(reader.bits_read(), 0);
619        reader.read_bits(5).expect("read_bits should succeed");
620        assert_eq!(reader.bits_read(), 5);
621        reader.read_bits(3).expect("read_bits should succeed");
622        assert_eq!(reader.bits_read(), 8);
623    }
624
625    #[test]
626    fn test_remaining_bits() {
627        let data = [0xFF, 0x00];
628        let mut reader = BitReader::new(&data);
629        assert_eq!(reader.remaining_bits(), 16);
630        reader.read_bits(5).expect("read_bits should succeed");
631        assert_eq!(reader.remaining_bits(), 11);
632    }
633
634    #[test]
635    fn test_peek_bit() {
636        let data = [0b10000000];
637        let mut reader = BitReader::new(&data);
638        assert_eq!(reader.peek_bit().expect("peek_bit should succeed"), 1);
639        assert_eq!(reader.peek_bit().expect("peek_bit should succeed"), 1);
640        assert_eq!(reader.bits_read(), 0);
641        reader.read_bit().expect("read_bit should succeed");
642        assert_eq!(reader.peek_bit().expect("peek_bit should succeed"), 0);
643    }
644
645    #[test]
646    fn test_eof() {
647        let data = [0xFF];
648        let mut reader = BitReader::new(&data);
649        reader.read_bits(8).expect("read_bits should succeed");
650        assert!(reader.read_bit().is_err());
651        assert!(reader.read_bits(1).is_err());
652        assert!(reader.peek_bit().is_err());
653    }
654
655    #[test]
656    fn test_empty_data() {
657        let data: [u8; 0] = [];
658        let reader = BitReader::new(&data);
659        assert!(!reader.has_more_data());
660        assert_eq!(reader.remaining_bytes(), 0);
661        assert_eq!(reader.remaining_bits(), 0);
662    }
663
664    // Additional comprehensive tests
665
666    #[test]
667    fn test_read_64_bits_max() {
668        let data = [0xFF; 8];
669        let mut reader = BitReader::new(&data);
670        let value = reader.read_bits(64).expect("read_bits should succeed");
671        assert_eq!(value, u64::MAX);
672    }
673
674    #[test]
675    fn test_read_across_multiple_bytes() {
676        // Test reading across 3 byte boundaries
677        let data = [0b10101010, 0b11001100, 0b11110000];
678        let mut reader = BitReader::new(&data);
679
680        assert_eq!(
681            reader.read_bits(4).expect("read_bits should succeed"),
682            0b1010
683        );
684        assert_eq!(
685            reader.read_bits(8).expect("read_bits should succeed"),
686            0b1010_1100
687        );
688        assert_eq!(
689            reader.read_bits(12).expect("read_bits should succeed"),
690            0b1100_1111_0000
691        );
692    }
693
694    #[test]
695    fn test_mixed_read_operations() {
696        let data = [0b11010010, 0b10110100];
697        let mut reader = BitReader::new(&data);
698
699        assert!(reader.read_flag().expect("read_flag should succeed")); // 1
700        assert!(reader.read_flag().expect("read_flag should succeed")); // 1
701        assert!(!reader.read_flag().expect("read_flag should succeed")); // 0
702        assert_eq!(
703            reader.read_bits(5).expect("read_bits should succeed"),
704            0b10010
705        ); // 10010
706        assert_eq!(
707            reader.read_u8().expect("read_u8 should succeed"),
708            0b10110100
709        );
710    }
711
712    #[test]
713    fn test_byte_align_at_boundary() {
714        let data = [0xFF, 0x12, 0x34];
715        let mut reader = BitReader::new(&data);
716
717        reader.byte_align(); // Should do nothing
718        assert_eq!(reader.bits_read(), 0);
719
720        reader.read_bits(8).expect("read_bits should succeed");
721        reader.byte_align(); // Should still do nothing
722        assert_eq!(reader.bits_read(), 8);
723    }
724
725    #[test]
726    fn test_skip_bits_partial_byte() {
727        let data = [0xFF, 0x12];
728        let mut reader = BitReader::new(&data);
729
730        reader.skip_bits(3);
731        assert_eq!(
732            reader.read_bits(5).expect("read_bits should succeed"),
733            0b11111
734        );
735        assert_eq!(reader.read_u8().expect("read_u8 should succeed"), 0x12);
736    }
737
738    #[test]
739    fn test_skip_bits_beyond_end() {
740        let data = [0xFF];
741        let mut reader = BitReader::new(&data);
742
743        reader.skip_bits(100); // Should stop at end
744        assert!(!reader.has_more_data());
745    }
746
747    #[test]
748    fn test_remaining_methods_consistency() {
749        let data = [0xFF, 0x00, 0xFF, 0x00];
750        let mut reader = BitReader::new(&data);
751
752        assert_eq!(reader.remaining_bits(), 32);
753        assert_eq!(reader.remaining_bytes(), 4);
754
755        reader.read_bits(5).expect("read_bits should succeed");
756        assert_eq!(reader.remaining_bits(), 27);
757        assert_eq!(reader.remaining_bytes(), 3);
758
759        reader.read_bits(11).expect("read_bits should succeed"); // Total 16 bits = 2 bytes
760        assert_eq!(reader.remaining_bits(), 16);
761        assert_eq!(reader.remaining_bytes(), 2);
762    }
763
764    #[test]
765    fn test_peek_doesnt_consume() {
766        let data = [0b10110100];
767        let mut reader = BitReader::new(&data);
768
769        for _ in 0..10 {
770            assert_eq!(reader.peek_bit().expect("peek_bit should succeed"), 1);
771        }
772        assert_eq!(reader.bits_read(), 0);
773
774        reader.read_bit().expect("read_bit should succeed");
775        for _ in 0..10 {
776            assert_eq!(reader.peek_bit().expect("peek_bit should succeed"), 0);
777        }
778        assert_eq!(reader.bits_read(), 1);
779    }
780
781    #[test]
782    fn test_read_all_integer_types() {
783        // Test reading all integer types in sequence
784        let data = [
785            0x12, // u8
786            0x34, 0x56, // u16
787            0x78, 0x9A, 0xBC, 0xDE, // u32
788            0xF0, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, // u64
789        ];
790        let mut reader = BitReader::new(&data);
791
792        assert_eq!(reader.read_u8().expect("read_u8 should succeed"), 0x12);
793        assert_eq!(reader.read_u16().expect("read_u16 should succeed"), 0x3456);
794        assert_eq!(
795            reader.read_u32().expect("read_u32 should succeed"),
796            0x789A_BCDE
797        );
798        assert_eq!(
799            reader.read_u64().expect("read_u64 should succeed"),
800            0xF011_2233_4455_6677
801        );
802        assert!(!reader.has_more_data());
803    }
804
805    #[test]
806    fn test_unaligned_integer_reads() {
807        let data = [0xFF, 0x12, 0x34, 0x56, 0x78];
808        let mut reader = BitReader::new(&data);
809
810        reader.read_bits(4).expect("read_bits should succeed"); // Unalign by 4 bits
811
812        // Now all integer reads should work across byte boundaries
813        assert_eq!(reader.read_bits(8).expect("read_bits should succeed"), 0xF1);
814        assert_eq!(
815            reader.read_bits(16).expect("read_bits should succeed"),
816            0x2345
817        );
818        assert_eq!(reader.read_bits(8).expect("read_bits should succeed"), 0x67);
819    }
820
821    #[test]
822    fn test_position_tracking() {
823        let data = [0xFF, 0x00, 0xFF];
824        let mut reader = BitReader::new(&data);
825
826        assert_eq!(reader.byte_position(), 0);
827        assert_eq!(reader.bit_position(), 0);
828
829        reader.read_bits(10).expect("read_bits should succeed");
830        assert_eq!(reader.byte_position(), 1);
831        assert_eq!(reader.bit_position(), 2);
832
833        reader.byte_align();
834        assert_eq!(reader.byte_position(), 2);
835        assert_eq!(reader.bit_position(), 0);
836    }
837
838    #[test]
839    fn test_data_accessor() {
840        let data = [0xFF, 0x00, 0xFF];
841        let reader = BitReader::new(&data);
842
843        assert_eq!(reader.data(), &data);
844        assert_eq!(reader.data().len(), 3);
845    }
846
847    #[test]
848    fn test_single_bit_pattern() {
849        // Test reading alternating bit pattern
850        let data = [0b10101010];
851        let mut reader = BitReader::new(&data);
852
853        for i in 0..8 {
854            let expected = if i % 2 == 0 { 1 } else { 0 };
855            assert_eq!(
856                reader.read_bit().expect("read_bit should succeed"),
857                expected
858            );
859        }
860    }
861
862    #[test]
863    fn test_eof_on_exact_boundary() {
864        let data = [0xFF];
865        let mut reader = BitReader::new(&data);
866
867        reader.read_bits(8).expect("read_bits should succeed");
868        assert!(!reader.has_more_data());
869        assert_eq!(reader.remaining_bits(), 0);
870
871        let result = reader.read_bit();
872        assert!(result.is_err());
873    }
874}