Skip to content

Commit 9bb994f

Browse files
Replace packing and unpacking with bitvec (#7)
1 parent af11785 commit 9bb994f

File tree

9 files changed

+768
-103
lines changed

9 files changed

+768
-103
lines changed

Cargo.lock

Lines changed: 59 additions & 28 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/main.rs

Lines changed: 54 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,10 @@ fn main() -> Result<()> {
5959
writeln!(&mut w, "//!")?;
6060
writeln!(&mut w, "//! - Version: `{:?}`", dbc.version())?;
6161
writeln!(&mut w)?;
62-
writeln!(&mut w, "use bitsh::Pack;")?;
62+
writeln!(
63+
&mut w,
64+
"use bitvec::prelude::{{BitField, BitStore, BitView, LocalBits}};"
65+
)?;
6366
writeln!(w, r##"#[cfg(feature = "arb")]"##)?;
6467
writeln!(&mut w, "use arbitrary::{{Arbitrary, Unstructured}};")?;
6568
writeln!(&mut w)?;
@@ -407,22 +410,30 @@ fn render_signal(mut w: impl Write, signal: &Signal, dbc: &DBC, msg: &Message) -
407410
fn signal_from_payload(mut w: impl Write, signal: &Signal) -> Result<()> {
408411
let read_fn = match signal.byte_order() {
409412
can_dbc::ByteOrder::LittleEndian => format!(
410-
"{typ}::unpack_le_bits(&self.raw, {start}, {size})",
411-
typ = signal_to_rust_int(signal),
413+
"self.raw.view_bits::<LocalBits>()[{start}..{end}].load_le::<{typ}>()",
414+
typ = signal_to_rust_uint(signal),
412415
start = signal.start_bit,
413-
size = signal.signal_size,
416+
end = signal.start_bit + signal.signal_size
414417
),
415418
can_dbc::ByteOrder::BigEndian => format!(
416-
"{typ}::unpack_be_bits(&self.raw, ({start} - ({size} - 1)), {size})",
417-
typ = signal_to_rust_int(signal),
418-
start = signal.start_bit,
419-
size = signal.signal_size,
419+
"self.raw.view_bits::<LocalBits>()[{start}..{end}].load_be::<{typ}>()",
420+
typ = signal_to_rust_uint(signal),
421+
start = signal.start_bit + 1 - signal.signal_size,
422+
end = signal.start_bit + 1,
420423
),
421424
};
422425

423426
writeln!(&mut w, r#"let signal = {};"#, read_fn)?;
424427
writeln!(&mut w)?;
425428

429+
if *signal.value_type() == can_dbc::ValueType::Signed {
430+
writeln!(
431+
&mut w,
432+
"let signal = {}::from_ne_bytes(signal.to_ne_bytes());",
433+
signal_to_rust_int(signal)
434+
)?;
435+
};
436+
426437
if signal.signal_size == 1 {
427438
writeln!(&mut w, "signal == 1")?;
428439
} else if signal_is_float_in_rust(signal) {
@@ -452,18 +463,32 @@ fn signal_to_payload(mut w: impl Write, signal: &Signal) -> Result<()> {
452463
writeln!(&mut w)?;
453464
}
454465

455-
writeln!(&mut w, "let start_bit = {};", signal.start_bit)?;
456-
writeln!(&mut w, "let bits = {};", signal.signal_size)?;
457-
let endianness = match signal.byte_order() {
458-
can_dbc::ByteOrder::LittleEndian => "le",
459-
can_dbc::ByteOrder::BigEndian => "be",
466+
if *signal.value_type() == can_dbc::ValueType::Signed {
467+
writeln!(
468+
&mut w,
469+
"let value = {}::from_ne_bytes(value.to_ne_bytes());",
470+
signal_to_rust_uint(signal)
471+
)?;
460472
};
461473

462-
writeln!(
463-
&mut w,
464-
r#"value.pack_{}_bits(&mut self.raw, start_bit, bits);"#,
465-
endianness
466-
)?;
474+
match signal.byte_order() {
475+
can_dbc::ByteOrder::LittleEndian => {
476+
writeln!(
477+
&mut w,
478+
r#"self.raw.view_bits_mut::<LocalBits>()[{start_bit}..{end_bit}].store_le(value);"#,
479+
start_bit = signal.start_bit,
480+
end_bit = signal.start_bit + signal.signal_size,
481+
)?;
482+
}
483+
can_dbc::ByteOrder::BigEndian => {
484+
writeln!(
485+
&mut w,
486+
r#"self.raw.view_bits_mut::<LocalBits>()[{start_bit}..{end_bit}].store_be(value);"#,
487+
start_bit = signal.start_bit + 1 - signal.signal_size,
488+
end_bit = signal.start_bit + 1,
489+
)?;
490+
}
491+
};
467492

468493
writeln!(&mut w, "Ok(())")?;
469494
Ok(())
@@ -506,6 +531,17 @@ fn signal_to_rust_int(signal: &Signal) -> String {
506531
format!("{}{}", sign, size)
507532
}
508533

534+
fn signal_to_rust_uint(signal: &Signal) -> String {
535+
let size = match *signal.signal_size() {
536+
n if n <= 8 => "8",
537+
n if n <= 16 => "16",
538+
n if n <= 32 => "32",
539+
_ => "64",
540+
};
541+
542+
format!("u{}", size)
543+
}
544+
509545
#[allow(clippy::float_cmp)]
510546
fn signal_is_float_in_rust(signal: &Signal) -> bool {
511547
*signal.offset() != 0.0 || *signal.factor() != 1.0

testing/can-messages/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ edition = "2018"
66

77
[dependencies]
88
arbitrary = { version = "1.0", optional = true }
9-
bitsh = { git = "https://github.com/bitbleep/bitsh/" }
9+
bitvec = { version = "0.21", default-features = false }
1010

1111
[features]
1212
default = ["debug", "arb"]

testing/can-messages/src/lib.rs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,3 +17,27 @@ fn check_range_value_valid() {
1717
let result = messages::Bar::new(1, 2.0, 3, 3);
1818
assert!(result.is_ok());
1919
}
20+
21+
#[test]
22+
fn pack_unpack_message() {
23+
let result = messages::Foo::new(63.99899, 10.0).unwrap();
24+
assert_eq!(result.voltage_raw(), 63.99899);
25+
assert_eq!(result.current_raw(), 10.0);
26+
}
27+
28+
#[test]
29+
fn pack_unpack_message_negative() {
30+
let result = messages::Foo::new(0.000976562, -3.0 * 0.0625).unwrap();
31+
assert_eq!(result.voltage_raw(), 0.000976562);
32+
assert_eq!(result.current_raw(), -3.0 * 0.0625);
33+
}
34+
35+
#[test]
36+
fn pack_unpack_message2() {
37+
let result = messages::Amet::new(1, 0.39, 3, 3, true).unwrap();
38+
assert_eq!(result.one_raw(), 1);
39+
assert_eq!(result.two_raw(), 0.39);
40+
assert_eq!(result.three_raw(), 3);
41+
assert_eq!(result.four_raw(), 3);
42+
assert_eq!(result.five_raw(), true);
43+
}

0 commit comments

Comments
 (0)