1use super::Message;
4
5impl Message {
6 #[inline]
29 pub fn decode_into(&self, data: &[u8], out: &mut [f64]) -> usize {
30 let min_bytes = self.min_bytes_required() as usize;
32 if data.len() < min_bytes {
33 return 0;
34 }
35
36 let signals = self.signals();
37 let count = signals.len().min(out.len());
38
39 for (i, out_val) in out.iter_mut().enumerate().take(count) {
40 if let Some(signal) = signals.at(i) {
41 if let Ok((_, physical)) = signal.decode_raw(data) {
43 *out_val = physical;
44 } else {
45 *out_val = 0.0;
46 }
47 }
48 }
49
50 count
51 }
52
53 #[inline]
65 pub fn decode_raw_into(&self, data: &[u8], out: &mut [i64]) -> usize {
66 let min_bytes = self.min_bytes_required() as usize;
67 if data.len() < min_bytes {
68 return 0;
69 }
70
71 let signals = self.signals();
72 let count = signals.len().min(out.len());
73
74 for (i, out_val) in out.iter_mut().enumerate().take(count) {
75 if let Some(signal) = signals.at(i) {
76 if let Ok((raw, _)) = signal.decode_raw(data) {
77 *out_val = raw;
78 } else {
79 *out_val = 0;
80 }
81 }
82 }
83
84 count
85 }
86
87 #[inline]
91 pub fn decode_signal(&self, index: usize, data: &[u8]) -> Option<f64> {
92 let signal = self.signals().at(index)?;
93 signal.decode_raw(data).ok().map(|(_, physical)| physical)
94 }
95
96 #[inline]
100 pub fn decode_signal_raw(&self, index: usize, data: &[u8]) -> Option<i64> {
101 let signal = self.signals().at(index)?;
102 signal.decode_raw(data).ok().map(|(raw, _)| raw)
103 }
104}
105
106#[cfg(test)]
107mod tests {
108 use crate::Dbc;
109
110 #[test]
111 fn test_decode_into_basic() {
112 let dbc = Dbc::parse(
113 r#"VERSION "1.0"
114
115BU_: ECM
116
117BO_ 256 Engine : 8 ECM
118 SG_ RPM : 0|16@1+ (0.25,0) [0|8000] "rpm" *
119 SG_ Temp : 16|8@1- (1,-40) [-40|215] "C" *
120"#,
121 )
122 .unwrap();
123
124 let msg = dbc.messages().find_by_id(256).unwrap();
125
126 let payload = [0x40, 0x1F, 0x5A, 0x00, 0x00, 0x00, 0x00, 0x00];
128 let mut values = [0.0f64; 8];
129
130 let count = msg.decode_into(&payload, &mut values);
131
132 assert_eq!(count, 2);
133 assert_eq!(values[0], 2000.0); assert_eq!(values[1], 50.0); }
136
137 #[test]
138 fn test_decode_raw_into() {
139 let dbc = Dbc::parse(
140 r#"VERSION "1.0"
141
142BU_: ECM
143
144BO_ 256 Engine : 8 ECM
145 SG_ RPM : 0|16@1+ (0.25,0) [0|8000] "rpm" *
146"#,
147 )
148 .unwrap();
149
150 let msg = dbc.messages().find_by_id(256).unwrap();
151
152 let payload = [0x40, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00];
153 let mut raw_values = [0i64; 8];
154
155 let count = msg.decode_raw_into(&payload, &mut raw_values);
156
157 assert_eq!(count, 1);
158 assert_eq!(raw_values[0], 8000); }
160
161 #[test]
162 fn test_decode_into_payload_too_short() {
163 let dbc = Dbc::parse(
164 r#"VERSION "1.0"
165
166BU_: ECM
167
168BO_ 256 Engine : 8 ECM
169 SG_ RPM : 0|16@1+ (1,0) [0|65535] "rpm" *
170"#,
171 )
172 .unwrap();
173
174 let msg = dbc.messages().find_by_id(256).unwrap();
175
176 let payload = [0x40];
178 let mut values = [0.0f64; 8];
179
180 let count = msg.decode_into(&payload, &mut values);
181
182 assert_eq!(count, 0);
183 }
184
185 #[test]
186 fn test_decode_signal_by_index() {
187 let dbc = Dbc::parse(
188 r#"VERSION "1.0"
189
190BU_: ECM
191
192BO_ 256 Engine : 8 ECM
193 SG_ RPM : 0|16@1+ (0.25,0) [0|8000] "rpm" *
194 SG_ Temp : 16|8@1- (1,-40) [-40|215] "C" *
195"#,
196 )
197 .unwrap();
198
199 let msg = dbc.messages().find_by_id(256).unwrap();
200 let payload = [0x40, 0x1F, 0x5A, 0x00, 0x00, 0x00, 0x00, 0x00];
201
202 assert_eq!(msg.decode_signal(0, &payload), Some(2000.0));
203 assert_eq!(msg.decode_signal(1, &payload), Some(50.0));
204 assert_eq!(msg.decode_signal(2, &payload), None); }
206
207 #[test]
208 fn test_decode_into_buffer_smaller_than_signals() {
209 let dbc = Dbc::parse(
210 r#"VERSION "1.0"
211
212BU_: ECM
213
214BO_ 256 Engine : 8 ECM
215 SG_ Sig1 : 0|8@1+ (1,0) [0|255] "" *
216 SG_ Sig2 : 8|8@1+ (1,0) [0|255] "" *
217 SG_ Sig3 : 16|8@1+ (1,0) [0|255] "" *
218"#,
219 )
220 .unwrap();
221
222 let msg = dbc.messages().find_by_id(256).unwrap();
223 let payload = [0x01, 0x02, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00];
224
225 let mut values = [0.0f64; 2];
227 let count = msg.decode_into(&payload, &mut values);
228
229 assert_eq!(count, 2);
230 assert_eq!(values[0], 1.0);
231 assert_eq!(values[1], 2.0);
232 }
233}