dope_core/io/provided/
mod.rs1use std::cell::Cell;
2
3use crate::driver::{DriverContext, DriverRef};
4
5use self::raw::buffer::BufferId;
6use self::raw::completion::CompletedBuffer;
7use self::raw::region::InitializedRegion;
8
9pub(crate) mod raw;
10
11pub struct ProvidedSpan {
12 offset: usize,
13 len: usize,
14}
15
16pub struct ProvidedLease<'d> {
17 driver: DriverRef<'d>,
18 id: Cell<Option<BufferId>>,
19 region: InitializedRegion,
20}
21
22pub struct ProvidedView<'d> {
23 _lease: ProvidedLease<'d>,
24 region: InitializedRegion,
25}
26
27impl<'d> ProvidedLease<'d> {
28 pub(crate) fn from_completion(driver: DriverRef<'d>, completed: CompletedBuffer) -> Self {
29 let CompletedBuffer { id, region } = completed;
30 Self {
31 driver,
32 id: Cell::new(Some(id)),
33 region,
34 }
35 }
36
37 pub fn as_slice(&self) -> &[u8] {
38 self.region.as_slice()
39 }
40
41 pub fn as_mut_slice(&mut self) -> &mut [u8] {
42 self.region.as_mut_slice()
43 }
44
45 pub fn advance(&mut self, count: usize) {
46 assert!(
47 self.region.advance(count),
48 "dope: provided lease advance out of bounds"
49 );
50 }
51
52 pub fn range_of(&self, bytes: &[u8]) -> Option<ProvidedSpan> {
53 let base = self.region.ptr.as_ptr().addr();
54 let start = bytes.as_ptr().addr();
55 let offset = start.checked_sub(base)?;
56 self.span(offset, bytes.len())
57 }
58
59 pub fn span(&self, offset: usize, len: usize) -> Option<ProvidedSpan> {
60 if offset > self.region.len || len > self.region.len - offset {
61 return None;
62 }
63 Some(ProvidedSpan { offset, len })
64 }
65
66 pub fn into_view(self, span: ProvidedSpan) -> Result<ProvidedView<'d>, Self> {
67 let Some(region) = self.region.subregion(span.offset, span.len) else {
68 return Err(self);
69 };
70 Ok(ProvidedView {
71 _lease: self,
72 region,
73 })
74 }
75
76 pub fn release(&self, driver: &mut DriverContext<'_, 'd>) {
77 let _ = self.driver;
78 if let Some(id) = self.id.take() {
79 driver.release_buffer(id);
80 }
81 }
82}
83
84impl AsRef<[u8]> for ProvidedLease<'_> {
85 fn as_ref(&self) -> &[u8] {
86 self.as_slice()
87 }
88}
89
90impl Drop for ProvidedLease<'_> {
91 fn drop(&mut self) {
92 if let Some(id) = self.id.take() {
93 self.driver.return_buffer(id);
94 }
95 }
96}
97
98impl ProvidedView<'_> {
99 pub fn as_slice(&self) -> &[u8] {
100 self.region.as_slice()
101 }
102
103 pub fn len(&self) -> usize {
104 self.region.len()
105 }
106
107 pub fn is_empty(&self) -> bool {
108 self.region.len() == 0
109 }
110
111 pub fn advance(&mut self, count: usize) {
112 assert!(
113 self.region.advance(count),
114 "dope: provided view advance out of bounds"
115 );
116 }
117}
118
119impl AsRef<[u8]> for ProvidedView<'_> {
120 fn as_ref(&self) -> &[u8] {
121 self.as_slice()
122 }
123}