use crate::error::{Error, Result};
use crate::io::Cursor;
#[derive(Debug, Clone)]
pub struct AttributeInfoMessage {
pub creation_order_tracked: bool,
pub creation_order_indexed: bool,
pub max_creation_index: Option<u64>,
pub fractal_heap_address: u64,
pub btree_name_index_address: u64,
pub btree_creation_order_address: Option<u64>,
}
pub fn parse(
cursor: &mut Cursor<'_>,
offset_size: u8,
_length_size: u8,
msg_size: usize,
) -> Result<AttributeInfoMessage> {
let start = cursor.position();
let version = cursor.read_u8()?;
if version != 0 {
return Err(Error::InvalidData(format!(
"unsupported attribute info version: {}",
version
)));
}
let flags = cursor.read_u8()?;
let creation_order_tracked = (flags & 0x01) != 0;
let creation_order_indexed = (flags & 0x02) != 0;
let max_creation_index = if creation_order_tracked {
Some(cursor.read_u16_le()? as u64)
} else {
None
};
let fractal_heap_address = cursor.read_offset(offset_size)?;
let btree_name_index_address = cursor.read_offset(offset_size)?;
let btree_creation_order_address = if creation_order_indexed {
Some(cursor.read_offset(offset_size)?)
} else {
None
};
let consumed = (cursor.position() - start) as usize;
if consumed < msg_size {
cursor.skip(msg_size - consumed)?;
}
Ok(AttributeInfoMessage {
creation_order_tracked,
creation_order_indexed,
max_creation_index,
fractal_heap_address,
btree_name_index_address,
btree_creation_order_address,
})
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_parse_attr_info_simple() {
let mut data = vec![
0x00, 0x00, ];
data.extend_from_slice(&0xF000u64.to_le_bytes());
data.extend_from_slice(&0xF100u64.to_le_bytes());
let mut cursor = Cursor::new(&data);
let msg = parse(&mut cursor, 8, 8, data.len()).unwrap();
assert!(!msg.creation_order_tracked);
assert_eq!(msg.fractal_heap_address, 0xF000);
assert_eq!(msg.btree_name_index_address, 0xF100);
}
}