1use super::{AsRawMsg, HDR_LENGTH, RawMsg, u32_to_u8s, u64_from_u8s, u64_to_u8s};
5use crate::{Error, Result};
6use std::io::prelude::*;
7
8pub(crate) const MEASURE: u8 = 1;
9
10#[derive(Clone, Debug, PartialEq)]
11pub struct Msg {
12 pub sid: u32,
13 pub program_uid: u32,
14 pub num_fields: u8,
18 pub fields: Vec<u64>,
19}
20
21fn deserialize_fields(buf: &[u8]) -> Result<Vec<u64>> {
22 buf.chunks(8)
23 .map(|sl| {
24 if sl.len() < 8 {
25 Err(Error(format!("not long enough: {:?}", sl)))
26 } else {
27 Ok(u64_from_u8s(sl))
28 }
29 })
30 .collect()
31}
32
33impl AsRawMsg for Msg {
34 fn get_hdr(&self) -> (u8, u32, u32) {
35 (
36 MEASURE,
37 HDR_LENGTH + 8 + u32::from(self.num_fields) * 8,
38 self.sid,
39 )
40 }
41
42 fn get_u32s<W: Write>(&self, w: &mut W) -> Result<()> {
43 let mut buf = [0u8; 4];
44 u32_to_u8s(&mut buf, self.program_uid);
45 w.write_all(&buf[..])?;
46 u32_to_u8s(&mut buf, u32::from(self.num_fields));
47 w.write_all(&buf[..])?;
48 Ok(())
49 }
50
51 fn get_bytes<W: Write>(&self, w: &mut W) -> Result<()> {
52 let mut buf = [0u8; 8];
53 for f in &self.fields {
54 u64_to_u8s(&mut buf, *f);
55 w.write_all(&buf[..])?;
56 }
57
58 Ok(())
59 }
60
61 fn from_raw_msg(msg: RawMsg) -> Result<Self> {
62 let u32s = unsafe { msg.get_u32s() }?;
63 let b = msg.get_bytes()?;
64
65 Ok(Msg {
66 sid: msg.sid,
67 program_uid: u32s[0],
68 num_fields: u32s[1] as u8,
69 fields: deserialize_fields(b)?,
70 })
71 }
72}
73
74#[cfg(test)]
75mod tests {
76 macro_rules! check_measure_msg {
77 ($id: ident, $sid:expr_2021, $program_uid:expr_2021, $fields:expr_2021) => {
78 check_msg!(
79 $id,
80 super::Msg,
81 super::Msg {
82 sid: $sid,
83 program_uid: $program_uid,
84 num_fields: $fields.len() as u8,
85 fields: $fields,
86 },
87 crate::serialize::Msg::Ms(mes),
88 mes
89 );
90 };
91 }
92
93 check_measure_msg!(
94 test_measure_1,
95 15,
96 72,
97 vec![424242, 65535, 65530, 200000, 150000]
98 );
99 check_measure_msg!(
100 test_measure_2,
101 256,
102 19,
103 vec![42424242, 65536, 65531, 100000, 50000]
104 );
105 check_measure_msg!(
106 test_measure_3,
107 32,
108 3,
109 vec![
110 42424242, 42424242, 42424242, 42424242, 42424242, 42424242, 42424242, 42424242,
111 42424242, 42424242, 42424242, 42424242, 42424242, 42424242, 42424242, 42424242,
112 42424242, 42424242, 42424242, 42424242, 42424242, 42424242, 42424242, 42424242,
113 42424242, 42424242, 42424242, 42424242, 42424242, 42424242, 42424242, 42424242
114 ]
115 );
116}