Skip to main content

hdf5_reader/messages/
shared_table.rs

1//! HDF5 Shared Message Table object-header message (type 0x000F).
2//!
3//! This message appears in the superblock extension and points at the file's
4//! SOHM master table.
5
6use crate::error::{Error, Result};
7use crate::io::Cursor;
8
9/// Pointer to the file-level shared object-header message table.
10#[derive(Debug, Clone)]
11pub struct SharedTableMessage {
12    /// Address of the SOHM master table (`SMTB`).
13    pub table_address: u64,
14    /// Number of shared-message indexes in the master table.
15    pub num_indices: u8,
16}
17
18/// Parse a Shared Message Table message.
19pub fn parse(
20    cursor: &mut Cursor<'_>,
21    offset_size: u8,
22    _length_size: u8,
23    msg_size: usize,
24) -> Result<SharedTableMessage> {
25    let start = cursor.position();
26    let version = cursor.read_u8()?;
27    if version != 0 {
28        return Err(Error::InvalidData(format!(
29            "unsupported shared message table message version: {version}"
30        )));
31    }
32    cursor.skip(3)?;
33
34    let table_address = cursor.read_offset(offset_size)?;
35    let num_indices = cursor.read_u8()?;
36    cursor.skip(3)?;
37
38    let consumed = (cursor.position() - start) as usize;
39    if consumed < msg_size {
40        cursor.skip(msg_size - consumed)?;
41    }
42
43    Ok(SharedTableMessage {
44        table_address,
45        num_indices,
46    })
47}
48
49#[cfg(test)]
50mod tests {
51    use super::*;
52
53    #[test]
54    fn parses_shared_table_message() {
55        let mut bytes = Vec::new();
56        bytes.push(0);
57        bytes.extend_from_slice(&[0, 0, 0]);
58        bytes.extend_from_slice(&0x1234u64.to_le_bytes());
59        bytes.push(2);
60        bytes.extend_from_slice(&[0, 0, 0]);
61
62        let mut cursor = Cursor::new(&bytes);
63        let msg = parse(&mut cursor, 8, 8, bytes.len()).unwrap();
64        assert_eq!(msg.table_address, 0x1234);
65        assert_eq!(msg.num_indices, 2);
66    }
67}