Skip to content

Commit

Permalink
Support big endian
Browse files Browse the repository at this point in the history
  • Loading branch information
wcampbell0x2a committed Nov 3, 2023
1 parent 704e7cb commit 4067135
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 38 deletions.
60 changes: 24 additions & 36 deletions src/impls/primitive.rs
Original file line number Diff line number Diff line change
Expand Up @@ -673,47 +673,35 @@ macro_rules! ImplDekuWrite {
)));
}

if (endian == Endian::Little) && (order == Order::Lsb0) {
let mut remaining_bits = bit_size;
for chunk in input_bits.chunks(8) {
if chunk.len() > remaining_bits {
writer.write_bits_order(
&chunk[chunk.len() - remaining_bits..],
Order::Lsb0,
)?;
break;
} else {
writer.write_bits_order(&chunk, Order::Lsb0)?;
match (endian, order) {
(Endian::Little, Order::Lsb0)
| (Endian::Little, Order::Msb0)
| (Endian::Big, Order::Lsb0) => {
let mut remaining_bits = bit_size;
for chunk in input_bits.chunks(8) {
if chunk.len() > remaining_bits {
writer.write_bits_order(
&chunk[chunk.len() - remaining_bits..],
order,
)?;
break;
} else {
writer.write_bits_order(&chunk, order)?;
}
remaining_bits -= chunk.len();
}
remaining_bits -= chunk.len();
}
return Ok(());
}

if (endian == Endian::Little) && (order == Order::Msb0) {
// Example read 10 bits u32 [0xAB, 0b11_000000]
// => [10101011, 00000011, 00000000, 00000000]
let mut remaining_bits = bit_size;
for chunk in input_bits.chunks(8) {
if chunk.len() > remaining_bits {
// TODO: allow write_bytes?
writer.write_bits_order(
&chunk[chunk.len() - remaining_bits..],
Order::Msb0,
)?;
break;
} else {
writer.write_bits_order(&chunk, Order::Msb0)?;
}
remaining_bits -= chunk.len();
(Endian::Big, Order::Msb0) => {
// big endian
// Example read 10 bits u32 [0xAB, 0b11_000000]
// => [00000000, 00000000, 00000010, 10101111]
writer.write_bits_order(
&input_bits[input_bits.len() - bit_size..],
Order::Msb0,
)?;
}
return Ok(());
}

// big endian
// Example read 10 bits u32 [0xAB, 0b11_000000]
// => [00000000, 00000000, 00000010, 10101111]
writer.write_bits_order(&input_bits[input_bits.len() - bit_size..], Order::Msb0)?;
Ok(())
}
}
Expand Down
4 changes: 2 additions & 2 deletions src/writer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ impl<'a, W: Write> Writer<'a, W> {
return Err(DekuError::WriteError);
}
#[cfg(feature = "logging")]
log::trace!("wrote {} bits : {:02x?}", buf.len() * 8, &buf);
log::trace!("wrote {} bits : 0x{:02x?}", buf.len() * 8, &buf);
} else {
// This is more complicated, as we need to skip the first bytes until we are "byte aligned"
// TODO: then reverse the buf before writing in the case that bits.len() > one byte buf ?
Expand Down Expand Up @@ -167,7 +167,7 @@ impl<'a, W: Write> Writer<'a, W> {
return Err(DekuError::WriteError);
}
#[cfg(feature = "logging")]
log::trace!("wrote {} bits : {:02x?}", buf.len() * 8, &buf);
log::trace!("wrote {} bits : 0x{:02x?}", buf.len() * 8, &buf);
}

#[cfg(feature = "logging")]
Expand Down
26 changes: 26 additions & 0 deletions tests/bit_order.rs
Original file line number Diff line number Diff line change
Expand Up @@ -297,3 +297,29 @@ fn test_bit_order_custom_reader_writer() {
let bytes = more_first.to_bytes().unwrap();
assert_eq_hex!(bytes, data);
}

#[derive(Debug, DekuRead, DekuWrite, PartialEq)]
#[deku(endian = "big", bit_order = "lsb")]
pub struct MoreFirstBe {
#[deku(bits = "13")]
offset: u16,
#[deku(bits = "3")]
t: u8,
}

#[test]
fn test_bit_order_more_first_be() {
env_logger::init();
let data = vec![0x40, 0x40];
let more_first = MoreFirstBe::try_from(data.as_ref()).unwrap();
assert_eq!(
more_first,
MoreFirstBe {
offset: 0x4000,
t: 2
}
);

let bytes = more_first.to_bytes().unwrap();
assert_eq_hex!(bytes, data);
}

0 comments on commit 4067135

Please sign in to comment.