Skip to main content

hdf5_reader/messages/
external_files.rs

1//! HDF5 External Data Files message (type 0x0007).
2//!
3//! Indicates that raw data for a dataset is stored in one or more external
4//! files. Rarely used in practice, especially in NetCDF files.
5
6use crate::error::Result;
7use crate::io::Cursor;
8pub use hdf5_core::{ExternalFileSlot, ExternalFilesMessage};
9
10/// Parse an external data files message.
11pub fn parse(
12    cursor: &mut Cursor<'_>,
13    offset_size: u8,
14    length_size: u8,
15    msg_size: usize,
16) -> Result<ExternalFilesMessage> {
17    let start = cursor.position();
18
19    let _version = cursor.read_u8()?;
20    let _reserved = cursor.read_bytes(3)?;
21
22    // Allocated slots (for pre-allocation; may differ from used slots)
23    let _allocated_slots = cursor.read_u16_le()?;
24    // Used slots — actual number of entries
25    let used_slots = cursor.read_u16_le()? as usize;
26
27    let heap_address = cursor.read_offset(offset_size)?;
28
29    let mut slots = Vec::with_capacity(used_slots);
30    for _ in 0..used_slots {
31        let name_offset = cursor.read_length(length_size)?;
32        let offset = cursor.read_length(length_size)?;
33        let size = cursor.read_length(length_size)?;
34        slots.push(ExternalFileSlot {
35            name_offset,
36            offset,
37            size,
38        });
39    }
40
41    let consumed = (cursor.position() - start) as usize;
42    if consumed < msg_size {
43        cursor.skip(msg_size - consumed)?;
44    }
45
46    Ok(ExternalFilesMessage {
47        heap_address,
48        slots,
49    })
50}