Skip to main content

async_hdf5/messages/
fill_value.rs

1use bytes::Bytes;
2
3use crate::endian::HDF5Reader;
4use crate::error::Result;
5
6/// Fill value message — specifies the default value for uninitialized data.
7///
8/// Message type 0x0005.
9#[derive(Debug, Clone)]
10pub struct FillValueMessage {
11    /// Raw fill value bytes (interpretation depends on the dataset's data type).
12    /// None if fill value is undefined.
13    pub value: Option<Vec<u8>>,
14    /// Fill time: 0=on allocation, 1=never, 2=if set by user.
15    pub fill_time: u8,
16}
17
18impl FillValueMessage {
19    /// Parse from the raw message bytes.
20    pub fn parse(data: &Bytes) -> Result<Self> {
21        let mut r = HDF5Reader::new(data.clone());
22
23        let version = r.read_u8()?;
24
25        match version {
26            1 | 2 => {
27                // v1/v2: alloc_time(1) + fill_time(1) + defined(1) + [size(4) + value]
28                let _alloc_time = r.read_u8()?;
29                let fill_time = r.read_u8()?;
30                let fill_value_defined = r.read_u8()?;
31
32                let value = if fill_value_defined != 0 {
33                    let size = r.read_u32()? as usize;
34                    if size > 0 {
35                        Some(r.read_bytes(size)?)
36                    } else {
37                        None
38                    }
39                } else {
40                    None
41                };
42
43                Ok(Self { value, fill_time })
44            }
45            3 => {
46                // v3: flags(1) — bits encode alloc_time, fill_time, defined, undefined
47                let flags = r.read_u8()?;
48                let fill_time = (flags >> 2) & 0x03;
49                let fill_value_defined = (flags >> 4) & 0x01 != 0;
50                let fill_value_undefined = (flags >> 5) & 0x01 != 0;
51
52                let value = if fill_value_defined && !fill_value_undefined {
53                    let size = r.read_u32()? as usize;
54                    if size > 0 {
55                        Some(r.read_bytes(size)?)
56                    } else {
57                        None
58                    }
59                } else {
60                    None
61                };
62
63                Ok(Self { value, fill_time })
64            }
65            _ => {
66                // Unknown version — return empty
67                Ok(Self {
68                    value: None,
69                    fill_time: 0,
70                })
71            }
72        }
73    }
74}