1use core::mem::MaybeUninit;
2use std::io::{IoSliceMut, Result as IOResult};
3
4mod adapter;
5pub use adapter::*;
6mod buffered;
7pub use buffered::*;
8
9#[cfg(target_os = "android")]
10pub mod android;
11#[cfg(unix)]
12mod generic_unix;
13#[cfg(target_os = "linux")]
14pub mod linux;
15#[cfg(target_os = "macos")]
16pub mod macos;
17#[cfg(windows)]
18pub mod windows;
19
20#[cfg(windows)]
21pub type PlatformNativeFileReader = self::windows::NativeFileBlobRandomReader;
22#[cfg(windows)]
23pub type PlatformNativeFileReaderAsync = self::windows::NativeFileBlobAsyncRandomReader;
24#[cfg(target_os = "linux")]
25pub type PlatformNativeFileReader = self::linux::NativeFileBlobRandomReader;
26#[cfg(target_os = "linux")]
27pub type PlatformNativeFileReaderAsync = self::linux::NativeFileAsyncBlobRandomReader;
28#[cfg(target_os = "android")]
29pub type PlatformNativeFileReader = self::android::BundledAssetRandomReader;
30#[cfg(target_os = "android")]
31pub type PlatformNativeFileReaderAsync = self::android::BundledAssetAsyncRandomReader;
32#[cfg(target_os = "macos")]
33pub type PlatformNativeFileReader = self::macos::NativeFileReader;
34#[cfg(target_os = "macos")]
35pub type PlatformNativeFileReaderAsync = self::macos::NativeFileAsyncReader;
36
37pub trait BlobMetadata {
39 fn byte_length(&self) -> std::io::Result<u64>;
40}
41
42pub trait BlobMetadataAsync {
44 fn byte_length_async(&self) -> impl core::future::Future<Output = std::io::Result<u64>>;
45}
46
47pub trait RandomReadBlob {
49 fn read(&self, pos: u64, buf: &mut [MaybeUninit<u8>]) -> std::io::Result<usize>;
50
51 #[inline]
52 fn readv(&self, offs: u64, iovecs: &mut [IoSliceMut]) -> std::io::Result<usize> {
53 match iovecs.first_mut() {
55 None => Ok(0),
56 Some(v) => self.read(offs, unsafe {
57 core::mem::transmute::<&mut [u8], &mut [MaybeUninit<u8>]>(&mut v[..])
58 }),
59 }
60 }
61
62 fn read_exact(&self, offs: u64, buf: &mut [MaybeUninit<u8>]) -> std::io::Result<()> {
64 let mut o = 0;
65 while o < buf.len() {
66 o += self.read(offs + o as u64, &mut buf[o..])?;
67 }
68
69 Ok(())
70 }
71
72 fn readv_all<'a, 'b, 'bb>(
73 &'a self,
74 offs: u64,
75 mut iovecs: &'b mut [IoSliceMut<'bb>],
76 ) -> std::io::Result<()> {
77 IoSliceMut::advance_slices(&mut iovecs, 0);
79
80 let mut o = 0;
81 while !iovecs.is_empty() {
82 let r = self.readv(offs + o as u64, iovecs)?;
83 IoSliceMut::advance_slices(&mut iovecs, r);
84 o += r;
85 }
86
87 Ok(())
88 }
89
90 fn read_to_end(&self, offs: u64) -> std::io::Result<Vec<u8>> {
91 const GROW_SIZE: usize = 8192;
92
93 let mut buf = Vec::with_capacity(GROW_SIZE);
94 let mut o = 0;
95 loop {
96 let r = match self.read(offs + o as u64, buf.spare_capacity_mut()) {
97 Ok(0) => break,
98 Ok(r) => r,
99 Err(e) if e.kind() == std::io::ErrorKind::UnexpectedEof => break,
100 Err(e) => return Err(e),
101 };
102
103 o += r;
104 unsafe {
105 buf.set_len(o);
106 }
107 if o >= buf.capacity() {
108 buf.reserve_exact(GROW_SIZE);
109 }
110 }
111
112 buf.shrink_to_fit();
113 Ok(buf)
114 }
115}
116impl<'t, T> RandomReadBlob for &'t T
117where
118 T: RandomReadBlob + ?Sized + 't,
119{
120 #[inline(always)]
121 fn read(&self, pos: u64, buf: &mut [MaybeUninit<u8>]) -> std::io::Result<usize> {
122 T::read(*self, pos, buf)
123 }
124
125 #[inline(always)]
126 fn readv(&self, offs: u64, iovecs: &mut [IoSliceMut]) -> std::io::Result<usize> {
127 T::readv(*self, offs, iovecs)
128 }
129
130 #[inline(always)]
131 fn read_exact(&self, offs: u64, buf: &mut [MaybeUninit<u8>]) -> std::io::Result<()> {
132 T::read_exact(*self, offs, buf)
133 }
134
135 #[inline(always)]
136 fn read_to_end(&self, offs: u64) -> std::io::Result<Vec<u8>> {
137 T::read_to_end(*self, offs)
138 }
139
140 #[inline(always)]
141 fn readv_all<'a, 'b, 'bb>(
142 &'a self,
143 offs: u64,
144 iovecs: &'b mut [IoSliceMut<'bb>],
145 ) -> std::io::Result<()> {
146 T::readv_all(*self, offs, iovecs)
147 }
148}
149
150pub trait RandomReadBlobAsync {
152 type ReadFuture<'a, 'b>: Future<Output = std::io::Result<usize>>
153 where
154 Self: 'a;
155 type ReadVecFuture<'a, 'b, 'bb>: Future<Output = std::io::Result<usize>>
156 where
157 Self: 'a,
158 'bb: 'b;
159
160 fn read_async<'a, 'b>(
161 &'a self,
162 offs: u64,
163 buf: &'b mut [MaybeUninit<u8>],
164 ) -> Self::ReadFuture<'a, 'b>;
165 fn readv_async<'a, 'b, 'bb>(
166 &'a self,
167 offs: u64,
168 iovecs: &'b mut [IoSliceMut<'bb>],
169 ) -> Self::ReadVecFuture<'a, 'b, 'bb>;
170
171 fn read_exact_async<'a, 'b>(
173 &'a self,
174 offs: u64,
175 buf: &'b mut [MaybeUninit<u8>],
176 ) -> impl core::future::Future<Output = IOResult<()>> + use<'a, 'b, Self> {
177 async move {
178 let mut o = 0;
179 while o < buf.len() {
180 let r = self.read_async(offs + o as u64, &mut buf[o..]).await?;
181 o += r;
182 }
183
184 Ok(())
185 }
186 }
187
188 fn readv_all_async<'a, 'b, 'bb>(
189 &'a self,
190 offs: u64,
191 mut iovecs: &'b mut [IoSliceMut<'bb>],
192 ) -> impl core::future::Future<Output = std::io::Result<()>> + use<'a, 'b, 'bb, Self> {
193 async move {
194 IoSliceMut::advance_slices(&mut iovecs, 0);
196
197 let mut o = 0;
198 while !iovecs.is_empty() {
199 let r = self.readv_async(offs + o as u64, iovecs).await?;
200 IoSliceMut::advance_slices(&mut iovecs, r);
201 o += r;
202 }
203
204 Ok(())
205 }
206 }
207
208 fn read_to_end_async<'a>(
209 &'a self,
210 offs: u64,
211 ) -> impl core::future::Future<Output = IOResult<Vec<u8>>> + use<'a, Self> {
212 async move {
213 const GROW_SIZE: usize = 8192;
214
215 let mut buf = Vec::with_capacity(GROW_SIZE);
216 let mut o = 0;
217 loop {
218 let r = match self
219 .read_async(offs + o as u64, buf.spare_capacity_mut())
220 .await
221 {
222 Ok(0) => break,
223 Ok(r) => r,
224 Err(e) if e.kind() == std::io::ErrorKind::UnexpectedEof => break,
225 Err(e) => return Err(e),
226 };
227
228 o += r;
229 unsafe {
230 buf.set_len(o);
231 }
232 if o >= buf.capacity() {
233 buf.reserve_exact(GROW_SIZE);
234 }
235 }
236
237 buf.shrink_to_fit();
238 Ok(buf)
239 }
240 }
241}
242impl<'t, T> RandomReadBlobAsync for &'t T
243where
244 T: RandomReadBlobAsync + ?Sized + 't,
245{
246 type ReadFuture<'a, 'b>
247 = T::ReadFuture<'a, 'b>
248 where
249 Self: 'a;
250 type ReadVecFuture<'a, 'b, 'bb>
251 = T::ReadVecFuture<'a, 'b, 'bb>
252 where
253 Self: 'a,
254 'bb: 'b;
255
256 #[inline(always)]
257 fn read_async<'a, 'b>(
258 &'a self,
259 offs: u64,
260 buf: &'b mut [MaybeUninit<u8>],
261 ) -> Self::ReadFuture<'a, 'b> {
262 T::read_async(*self, offs, buf)
263 }
264
265 #[inline(always)]
266 fn readv_async<'a, 'b, 'bb>(
267 &'a self,
268 offs: u64,
269 iovecs: &'b mut [IoSliceMut<'bb>],
270 ) -> Self::ReadVecFuture<'a, 'b, 'bb> {
271 T::readv_async(*self, offs, iovecs)
272 }
273
274 #[inline(always)]
275 fn read_exact_async<'a, 'b>(
276 &'a self,
277 offs: u64,
278 buf: &'b mut [MaybeUninit<u8>],
279 ) -> impl core::future::Future<Output = IOResult<()>> + use<'a, 'b, 't, T> {
280 T::read_exact_async(*self, offs, buf)
281 }
282
283 #[inline(always)]
284 fn read_to_end_async<'a>(
285 &'a self,
286 offs: u64,
287 ) -> impl core::future::Future<Output = IOResult<Vec<u8>>> + use<'a, 't, T> {
288 T::read_to_end_async(*self, offs)
289 }
290
291 #[inline(always)]
292 fn readv_all_async<'a, 'b, 'bb>(
293 &'a self,
294 offs: u64,
295 iovecs: &'b mut [IoSliceMut<'bb>],
296 ) -> impl core::future::Future<Output = std::io::Result<()>> + use<'a, 'b, 'bb, 't, T> {
297 T::readv_all_async(*self, offs, iovecs)
298 }
299}
300
301pub trait MemoryMapBlob {
303 type MemoryUnmapData;
304
305 fn mmap(
306 &self,
307 offs: u64,
308 len: usize,
309 ) -> std::io::Result<(*mut core::ffi::c_void, Self::MemoryUnmapData)>;
310 fn munmap(&self, data: Self::MemoryUnmapData) -> std::io::Result<()>;
311}
312impl<'t, T> MemoryMapBlob for &'t T
313where
314 T: MemoryMapBlob + ?Sized + 't,
315{
316 type MemoryUnmapData = T::MemoryUnmapData;
317
318 #[inline(always)]
319 fn mmap(
320 &self,
321 offs: u64,
322 len: usize,
323 ) -> std::io::Result<(*mut core::ffi::c_void, Self::MemoryUnmapData)> {
324 T::mmap(*self, offs, len)
325 }
326
327 #[inline(always)]
328 fn munmap(&self, data: Self::MemoryUnmapData) -> std::io::Result<()> {
329 T::munmap(*self, data)
330 }
331}