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 {
socket: UnixStream,
@@ -12,6 +12,39 @@ struct WlHeader {
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>> {
let wl_sock_path: String = format!(
"{}/{}",
@@ -43,32 +76,24 @@ fn wl_display_get_registry(wl_state: &mut WlState) -> Result<(), Box<dyn Error>>
Ok(())
}
fn wl_registry_global(header: &WlHeader, wl_state: &mut WlState) -> Result<(), Box<dyn Error>> {
let mut event = vec![0; (header.size - 8).into()];
wl_state.socket.read_exact(&mut event)?;
let mut offset = 0;
fn wl_registry_global(event: &Vec<u8>, wl_state: &mut WlState) -> Result<(), Box<dyn Error>> {
let mut offset: usize = 0;
let name = u32::from_ne_bytes(event[offset..offset+4].try_into()?);
offset += 4;
let interface_len = u32::from_ne_bytes(event[offset..offset+4].try_into()?);
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()?);
let name = event.read_u32(&mut offset);
let interface = event.read_string(&mut offset);
let version = event.read_u32(&mut offset);
println!(
"Received global:\n\tName: {}\n\tInterface len: {}\n\tInterface: {}\n\tVersion: {}\n\tOffset: {}",
"Received global:\n\tName: {}\n\tInterface: {}\n\tVersion: {}",
name,
interface_len,
interface,
version,
offset
);
Ok(())
}
fn main() ->Result<(), Box<dyn Error>> {
fn main() -> Result<(), Box<dyn Error>> {
let wl_sock = match wl_connect() {
Ok(res) => res,
@@ -87,6 +112,7 @@ fn main() ->Result<(), Box<dyn Error>> {
wl_display_get_registry(&mut wl_state)?;
let mut header = [0u8; 8];
wl_state.socket.read_exact(&mut header)?;
let header = WlHeader {
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()?)
};
println!(
"Received event:\n\tObject: {}\n\tOpcode: {}\n\tSize: {}",
header.object,
header.opcode,
header.size
);
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(&header, &mut wl_state)?;
wl_registry_global(&event, &mut wl_state)?;
}
else {
println!(
"Received event:\n\tObject: {}\n\tOpcode: {}\n\tSize: {}",
header.object,
header.opcode,
header.size
);
}
Ok(())