1use crate::block::{BlockDevice, BlockRead};
19use crate::error::{Error, Result};
20use std::sync::Arc;
21
22pub struct SliceReader<'a> {
27 parent: &'a (dyn BlockRead + 'a),
28 start: u64,
29 length: u64,
30}
31
32impl<'a> SliceReader<'a> {
33 pub fn new(parent: &'a (dyn BlockRead + 'a), start: u64, length: u64) -> Self {
34 Self {
35 parent,
36 start,
37 length,
38 }
39 }
40
41 pub fn start(&self) -> u64 {
43 self.start
44 }
45
46 pub fn length(&self) -> u64 {
48 self.length
49 }
50}
51
52impl<'a> BlockRead for SliceReader<'a> {
53 fn read_at(&self, offset: u64, buf: &mut [u8]) -> Result<()> {
54 let want = buf.len() as u64;
55 if offset
56 .checked_add(want)
57 .map(|e| e > self.length)
58 .unwrap_or(true)
59 {
60 return Err(Error::ShortRead {
61 offset,
62 want: buf.len(),
63 got: 0,
64 });
65 }
66 self.parent.read_at(self.start + offset, buf)
67 }
68
69 fn size_bytes(&self) -> u64 {
70 self.length
71 }
72}
73
74impl<'a> BlockDevice for SliceReader<'a> {}
78
79pub struct OwnedSlice {
83 parent: Arc<dyn BlockRead>,
84 start: u64,
85 length: u64,
86}
87
88impl OwnedSlice {
89 pub fn new(parent: Arc<dyn BlockRead>, start: u64, length: u64) -> Self {
90 Self {
91 parent,
92 start,
93 length,
94 }
95 }
96
97 pub fn start(&self) -> u64 {
98 self.start
99 }
100
101 pub fn length(&self) -> u64 {
102 self.length
103 }
104}
105
106impl BlockRead for OwnedSlice {
107 fn read_at(&self, offset: u64, buf: &mut [u8]) -> Result<()> {
108 let want = buf.len() as u64;
109 if offset
110 .checked_add(want)
111 .map(|e| e > self.length)
112 .unwrap_or(true)
113 {
114 return Err(Error::ShortRead {
115 offset,
116 want: buf.len(),
117 got: 0,
118 });
119 }
120 self.parent.read_at(self.start + offset, buf)
121 }
122
123 fn size_bytes(&self) -> u64 {
124 self.length
125 }
126}
127
128impl BlockDevice for OwnedSlice {}
130
131#[cfg(test)]
132mod tests {
133 use super::*;
134 use std::sync::Mutex;
135
136 struct Bytes(Mutex<Vec<u8>>);
137 impl BlockRead for Bytes {
138 fn read_at(&self, offset: u64, buf: &mut [u8]) -> Result<()> {
139 let b = self.0.lock().unwrap();
140 let start = offset as usize;
141 let end = start + buf.len();
142 if end > b.len() {
143 return Err(Error::ShortRead {
144 offset,
145 want: buf.len(),
146 got: b.len().saturating_sub(start),
147 });
148 }
149 buf.copy_from_slice(&b[start..end]);
150 Ok(())
151 }
152 fn size_bytes(&self) -> u64 {
153 self.0.lock().unwrap().len() as u64
154 }
155 }
156
157 #[test]
158 fn slice_reader_rebases_offsets() {
159 let mut v = vec![0u8; 4096];
160 v[2000..2004].copy_from_slice(&[0xAB, 0xCD, 0xEF, 0x01]);
161 let dev = Bytes(Mutex::new(v));
162
163 let slice = SliceReader::new(&dev, 2000, 4);
164 assert_eq!(slice.size_bytes(), 4);
165 assert_eq!(slice.start(), 2000);
166 assert_eq!(slice.length(), 4);
167
168 let mut buf = [0u8; 4];
169 slice.read_at(0, &mut buf).unwrap();
170 assert_eq!(buf, [0xAB, 0xCD, 0xEF, 0x01]);
171 }
172
173 #[test]
174 fn slice_reader_rejects_out_of_bounds() {
175 let dev = Bytes(Mutex::new(vec![0u8; 4096]));
176 let slice = SliceReader::new(&dev, 0, 16);
177 let mut buf = [0u8; 8];
178 match slice.read_at(12, &mut buf) {
179 Err(Error::ShortRead { .. }) => {}
180 other => panic!("expected ShortRead, got {other:?}"),
181 }
182 }
183
184 #[test]
185 fn owned_slice_works_through_arc() {
186 let mut v = vec![0u8; 4096];
187 v[100..104].copy_from_slice(&[0x11, 0x22, 0x33, 0x44]);
188 let dev: Arc<dyn BlockRead> = Arc::new(Bytes(Mutex::new(v)));
189
190 let slice = OwnedSlice::new(dev, 100, 4);
191 assert_eq!(slice.size_bytes(), 4);
192 let mut buf = [0u8; 4];
193 slice.read_at(0, &mut buf).unwrap();
194 assert_eq!(buf, [0x11, 0x22, 0x33, 0x44]);
195 }
196
197 #[test]
198 fn slices_reject_writes_via_blockdevice_default() {
199 let dev = Bytes(Mutex::new(vec![0u8; 16]));
200 let slice = SliceReader::new(&dev, 0, 8);
201 let err = BlockDevice::write_at(&slice, 0, &[1u8; 4]).unwrap_err();
202 assert!(matches!(err, Error::ReadOnly));
203 }
204}