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}