Use WlEvent trait to abstract read_u32 and read_string

This commit is contained in:
2025-03-25 13:21:05 -07:00
parent 857b40dda4
commit 4402df8495

View File

@@ -1,4 +1,4 @@
use std::{env, error::Error, io::{Read, Write}, os::unix::net::UnixStream}; use std::{env, error::Error, io::{Read, Write}, os::unix::net::UnixStream, u32};
struct WlState { struct WlState {
socket: UnixStream, socket: UnixStream,
@@ -12,6 +12,39 @@ struct WlHeader {
size: u16 size: u16
} }
trait WlEvent {
fn read_u32(&self, offset: &mut usize) -> u32;
fn read_string(&self, offset: &mut usize) -> String;
}
impl WlEvent for Vec<u8> {
fn read_u32(&self, offset: &mut usize) -> u32 {
let res = u32::from_ne_bytes(
self[*offset..*offset+4]
.try_into()
.expect("u32::from_ne_bytes failed in WlEvent::read_u32")
);
*offset += 4;
res
}
fn read_string(&self, offset: &mut usize) -> String {
let str_len = u32::from_ne_bytes(
self[*offset..*offset+4]
.try_into()
.expect("u32::from_ne_bytes failed in WlEvent::read_string")
);
*offset += 4;
let str = String::from_utf8(
self[*offset..*offset+(str_len as usize)]
.to_vec())
.expect("String::from_utf8 failed in read_string()"
);
*offset += (str_len+3 & u32::MAX-3) as usize;
str
}
}
fn wl_connect() -> Result<UnixStream, Box<dyn Error>> { fn wl_connect() -> Result<UnixStream, Box<dyn Error>> {
let wl_sock_path: String = format!( let wl_sock_path: String = format!(
"{}/{}", "{}/{}",
@@ -43,32 +76,24 @@ fn wl_display_get_registry(wl_state: &mut WlState) -> Result<(), Box<dyn Error>>
Ok(()) Ok(())
} }
fn wl_registry_global(header: &WlHeader, wl_state: &mut WlState) -> Result<(), Box<dyn Error>> { fn wl_registry_global(event: &Vec<u8>, wl_state: &mut WlState) -> Result<(), Box<dyn Error>> {
let mut event = vec![0; (header.size - 8).into()]; let mut offset: usize = 0;
wl_state.socket.read_exact(&mut event)?;
let mut offset = 0;
let name = u32::from_ne_bytes(event[offset..offset+4].try_into()?); let name = event.read_u32(&mut offset);
offset += 4; let interface = event.read_string(&mut offset);
let interface_len = u32::from_ne_bytes(event[offset..offset+4].try_into()?); let version = event.read_u32(&mut offset);
offset += 4;
let interface = String::from_utf8(event[offset..offset+(interface_len as usize)].into())?;
offset += (interface_len+3 & u32::MAX-3) as usize;
let version = u32::from_ne_bytes(event[offset..offset+4].try_into()?);
println!( println!(
"Received global:\n\tName: {}\n\tInterface len: {}\n\tInterface: {}\n\tVersion: {}\n\tOffset: {}", "Received global:\n\tName: {}\n\tInterface: {}\n\tVersion: {}",
name, name,
interface_len,
interface, interface,
version, version,
offset
); );
Ok(()) Ok(())
} }
fn main() ->Result<(), Box<dyn Error>> { fn main() -> Result<(), Box<dyn Error>> {
let wl_sock = match wl_connect() { let wl_sock = match wl_connect() {
Ok(res) => res, Ok(res) => res,
@@ -87,6 +112,7 @@ fn main() ->Result<(), Box<dyn Error>> {
wl_display_get_registry(&mut wl_state)?; wl_display_get_registry(&mut wl_state)?;
let mut header = [0u8; 8]; let mut header = [0u8; 8];
wl_state.socket.read_exact(&mut header)?; wl_state.socket.read_exact(&mut header)?;
let header = WlHeader { let header = WlHeader {
object: u32::from_ne_bytes(header[0..4].try_into()?), object: u32::from_ne_bytes(header[0..4].try_into()?),
@@ -94,15 +120,19 @@ fn main() ->Result<(), Box<dyn Error>> {
size: u16::from_ne_bytes(header[6..8].try_into()?) size: u16::from_ne_bytes(header[6..8].try_into()?)
}; };
let mut event: Vec<u8> = vec![0; header.size as usize];
wl_state.socket.read_exact(&mut event)?;
if header.object == wl_state.registry_id && header.opcode == 0 {
wl_registry_global(&event, &mut wl_state)?;
}
else {
println!( println!(
"Received event:\n\tObject: {}\n\tOpcode: {}\n\tSize: {}", "Received event:\n\tObject: {}\n\tOpcode: {}\n\tSize: {}",
header.object, header.object,
header.opcode, header.opcode,
header.size header.size
); );
if header.object == wl_state.registry_id && header.opcode == 0 {
wl_registry_global(&header, &mut wl_state)?;
} }
Ok(()) Ok(())