Skip to content

Commit 5b55dab

Browse files
committed
Restore last bit read during id_pat
* Restore last leftover reading in reader for bit reads during ip_pat
1 parent 41b88b8 commit 5b55dab

File tree

3 files changed

+28
-3
lines changed

3 files changed

+28
-3
lines changed

deku-derive/src/macros/deku_read.rs

+2
Original file line numberDiff line numberDiff line change
@@ -371,6 +371,7 @@ fn emit_enum(input: &DekuData) -> Result<TokenStream, syn::Error> {
371371

372372
let variant_read = quote! {
373373
__deku_reader.last_bits_read_amt = 0;
374+
let __deku_last_leftover = __deku_reader.leftover.clone();
374375
#variant_id_read
375376

376377
#(#pre_match_tokens)*
@@ -822,6 +823,7 @@ fn emit_field_read(
822823
if let Err(e) = __deku_reader.seek_last_read() {
823824
return Err(::#crate_::DekuError::Io(e.kind()));
824825
}
826+
__deku_reader.leftover = __deku_last_leftover;
825827
#type_as_deku_read::from_reader_with_ctx
826828
(
827829
__deku_reader,

src/reader.rs

+6-3
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,9 @@ pub enum ReaderRet {
2121
Bits(Option<BitVec<u8, Msb0>>),
2222
}
2323

24-
#[derive(Debug)]
25-
enum Leftover {
24+
/// Bits or Byte stored from previous read, such as the case of id_pat
25+
#[derive(Debug, Clone)]
26+
pub enum Leftover {
2627
Byte(u8),
2728
#[cfg(feature = "bits")]
2829
Bits(BitVec<u8, Msb0>),
@@ -32,7 +33,7 @@ enum Leftover {
3233
pub struct Reader<'a, R: Read + Seek> {
3334
inner: &'a mut R,
3435
/// bits stored from previous reads that didn't read to the end of a byte size
35-
leftover: Option<Leftover>,
36+
pub leftover: Option<Leftover>,
3637
/// Amount of bits read after last read, reseted before reading enum ids
3738
pub last_bits_read_amt: usize,
3839
/// Amount of bits read during the use of [read_bits](Reader::read_bits) and [read_bytes](Reader::read_bytes)
@@ -75,6 +76,8 @@ impl<'a, R: Read + Seek> Reader<'a, R> {
7576
pub fn seek_last_read(&mut self) -> no_std_io::io::Result<()> {
7677
let number = self.last_bits_read_amt as i64;
7778
let seek_amt = (number / 8).saturating_add((number % 8).signum());
79+
#[cfg(feature = "logging")]
80+
log::trace!("seek_last_read: {seek_amt:?}");
7881
self.seek(SeekFrom::Current(seek_amt.saturating_neg()))?;
7982
self.bits_read -= self.last_bits_read_amt;
8083
self.leftover = None;

tests/test_regression.rs

+20
Original file line numberDiff line numberDiff line change
@@ -385,3 +385,23 @@ fn issue_397() {
385385
}
386386
let _ = Packet::from_bytes((&[0x00, 0x01], 0));
387387
}
388+
389+
#[test]
390+
fn issue_533() {
391+
#[derive(PartialEq, Debug, DekuRead)]
392+
#[deku(id_type = "u8", bits = "1")]
393+
pub enum BitsAndValue {
394+
#[deku(id = 0)]
395+
Zero,
396+
#[deku(id_pat = "_")]
397+
Other(#[deku(bits = 1)] u8),
398+
}
399+
let input = [0b0100_0000];
400+
let mut cursor = Cursor::new(input);
401+
let mut reader = Reader::new(&mut cursor);
402+
let v = BitsAndValue::from_reader_with_ctx(&mut reader, ()).unwrap();
403+
assert_eq!(v, BitsAndValue::Zero);
404+
405+
let v = BitsAndValue::from_reader_with_ctx(&mut reader, ()).unwrap();
406+
assert_eq!(v, BitsAndValue::Other(1));
407+
}

0 commit comments

Comments
 (0)