use std::ptr::NonNull;
use super::{Mr, Slicing};
use crate::bindings::*;
#[derive(Debug, Clone, Copy)]
pub struct MrSlice<'a> {
mr: &'a Mr,
offset: usize,
len: usize,
}
impl<'a> MrSlice<'a> {
pub(crate) fn new(mr: &'a Mr, offset: usize, len: usize) -> Self {
Self { mr, offset, len }
}
#[inline]
pub fn mr(&self) -> &Mr {
self.mr
}
#[inline]
pub fn lkey(&self) -> u32 {
self.mr.lkey()
}
#[inline]
pub fn rkey(&self) -> u32 {
self.mr.rkey()
}
#[must_use = "must check if the resize was successful"]
#[inline]
pub fn resize(&mut self, len: usize) -> bool {
let max_len = self.mr.len() - self.offset;
if len <= max_len {
self.len = len;
true
} else {
false
}
}
}
unsafe impl<'a, 's> Slicing<'s> for MrSlice<'a>
where
'a: 's,
{
type Output = MrSlice<'s>;
#[inline]
fn addr(&'s self) -> *mut u8 {
(self.mr.addr() as usize + self.offset) as *mut u8
}
#[inline]
fn len(&'s self) -> usize {
self.len
}
#[inline]
unsafe fn slice_unchecked(&'s self, offset: usize, len: usize) -> Self::Output {
Self {
mr: self.mr,
offset: self.offset + offset,
len,
}
}
}
impl From<MrSlice<'_>> for ibv_sge {
fn from(slice: MrSlice<'_>) -> Self {
Self {
addr: slice.addr() as u64,
length: slice.len() as u32,
lkey: slice.mr.lkey(),
}
}
}
impl From<MrSlice<'_>> for NonNull<u8> {
fn from(slice: MrSlice<'_>) -> Self {
unsafe { NonNull::new_unchecked(slice.addr()) }
}
}