1use crate::error::{Error, Result};
8use crate::io::Cursor;
9
10pub fn resolve_object_reference(ref_bytes: &[u8], offset_size: u8) -> Result<u64> {
14 if ref_bytes.len() < offset_size as usize {
15 return Err(Error::InvalidData(format!(
16 "object reference too short: need {} bytes, have {}",
17 offset_size,
18 ref_bytes.len()
19 )));
20 }
21 let mut cursor = Cursor::new(ref_bytes);
22 cursor.read_offset(offset_size)
23}
24
25pub fn read_object_references(raw_data: &[u8], offset_size: u8) -> Result<Vec<u64>> {
29 let ref_size = offset_size as usize;
30 if ref_size == 0 {
31 return Ok(Vec::new());
32 }
33 let count = raw_data.len() / ref_size;
34 let mut refs = Vec::with_capacity(count);
35 let mut cursor = Cursor::new(raw_data);
36 for _ in 0..count {
37 let addr = cursor.read_offset(offset_size)?;
38 refs.push(addr);
39 }
40 Ok(refs)
41}
42
43#[cfg(test)]
44mod tests {
45 use super::*;
46
47 #[test]
48 fn test_resolve_object_reference_8byte() {
49 let addr: u64 = 0x1234_5678_9ABC_DEF0;
50 let bytes = addr.to_le_bytes();
51 let result = resolve_object_reference(&bytes, 8).unwrap();
52 assert_eq!(result, addr);
53 }
54
55 #[test]
56 fn test_resolve_object_reference_4byte() {
57 let addr: u32 = 0x1234_5678;
58 let bytes = addr.to_le_bytes();
59 let result = resolve_object_reference(&bytes, 4).unwrap();
60 assert_eq!(result, addr as u64);
61 }
62
63 #[test]
64 fn test_read_object_references() {
65 let mut data = Vec::new();
66 data.extend_from_slice(&0x1000u64.to_le_bytes());
67 data.extend_from_slice(&0x2000u64.to_le_bytes());
68 data.extend_from_slice(&0x3000u64.to_le_bytes());
69
70 let refs = read_object_references(&data, 8).unwrap();
71 assert_eq!(refs, vec![0x1000, 0x2000, 0x3000]);
72 }
73
74 #[test]
75 fn test_read_object_references_4byte() {
76 let mut data = Vec::new();
77 data.extend_from_slice(&0xAAAAu32.to_le_bytes());
78 data.extend_from_slice(&0xBBBBu32.to_le_bytes());
79
80 let refs = read_object_references(&data, 4).unwrap();
81 assert_eq!(refs, vec![0xAAAA, 0xBBBB]);
82 }
83
84 #[test]
85 fn test_too_short_reference() {
86 let data = [0x01, 0x02];
87 let err = resolve_object_reference(&data, 8).unwrap_err();
88 assert!(matches!(err, Error::InvalidData(_)));
89 }
90}