Skip to main content

async_hdf5/messages/
dataspace.rs

1use bytes::Bytes;
2
3use crate::endian::HDF5Reader;
4use crate::error::Result;
5
6/// Dataspace message — describes the dimensionality of a dataset.
7///
8/// Message type 0x0001.
9#[derive(Debug, Clone)]
10pub struct DataspaceMessage {
11    /// Number of dimensions (0 = scalar).
12    pub rank: u8,
13    /// Dataspace type: 0 = scalar, 1 = simple, 2 = null.
14    /// Only present for v2 messages; v1 defaults to 1 (simple) for rank > 0,
15    /// 0 (scalar) for rank == 0.
16    pub dataspace_type: u8,
17    /// Current size along each dimension.
18    pub dimensions: Vec<u64>,
19    /// Maximum size along each dimension (None = same as current).
20    /// A value of u64::MAX means unlimited.
21    pub max_dimensions: Option<Vec<u64>>,
22}
23
24impl DataspaceMessage {
25    /// Parse from the raw message bytes.
26    pub fn parse(data: &Bytes, size_of_lengths: u8) -> Result<Self> {
27        let mut r = HDF5Reader::with_sizes(data.clone(), 8, size_of_lengths);
28
29        let version = r.read_u8()?;
30        let rank = r.read_u8()?;
31        let flags = r.read_u8()?;
32
33        // v1: reserved (1 byte) + reserved (4 bytes) = 5 bytes (no type field)
34        // v2: type field (1 byte): 0=scalar, 1=simple, 2=null
35        let dataspace_type = match version {
36            1 => {
37                r.skip(5); // 1 reserved + 4 reserved
38                if rank == 0 {
39                    0
40                } else {
41                    1
42                }
43            }
44            2 => r.read_u8()?,
45            _ => {
46                // Best-effort: try to continue
47
48                r.read_u8()?
49            }
50        };
51
52        let mut dimensions = Vec::with_capacity(rank as usize);
53        for _ in 0..rank {
54            dimensions.push(r.read_length()?);
55        }
56
57        let has_max = flags & 0x01 != 0;
58        let max_dimensions = if has_max {
59            let mut max = Vec::with_capacity(rank as usize);
60            for _ in 0..rank {
61                max.push(r.read_length()?);
62            }
63            Some(max)
64        } else {
65            None
66        };
67
68        Ok(Self {
69            rank,
70            dataspace_type,
71            dimensions,
72            max_dimensions,
73        })
74    }
75}