hdf5_reader/messages/
link_info.rs1use crate::error::{Error, Result};
8use crate::io::Cursor;
9
10#[derive(Debug, Clone)]
12pub struct LinkInfoMessage {
13 pub creation_order_tracked: bool,
15 pub creation_order_indexed: bool,
17 pub max_creation_index: Option<u64>,
19 pub fractal_heap_address: u64,
21 pub btree_name_index_address: u64,
23 pub btree_creation_order_address: Option<u64>,
25}
26
27pub fn parse(
29 cursor: &mut Cursor<'_>,
30 offset_size: u8,
31 _length_size: u8,
32 msg_size: usize,
33) -> Result<LinkInfoMessage> {
34 let start = cursor.position();
35 let version = cursor.read_u8()?;
36
37 if version != 0 {
38 return Err(Error::InvalidData(format!(
39 "unsupported link info version: {}",
40 version
41 )));
42 }
43
44 let flags = cursor.read_u8()?;
45 let creation_order_tracked = (flags & 0x01) != 0;
46 let creation_order_indexed = (flags & 0x02) != 0;
47
48 let max_creation_index = if creation_order_tracked {
49 Some(cursor.read_u64_le()?)
50 } else {
51 None
52 };
53
54 let fractal_heap_address = cursor.read_offset(offset_size)?;
55 let btree_name_index_address = cursor.read_offset(offset_size)?;
56
57 let btree_creation_order_address = if creation_order_indexed {
58 Some(cursor.read_offset(offset_size)?)
59 } else {
60 None
61 };
62
63 let consumed = (cursor.position() - start) as usize;
64 if consumed < msg_size {
65 cursor.skip(msg_size - consumed)?;
66 }
67
68 Ok(LinkInfoMessage {
69 creation_order_tracked,
70 creation_order_indexed,
71 max_creation_index,
72 fractal_heap_address,
73 btree_name_index_address,
74 btree_creation_order_address,
75 })
76}
77
78#[cfg(test)]
79mod tests {
80 use super::*;
81
82 #[test]
83 fn test_parse_link_info_no_order() {
84 let mut data = vec![
85 0x00, 0x00, ];
88 data.extend_from_slice(&0xA000u64.to_le_bytes());
90 data.extend_from_slice(&0xB000u64.to_le_bytes());
92
93 let mut cursor = Cursor::new(&data);
94 let msg = parse(&mut cursor, 8, 8, data.len()).unwrap();
95 assert!(!msg.creation_order_tracked);
96 assert!(!msg.creation_order_indexed);
97 assert!(msg.max_creation_index.is_none());
98 assert_eq!(msg.fractal_heap_address, 0xA000);
99 assert_eq!(msg.btree_name_index_address, 0xB000);
100 assert!(msg.btree_creation_order_address.is_none());
101 }
102
103 #[test]
104 fn test_parse_link_info_with_order() {
105 let mut data = vec![
106 0x00, 0x03, ];
109 data.extend_from_slice(&99u64.to_le_bytes());
111 data.extend_from_slice(&0xC000u64.to_le_bytes());
113 data.extend_from_slice(&0xD000u64.to_le_bytes());
115 data.extend_from_slice(&0xE000u64.to_le_bytes());
117
118 let mut cursor = Cursor::new(&data);
119 let msg = parse(&mut cursor, 8, 8, data.len()).unwrap();
120 assert!(msg.creation_order_tracked);
121 assert!(msg.creation_order_indexed);
122 assert_eq!(msg.max_creation_index, Some(99));
123 assert_eq!(msg.fractal_heap_address, 0xC000);
124 assert_eq!(msg.btree_name_index_address, 0xD000);
125 assert_eq!(msg.btree_creation_order_address, Some(0xE000));
126 }
127}