From f34e3fb80c3057ff608e6588935a5e160248ac3f Mon Sep 17 00:00:00 2001 From: zhuyu4839 Date: Fri, 13 Sep 2024 14:03:46 +0800 Subject: [PATCH 1/5] Add decode and encode for Signal --- src/extend/mod.rs | 1 + src/extend/signal.rs | 124 +++++++++++++++++++++++++++++++++++++++++++ src/lib.rs | 1 + 3 files changed, 126 insertions(+) create mode 100644 src/extend/mod.rs create mode 100644 src/extend/signal.rs diff --git a/src/extend/mod.rs b/src/extend/mod.rs new file mode 100644 index 0000000..2330106 --- /dev/null +++ b/src/extend/mod.rs @@ -0,0 +1 @@ +mod signal; diff --git a/src/extend/signal.rs b/src/extend/signal.rs new file mode 100644 index 0000000..9098d92 --- /dev/null +++ b/src/extend/signal.rs @@ -0,0 +1,124 @@ +use crate::{ByteOrder, Signal, ValueType}; + +impl Signal { + /// Decodes/Extracts a signal from the message data + /// + /// # Params + /// + /// * data: source data + /// + /// # Return + /// + /// Raw signal value + pub fn decode(&self, data: &[u8]) -> u64 { + if self.signal_size == 0 { + return 0; + } + + let mut result = 0; + match self.byte_order { + ByteOrder::LittleEndian => { + let mut src_bit = self.start_bit as usize; + let mut dst_bit = 0; + for _ in 0..self.signal_size { + /* copy bit */ + if (data[src_bit / 8] & (1 << (src_bit % 8))) > 0 { + result |= 1 << dst_bit; + } + + /* calculate next position */ + src_bit += 1; + dst_bit += 1; + } + }, + ByteOrder::BigEndian => { + let mut src_bit = self.start_bit as usize; + let mut dst_bit = self.signal_size - 1; + for _ in 0..self.signal_size { + /* copy bit */ + if (data[src_bit / 8] & (1 << (src_bit % 8))) > 0 { + result |= 1 << dst_bit; + } + + /* calculate next position */ + if (src_bit % 8) == 0 { + src_bit += 15; + } + else { + src_bit -= 1; + } + dst_bit -= 1; + } + }, + } + + match self.value_type() { + ValueType::Signed => { + if (result & (1 << (self.signal_size - 1))) > 0 { + for i in self.signal_size..64 { + result |= 1 << i; + } + } + }, + ValueType::Unsigned => {} + } + + result + } + + /// Encodes a signal into the message data + /// + /// # Params + /// + /// * data: source data + /// + /// * value: Raw signal value + pub fn encode(&self, data: &mut Vec, value: u64) { + if self.signal_size == 0 { + return; + } + + match self.byte_order { + ByteOrder::LittleEndian => { + let mut src_bit = self.start_bit as usize; + let mut dst_bit = 0; + for _ in 0..self.signal_size { + /* copy bit */ + if (value & 1 << dst_bit) > 0 { + data[src_bit / 8] |= 1 << (src_bit % 8); + } + else { + data[src_bit / 8] &= !(1 << (src_bit % 8)); + } + + /* calculate next position */ + src_bit += 1; + dst_bit += 1; + } + }, + ByteOrder::BigEndian => { + let mut src_bit = self.start_bit as usize; + let mut dst_bit = self.signal_size - 1; + for _ in 0..self.signal_size { + /* copy bit */ + if (value & 1 << dst_bit) > 0 { + data[src_bit / 8] |= 1 << (dst_bit % 8); + } + else { + data[src_bit / 8] &= !(1 << (src_bit % 8)); + } + + /* calculate next position */ + if (src_bit % 8) == 0 { + src_bit += 15; + } + else { + src_bit -= 1; + } + dst_bit -= 1; + } + }, + } + } +} + diff --git a/src/lib.rs b/src/lib.rs index 2ee1407..a3cb8f0 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -46,6 +46,7 @@ use std::convert::TryFrom; use derive_getters::Getters; pub mod parser; +mod extend; #[cfg(test)] mod tests { From 83bff97cc6f35f8fc2102f9d9f3820ce1e4904d7 Mon Sep 17 00:00:00 2001 From: blockish Date: Tue, 25 Mar 2025 10:11:04 +0800 Subject: [PATCH 2/5] added `Value` struct --- Cargo.toml | 3 ++- src/extend/mod.rs | 37 +++++++++++++++++++++++++++++++++++++ src/extend/signal.rs | 29 +++++++++++++++++++++++++---- src/lib.rs | 1 + 4 files changed, 65 insertions(+), 5 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 4062646..eadcf91 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -14,8 +14,9 @@ travis-ci = { repository = "marcelbuesing/can-dbc", branch = "dev" } codecov = { repository = "marcelbuesing/can-dbc", branch = "dev", service = "github" } [dependencies] -derive-getters = "0.3" +derive-getters = "0.5" nom = { version = "7.1", features = ["alloc"] } +num = "0.4" serde = { version = "1.0", optional = true } serde_derive = { version = "1.0", optional = true } diff --git a/src/extend/mod.rs b/src/extend/mod.rs index 2330106..6a2f3f9 100644 --- a/src/extend/mod.rs +++ b/src/extend/mod.rs @@ -1 +1,38 @@ mod signal; + +use derive_getters::Getters; + +/// DBC value +#[derive(Debug, Clone, Getters)] +pub struct Value { + pub(crate) name: String, + #[getter(rename = "raw_value")] + #[getter(copy)] + pub(crate) raw: u64, + #[getter(copy)] + pub(crate) offset: f64, + #[getter(copy)] + pub(crate) factor: f64, + pub(crate) unit: String, +} + +impl Value { + /// Get the value of the signal + #[inline] + pub fn value(&self) -> T + where + T: num::NumCast + Default, + { + T::from( + self.raw as f64 * self.factor + self.offset + ).unwrap_or_default() + } + /// Get the value and unit of the signal as a string + #[inline] + pub fn value_string(&self) -> String + where + T: num::NumCast + Default + std::fmt::Display, + { + format!("{} {}", self.value::(), self.unit) + } +} diff --git a/src/extend/signal.rs b/src/extend/signal.rs index 9098d92..b8b8e1f 100644 --- a/src/extend/signal.rs +++ b/src/extend/signal.rs @@ -1,6 +1,27 @@ use crate::{ByteOrder, Signal, ValueType}; +use super::Value; impl Signal { + /// Decodes/Extracts a signal from the message data as a [`Value`] + /// + /// # Params + /// + /// * data: source data + /// + /// # Return + /// + /// [`Value`] if the size of signal is not zero + pub fn decode_value(&self, data: &[u8]) -> Option { + self.decode(data) + .map(|v| Value { + name: self.name.clone(), + raw: v, + offset: self.offset, + factor: self.factor, + unit: self.unit.clone(), + }) + } + /// Decodes/Extracts a signal from the message data /// /// # Params @@ -9,10 +30,10 @@ impl Signal { /// /// # Return /// - /// Raw signal value - pub fn decode(&self, data: &[u8]) -> u64 { + /// Raw signal value if the size of signal is not zero + pub fn decode(&self, data: &[u8]) -> Option { if self.signal_size == 0 { - return 0; + return None; } let mut result = 0; @@ -63,7 +84,7 @@ impl Signal { ValueType::Unsigned => {} } - result + Some(result) } /// Encodes a signal into the message data diff --git a/src/lib.rs b/src/lib.rs index a3cb8f0..95a7345 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -47,6 +47,7 @@ use derive_getters::Getters; pub mod parser; mod extend; +pub use extend::*; #[cfg(test)] mod tests { From 47ce35f7b18abd1083ab4e3fd7114f88ce6f6fee Mon Sep 17 00:00:00 2001 From: blockish Date: Tue, 25 Mar 2025 11:33:50 +0800 Subject: [PATCH 3/5] added Send and Sync trait impl for Value --- Cargo.toml | 2 +- src/extend/mod.rs | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index eadcf91..cffba88 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -16,7 +16,7 @@ codecov = { repository = "marcelbuesing/can-dbc", branch = "dev", service = "git [dependencies] derive-getters = "0.5" nom = { version = "7.1", features = ["alloc"] } -num = "0.4" +num = { version = "0.4", default-features = false } serde = { version = "1.0", optional = true } serde_derive = { version = "1.0", optional = true } diff --git a/src/extend/mod.rs b/src/extend/mod.rs index 6a2f3f9..b0ed277 100644 --- a/src/extend/mod.rs +++ b/src/extend/mod.rs @@ -16,6 +16,9 @@ pub struct Value { pub(crate) unit: String, } +unsafe impl Send for Value {} +unsafe impl Sync for Value {} + impl Value { /// Get the value of the signal #[inline] From 4e629a952d6e5c9f34c8ccfb3f842e74396bf806 Mon Sep 17 00:00:00 2001 From: blockish Date: Thu, 27 Mar 2025 18:21:47 +0800 Subject: [PATCH 4/5] add length check for signal en/decode --- src/extend/signal.rs | 29 +++++++++++++++++++++++------ 1 file changed, 23 insertions(+), 6 deletions(-) diff --git a/src/extend/signal.rs b/src/extend/signal.rs index b8b8e1f..102e995 100644 --- a/src/extend/signal.rs +++ b/src/extend/signal.rs @@ -36,6 +36,7 @@ impl Signal { return None; } + let len = data.len(); let mut result = 0; match self.byte_order { ByteOrder::LittleEndian => { @@ -43,7 +44,11 @@ impl Signal { let mut dst_bit = 0; for _ in 0..self.signal_size { /* copy bit */ - if (data[src_bit / 8] & (1 << (src_bit % 8))) > 0 { + let index = src_bit / 8; + if index >= len { + return None; + } + if (data[index] & (1 << (src_bit % 8))) > 0 { result |= 1 << dst_bit; } @@ -57,7 +62,11 @@ impl Signal { let mut dst_bit = self.signal_size - 1; for _ in 0..self.signal_size { /* copy bit */ - if (data[src_bit / 8] & (1 << (src_bit % 8))) > 0 { + let index = src_bit / 8; + if index >= len { + return None; + } + if (data[index] & (1 << (src_bit % 8))) > 0 { result |= 1 << dst_bit; } @@ -105,11 +114,15 @@ impl Signal { let mut dst_bit = 0; for _ in 0..self.signal_size { /* copy bit */ + let index = src_bit / 8; + if index >= data.len() { + data.resize(index + 1, 0); + } if (value & 1 << dst_bit) > 0 { - data[src_bit / 8] |= 1 << (src_bit % 8); + data[index] |= 1 << (src_bit % 8); } else { - data[src_bit / 8] &= !(1 << (src_bit % 8)); + data[index] &= !(1 << (src_bit % 8)); } /* calculate next position */ @@ -122,11 +135,15 @@ impl Signal { let mut dst_bit = self.signal_size - 1; for _ in 0..self.signal_size { /* copy bit */ + let index = src_bit / 8; + if index >= data.len() { + data.resize(index + 1, 0); + } if (value & 1 << dst_bit) > 0 { - data[src_bit / 8] |= 1 << (dst_bit % 8); + data[index] |= 1 << (dst_bit % 8); } else { - data[src_bit / 8] &= !(1 << (src_bit % 8)); + data[index] &= !(1 << (src_bit % 8)); } /* calculate next position */ From 4fa7699eff359b6ebd5191eef001a98d5c128c95 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Fri, 3 Oct 2025 22:22:51 +0000 Subject: [PATCH 5/5] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- src/extend/mod.rs | 4 +--- src/extend/signal.rs | 40 +++++++++++++++++----------------------- src/lib.rs | 2 +- 3 files changed, 19 insertions(+), 27 deletions(-) diff --git a/src/extend/mod.rs b/src/extend/mod.rs index b0ed277..fd616b8 100644 --- a/src/extend/mod.rs +++ b/src/extend/mod.rs @@ -26,9 +26,7 @@ impl Value { where T: num::NumCast + Default, { - T::from( - self.raw as f64 * self.factor + self.offset - ).unwrap_or_default() + T::from(self.raw as f64 * self.factor + self.offset).unwrap_or_default() } /// Get the value and unit of the signal as a string #[inline] diff --git a/src/extend/signal.rs b/src/extend/signal.rs index 102e995..6994b4b 100644 --- a/src/extend/signal.rs +++ b/src/extend/signal.rs @@ -1,5 +1,5 @@ -use crate::{ByteOrder, Signal, ValueType}; use super::Value; +use crate::{ByteOrder, Signal, ValueType}; impl Signal { /// Decodes/Extracts a signal from the message data as a [`Value`] @@ -12,14 +12,13 @@ impl Signal { /// /// [`Value`] if the size of signal is not zero pub fn decode_value(&self, data: &[u8]) -> Option { - self.decode(data) - .map(|v| Value { - name: self.name.clone(), - raw: v, - offset: self.offset, - factor: self.factor, - unit: self.unit.clone(), - }) + self.decode(data).map(|v| Value { + name: self.name.clone(), + raw: v, + offset: self.offset, + factor: self.factor, + unit: self.unit.clone(), + }) } /// Decodes/Extracts a signal from the message data @@ -56,7 +55,7 @@ impl Signal { src_bit += 1; dst_bit += 1; } - }, + } ByteOrder::BigEndian => { let mut src_bit = self.start_bit as usize; let mut dst_bit = self.signal_size - 1; @@ -73,13 +72,12 @@ impl Signal { /* calculate next position */ if (src_bit % 8) == 0 { src_bit += 15; - } - else { + } else { src_bit -= 1; } dst_bit -= 1; } - }, + } } match self.value_type() { @@ -89,7 +87,7 @@ impl Signal { result |= 1 << i; } } - }, + } ValueType::Unsigned => {} } @@ -120,8 +118,7 @@ impl Signal { } if (value & 1 << dst_bit) > 0 { data[index] |= 1 << (src_bit % 8); - } - else { + } else { data[index] &= !(1 << (src_bit % 8)); } @@ -129,7 +126,7 @@ impl Signal { src_bit += 1; dst_bit += 1; } - }, + } ByteOrder::BigEndian => { let mut src_bit = self.start_bit as usize; let mut dst_bit = self.signal_size - 1; @@ -141,22 +138,19 @@ impl Signal { } if (value & 1 << dst_bit) > 0 { data[index] |= 1 << (dst_bit % 8); - } - else { + } else { data[index] &= !(1 << (src_bit % 8)); } /* calculate next position */ if (src_bit % 8) == 0 { src_bit += 15; - } - else { + } else { src_bit -= 1; } dst_bit -= 1; } - }, + } } } } - diff --git a/src/lib.rs b/src/lib.rs index 1efd861..f22f25e 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -10,8 +10,8 @@ use std::convert::TryFrom; use derive_getters::Getters; -pub mod parser; mod extend; +pub mod parser; pub use extend::*; #[cfg(test)]