xcon: move wire core into workspace crate
This commit is contained in:
parent
61ec13def0
commit
d8380b3dce
11 changed files with 138 additions and 99 deletions
137
xcon/src/parser.rs
Normal file
137
xcon/src/parser.rs
Normal file
|
|
@ -0,0 +1,137 @@
|
|||
use {
|
||||
crate::{Message, XconError},
|
||||
bstr::{BStr, ByteSlice},
|
||||
jay_utils::ptr_ext::PtrExt,
|
||||
std::{borrow::Cow, rc::Rc},
|
||||
uapi::{OwnedFd, Pod},
|
||||
};
|
||||
|
||||
pub struct Parser<'a> {
|
||||
pos: usize,
|
||||
buf: &'a [u8],
|
||||
fds_pos: usize,
|
||||
fds: Vec<Rc<OwnedFd>>,
|
||||
}
|
||||
|
||||
impl<'a> Parser<'a> {
|
||||
pub fn new(buf: &'a [u8], fds: Vec<Rc<OwnedFd>>) -> Self {
|
||||
Self {
|
||||
buf,
|
||||
pos: 0,
|
||||
fds,
|
||||
fds_pos: 0,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn eof(&self) -> bool {
|
||||
self.pos == self.buf.len()
|
||||
}
|
||||
|
||||
fn rem(&self) -> usize {
|
||||
self.buf.len() - self.pos
|
||||
}
|
||||
|
||||
pub fn unmarshal<T: Message<'a>>(&mut self) -> Result<T, XconError> {
|
||||
T::deserialize(self)
|
||||
}
|
||||
|
||||
pub fn pad(&mut self, new: usize) -> Result<(), XconError> {
|
||||
if new > self.buf.len() - self.pos {
|
||||
return Err(XconError::UnexpectedEof);
|
||||
}
|
||||
self.pos += new;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn align(&mut self, n: usize) -> Result<(), XconError> {
|
||||
let new = self.pos + (self.pos.wrapping_neg() & (n - 1));
|
||||
if new > self.buf.len() {
|
||||
return Err(XconError::UnexpectedEof);
|
||||
}
|
||||
self.pos = new;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn read_fd(&mut self) -> Result<Rc<OwnedFd>, XconError> {
|
||||
if self.fds_pos >= self.fds.len() {
|
||||
return Err(XconError::NotEnoughFds);
|
||||
}
|
||||
self.fds_pos += 1;
|
||||
Ok(self.fds[self.fds_pos - 1].clone())
|
||||
}
|
||||
|
||||
pub fn read_pod<T: Pod>(&mut self) -> Result<T, XconError> {
|
||||
match uapi::pod_read_init(&self.buf[self.pos..]) {
|
||||
Ok(v) => {
|
||||
self.pos += size_of::<T>();
|
||||
Ok(v)
|
||||
}
|
||||
_ => Err(XconError::UnexpectedEof),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn read_list_slice<T: Message<'a> + Pod>(
|
||||
&mut self,
|
||||
n: Option<usize>,
|
||||
) -> Result<&'a [T], XconError> {
|
||||
let n = match n {
|
||||
Some(n) => n,
|
||||
_ => self.rem() / size_of::<T>(),
|
||||
};
|
||||
let len = size_of::<T>() * n;
|
||||
if len > self.rem() {
|
||||
return Err(XconError::UnexpectedEof);
|
||||
}
|
||||
if self.buf[self.pos..].as_ptr() as usize & (align_of::<T>() - 1) != 0 {
|
||||
return Err(XconError::UnalignedSlice);
|
||||
}
|
||||
let res =
|
||||
unsafe { std::slice::from_raw_parts(self.buf.as_ptr().add(self.pos) as *const T, n) };
|
||||
self.pos += len;
|
||||
Ok(res)
|
||||
}
|
||||
|
||||
pub fn read_list<T: Message<'a> + Clone>(
|
||||
&mut self,
|
||||
n: Option<usize>,
|
||||
) -> Result<Cow<'a, [T]>, XconError> {
|
||||
let mut res = vec![];
|
||||
if let Some(n) = n {
|
||||
for _ in 0..n {
|
||||
res.push(T::deserialize(self)?);
|
||||
}
|
||||
} else {
|
||||
while !self.eof() {
|
||||
res.push(T::deserialize(self)?);
|
||||
}
|
||||
}
|
||||
Ok(res.into())
|
||||
}
|
||||
|
||||
pub fn read_bytes<const N: usize>(&mut self) -> Result<&'a [u8; N], XconError> {
|
||||
if N > self.rem() {
|
||||
return Err(XconError::UnexpectedEof);
|
||||
}
|
||||
let res = unsafe { self.buf.as_ptr().add(self.pos).cast::<[u8; N]>().deref() };
|
||||
self.pos += N;
|
||||
Ok(res)
|
||||
}
|
||||
|
||||
pub fn read_slice(&mut self, n: usize) -> Result<&'a [u8], XconError> {
|
||||
if n > self.rem() {
|
||||
return Err(XconError::UnexpectedEof);
|
||||
}
|
||||
let res = &self.buf[self.pos..self.pos + n];
|
||||
self.pos += n;
|
||||
Ok(res)
|
||||
}
|
||||
|
||||
pub fn read_string(&mut self, n: usize) -> Result<&'a BStr, XconError> {
|
||||
if n > self.rem() {
|
||||
return Err(XconError::UnexpectedEof);
|
||||
}
|
||||
let res = &self.buf[self.pos..self.pos + n];
|
||||
self.pos += n;
|
||||
Ok(res.as_bstr())
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue