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 mut count = 0;
38 for (out_val, signal) in out.iter_mut().zip(self.signals().iter()) {
39 *out_val = signal.decode_raw(data).map(|(_, p)| p).unwrap_or(0.0);
41 count += 1;
42 }
43
44 count
45 }
46
47 #[inline]
59 pub fn decode_raw_into(&self, data: &[u8], out: &mut [i64]) -> usize {
60 let min_bytes = self.min_bytes_required() as usize;
61 if data.len() < min_bytes {
62 return 0;
63 }
64
65 let mut count = 0;
67 for (out_val, signal) in out.iter_mut().zip(self.signals().iter()) {
68 *out_val = signal.decode_raw(data).map(|(r, _)| r).unwrap_or(0);
69 count += 1;
70 }
71
72 count
73 }
74
75 #[inline]
79 pub fn decode_signal(&self, index: usize, data: &[u8]) -> Option<f64> {
80 let signal = self.signals().at(index)?;
81 signal.decode_raw(data).ok().map(|(_, physical)| physical)
82 }
83
84 #[inline]
88 pub fn decode_signal_raw(&self, index: usize, data: &[u8]) -> Option<i64> {
89 let signal = self.signals().at(index)?;
90 signal.decode_raw(data).ok().map(|(raw, _)| raw)
91 }
92}
93
94#[cfg(test)]
95mod tests {
96 use crate::Dbc;
97
98 #[test]
99 fn test_decode_into_basic() {
100 let dbc = Dbc::parse(
101 r#"VERSION "1.0"
102
103BU_: ECM
104
105BO_ 256 Engine : 8 ECM
106 SG_ RPM : 0|16@1+ (0.25,0) [0|8000] "rpm" *
107 SG_ Temp : 16|8@1- (1,-40) [-40|215] "C" *
108"#,
109 )
110 .unwrap();
111
112 let msg = dbc.messages().find_by_id(256).unwrap();
113
114 let payload = [0x40, 0x1F, 0x5A, 0x00, 0x00, 0x00, 0x00, 0x00];
116 let mut values = [0.0f64; 8];
117
118 let count = msg.decode_into(&payload, &mut values);
119
120 assert_eq!(count, 2);
121 assert_eq!(values[0], 2000.0); assert_eq!(values[1], 50.0); }
124
125 #[test]
126 fn test_decode_raw_into() {
127 let dbc = Dbc::parse(
128 r#"VERSION "1.0"
129
130BU_: ECM
131
132BO_ 256 Engine : 8 ECM
133 SG_ RPM : 0|16@1+ (0.25,0) [0|8000] "rpm" *
134"#,
135 )
136 .unwrap();
137
138 let msg = dbc.messages().find_by_id(256).unwrap();
139
140 let payload = [0x40, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00];
141 let mut raw_values = [0i64; 8];
142
143 let count = msg.decode_raw_into(&payload, &mut raw_values);
144
145 assert_eq!(count, 1);
146 assert_eq!(raw_values[0], 8000); }
148
149 #[test]
150 fn test_decode_into_payload_too_short() {
151 let dbc = Dbc::parse(
152 r#"VERSION "1.0"
153
154BU_: ECM
155
156BO_ 256 Engine : 8 ECM
157 SG_ RPM : 0|16@1+ (1,0) [0|65535] "rpm" *
158"#,
159 )
160 .unwrap();
161
162 let msg = dbc.messages().find_by_id(256).unwrap();
163
164 let payload = [0x40];
166 let mut values = [0.0f64; 8];
167
168 let count = msg.decode_into(&payload, &mut values);
169
170 assert_eq!(count, 0);
171 }
172
173 #[test]
174 fn test_decode_signal_by_index() {
175 let dbc = Dbc::parse(
176 r#"VERSION "1.0"
177
178BU_: ECM
179
180BO_ 256 Engine : 8 ECM
181 SG_ RPM : 0|16@1+ (0.25,0) [0|8000] "rpm" *
182 SG_ Temp : 16|8@1- (1,-40) [-40|215] "C" *
183"#,
184 )
185 .unwrap();
186
187 let msg = dbc.messages().find_by_id(256).unwrap();
188 let payload = [0x40, 0x1F, 0x5A, 0x00, 0x00, 0x00, 0x00, 0x00];
189
190 assert_eq!(msg.decode_signal(0, &payload), Some(2000.0));
191 assert_eq!(msg.decode_signal(1, &payload), Some(50.0));
192 assert_eq!(msg.decode_signal(2, &payload), None); }
194
195 #[test]
196 fn test_decode_into_buffer_smaller_than_signals() {
197 let dbc = Dbc::parse(
198 r#"VERSION "1.0"
199
200BU_: ECM
201
202BO_ 256 Engine : 8 ECM
203 SG_ Sig1 : 0|8@1+ (1,0) [0|255] "" *
204 SG_ Sig2 : 8|8@1+ (1,0) [0|255] "" *
205 SG_ Sig3 : 16|8@1+ (1,0) [0|255] "" *
206"#,
207 )
208 .unwrap();
209
210 let msg = dbc.messages().find_by_id(256).unwrap();
211 let payload = [0x01, 0x02, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00];
212
213 let mut values = [0.0f64; 2];
215 let count = msg.decode_into(&payload, &mut values);
216
217 assert_eq!(count, 2);
218 assert_eq!(values[0], 1.0);
219 assert_eq!(values[1], 2.0);
220 }
221}