use binrw::BinRead;
use spice_client::protocol::*;
use std::io::Cursor;
fn main() {
let raw_data = vec![
0x00, 0x00, 0x00, 0x00, 0x8d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8f, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x01, 0x00, 0x00, 0x00, 0x73, 0x05, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00,
0x02, 0x00, 0x00, 0x00, 0x08, 0x04, 0x09, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x24,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8, 0xa8, 0xa8, 0x00, 0xa8, 0xa8, 0xa8, 0x00,
0xa8, 0xa8, 0xa8, 0x00,
];
println!("Manual parsing:");
println!(
"bbox.left: {}",
u32::from_le_bytes([raw_data[0], raw_data[1], raw_data[2], raw_data[3]])
);
println!(
"bbox.top: {}",
u32::from_le_bytes([raw_data[4], raw_data[5], raw_data[6], raw_data[7]])
);
println!(
"bbox.right: {}",
u32::from_le_bytes([raw_data[8], raw_data[9], raw_data[10], raw_data[11]])
);
println!(
"bbox.bottom: {}",
u32::from_le_bytes([raw_data[12], raw_data[13], raw_data[14], raw_data[15]])
);
println!(
"Next 4 bytes (clip?): 0x{:02x} 0x{:02x} 0x{:02x} 0x{:02x}",
raw_data[16], raw_data[17], raw_data[18], raw_data[19]
);
println!("Raw data length: {} bytes", raw_data.len());
println!("Raw data (hex):");
for (i, chunk) in raw_data.chunks(16).enumerate() {
print!("{:04x}: ", i * 16);
for byte in chunk {
print!("{:02x} ", byte);
}
println!();
}
let mut cursor = Cursor::new(&raw_data);
match SpiceDrawBase::read(&mut cursor) {
Ok(base) => {
println!("\nParsed SpiceDrawBase:");
println!(" bbox: {:?}", base.box_);
println!(
" clip: type={} (0x{:02x})",
base.clip.clip_type, base.clip.clip_type
);
if base.clip.clip_type > 1 {
println!(
" WARNING: Invalid clip type! Expected 0 or 1, got {}",
base.clip.clip_type
);
}
let pos = cursor.position() as usize;
println!("\nCursor position after base: {}", pos);
if pos + 8 <= raw_data.len() {
let addr_bytes = &raw_data[pos..pos + 8];
let src_image = u64::from_le_bytes([
addr_bytes[0],
addr_bytes[1],
addr_bytes[2],
addr_bytes[3],
addr_bytes[4],
addr_bytes[5],
addr_bytes[6],
addr_bytes[7],
]);
println!("src_image address: 0x{:x} ({})", src_image, src_image);
println!("Address breakdown:");
println!(
" Upper 32 bits: 0x{:x} ({})",
src_image >> 32,
src_image >> 32
);
println!(
" Lower 32 bits: 0x{:x} ({})",
src_image & 0xFFFFFFFF,
src_image & 0xFFFFFFFF
);
if src_image > 0x1_0000_0000 {
println!(
" WARNING: Address > 4GB, likely special encoding or cache reference"
);
}
if (src_image >> 32) > 0 {
let high = (src_image >> 32) as u32;
let low = (src_image & 0xFFFFFFFF) as u32;
println!(
" Possible cache ref: surface_id=0x{:x}, offset=0x{:x}",
high, low
);
}
if pos + 24 <= raw_data.len() {
let src_area_left = u32::from_le_bytes([
raw_data[pos + 8],
raw_data[pos + 9],
raw_data[pos + 10],
raw_data[pos + 11],
]);
let src_area_top = u32::from_le_bytes([
raw_data[pos + 12],
raw_data[pos + 13],
raw_data[pos + 14],
raw_data[pos + 15],
]);
let src_area_right = u32::from_le_bytes([
raw_data[pos + 16],
raw_data[pos + 17],
raw_data[pos + 18],
raw_data[pos + 19],
]);
let src_area_bottom = u32::from_le_bytes([
raw_data[pos + 20],
raw_data[pos + 21],
raw_data[pos + 22],
raw_data[pos + 23],
]);
println!(
"src_area: ({},{}) to ({},{})",
src_area_left, src_area_top, src_area_right, src_area_bottom
);
}
}
}
Err(e) => {
println!("Failed to parse SpiceDrawBase: {:?}", e);
}
}
}