async_hdf5/messages/
link.rs1use bytes::Bytes;
2
3use crate::endian::HDF5Reader;
4use crate::error::{HDF5Error, Result};
5
6#[derive(Debug, Clone, Copy, PartialEq, Eq)]
8pub enum LinkType {
9 Hard,
11 Soft,
13 External,
15}
16
17#[derive(Debug, Clone)]
21pub struct LinkMessage {
22 pub name: String,
24 pub link_type: LinkType,
26 pub target_address: Option<u64>,
28 pub soft_link_value: Option<String>,
30 pub creation_order: Option<u64>,
32}
33
34impl LinkMessage {
35 pub fn parse(data: &Bytes, size_of_offsets: u8, size_of_lengths: u8) -> Result<Self> {
37 let mut r = HDF5Reader::with_sizes(data.clone(), size_of_offsets, size_of_lengths);
38
39 let _version = r.read_u8()?;
40 let flags = r.read_u8()?;
41
42 let link_type = if flags & 0x08 != 0 {
49 match r.read_u8()? {
50 0 => LinkType::Hard,
51 1 => LinkType::Soft,
52 64 => LinkType::External,
53 t => return Err(HDF5Error::UnsupportedLinkType(t)),
54 }
55 } else {
56 LinkType::Hard };
58
59 let creation_order = if flags & 0x04 != 0 {
60 Some(r.read_u64()?)
61 } else {
62 None
63 };
64
65 let _charset = if flags & 0x10 != 0 {
66 r.read_u8()? } else {
68 0
69 };
70
71 let name_size_field_width = 1u8 << (flags & 0x03);
72 let name_length = match name_size_field_width {
73 1 => r.read_u8()? as usize,
74 2 => r.read_u16()? as usize,
75 4 => r.read_u32()? as usize,
76 8 => r.read_u64()? as usize,
77 _ => unreachable!(),
78 };
79
80 let name_bytes = r.read_bytes(name_length)?;
81 let name = String::from_utf8_lossy(&name_bytes).to_string();
82
83 let (target_address, soft_link_value) = match link_type {
84 LinkType::Hard => {
85 let addr = r.read_offset()?;
86 (Some(addr), None)
87 }
88 LinkType::Soft => {
89 let value_length = r.read_u16()? as usize;
90 let value_bytes = r.read_bytes(value_length)?;
91 let value = String::from_utf8_lossy(&value_bytes).to_string();
92 (None, Some(value))
93 }
94 LinkType::External => {
95 let value_length = r.read_u16()? as usize;
96 let value_bytes = r.read_bytes(value_length)?;
97 let value = String::from_utf8_lossy(&value_bytes).to_string();
98 (None, Some(value))
99 }
100 };
101
102 Ok(Self {
103 name,
104 link_type,
105 target_address,
106 soft_link_value,
107 creation_order,
108 })
109 }
110}