hdf5_reader/messages/
shared.rs1use crate::error::{Error, Result};
8use crate::io::Cursor;
9
10#[derive(Debug, Clone)]
12pub enum SharedMessage {
13 SharedInOhdr {
15 message_type: u16,
17 address: u64,
19 },
20 SharedInSohm {
22 message_type: u16,
24 heap_id: Vec<u8>,
26 },
27}
28
29pub fn parse(
35 cursor: &mut Cursor<'_>,
36 message_type: u16,
37 offset_size: u8,
38 _length_size: u8,
39 msg_size: usize,
40) -> Result<SharedMessage> {
41 let start = cursor.position();
42 let version = cursor.read_u8()?;
43
44 let msg = match version {
45 1 => {
46 let _type_field = cursor.read_u8()?;
48 let _reserved = cursor.read_bytes(6)?;
49 let address = cursor.read_offset(offset_size)?;
50 SharedMessage::SharedInOhdr {
51 message_type,
52 address,
53 }
54 }
55 2 => {
56 let type_field = cursor.read_u8()?;
57 cursor.skip(2)?;
58 match type_field {
59 0 => {
60 let address = cursor.read_offset(offset_size)?;
61 SharedMessage::SharedInOhdr {
62 message_type,
63 address,
64 }
65 }
66 t => {
67 return Err(Error::InvalidData(format!(
68 "unknown shared message v2 type: {}",
69 t
70 )));
71 }
72 }
73 }
74 3 => {
75 let type_field = cursor.read_u8()?;
76 cursor.skip(2)?;
77 match type_field {
78 1 => {
79 let heap_id = cursor.read_bytes(8)?.to_vec();
80 SharedMessage::SharedInSohm {
81 message_type,
82 heap_id,
83 }
84 }
85 2 => {
86 let address = cursor.read_offset(offset_size)?;
87 SharedMessage::SharedInOhdr {
88 message_type,
89 address,
90 }
91 }
92 t => {
93 return Err(Error::InvalidData(format!(
94 "unsupported shared message v3 type: {}",
95 t
96 )));
97 }
98 }
99 }
100 v => {
101 return Err(Error::InvalidData(format!(
102 "unsupported shared message version: {}",
103 v
104 )));
105 }
106 };
107
108 let consumed = (cursor.position() - start) as usize;
109 if consumed < msg_size {
110 cursor.skip(msg_size - consumed)?;
111 }
112
113 Ok(msg)
114}
115
116#[cfg(test)]
117mod tests {
118 use super::*;
119 use crate::messages::MSG_DATATYPE;
120
121 #[test]
122 fn parses_v2_object_header_reference_with_padding() {
123 let mut bytes = Vec::new();
124 bytes.push(2);
125 bytes.push(0);
126 bytes.extend_from_slice(&[0, 0]);
127 bytes.extend_from_slice(&0x1234u64.to_le_bytes());
128
129 let mut cursor = Cursor::new(&bytes);
130 let message = parse(&mut cursor, MSG_DATATYPE, 8, 8, bytes.len()).unwrap();
131 match message {
132 SharedMessage::SharedInOhdr {
133 message_type,
134 address,
135 } => {
136 assert_eq!(message_type, MSG_DATATYPE);
137 assert_eq!(address, 0x1234);
138 }
139 other => panic!("expected OHDR reference, got {:?}", other),
140 }
141 }
142
143 #[test]
144 fn parses_v3_sohm_heap_id_with_padding() {
145 let mut bytes = Vec::new();
146 bytes.push(3);
147 bytes.push(1);
148 bytes.extend_from_slice(&[0, 0]);
149 bytes.extend_from_slice(&[1, 2, 3, 4, 5, 6, 7, 8]);
150
151 let mut cursor = Cursor::new(&bytes);
152 let message = parse(&mut cursor, MSG_DATATYPE, 8, 8, bytes.len()).unwrap();
153 match message {
154 SharedMessage::SharedInSohm {
155 message_type,
156 heap_id,
157 } => {
158 assert_eq!(message_type, MSG_DATATYPE);
159 assert_eq!(heap_id, vec![1, 2, 3, 4, 5, 6, 7, 8]);
160 }
161 other => panic!("expected SOHM reference, got {:?}", other),
162 }
163 }
164}