d4_framefile/
blob.rs

1use crate::randfile::RandFile;
2use std::io::{Read, Result, Seek};
3
4#[cfg(all(feature = "mapped_io", not(target_arch = "wasm32")))]
5use std::fs::File;
6
7pub struct Blob<T> {
8    file: RandFile<T>,
9    size: usize,
10    offset: u64,
11}
12
13pub struct BlobReader<'a, T> {
14    cursor: u64,
15    blob: &'a mut Blob<T>,
16}
17
18impl<'a, T: Read + Seek> Read for BlobReader<'a, T> {
19    fn read(&mut self, buf: &mut [u8]) -> Result<usize> {
20        let bytes_read = self.blob.read_block(self.cursor, buf)?;
21        self.cursor += bytes_read as u64;
22        Ok(bytes_read)
23    }
24}
25
26impl<T: Read + Seek> Blob<T> {
27    pub fn get_reader(&mut self) -> BlobReader<'_, T> {
28        BlobReader {
29            cursor: 0,
30            blob: self,
31        }
32    }
33    pub fn size(&self) -> usize {
34        self.size
35    }
36    pub fn get_view(&self, offset: u64, size: usize) -> Self {
37        let rel_offset = offset.min(self.size as u64);
38        let abs_offset = self.offset + rel_offset;
39        let size = (self.size - rel_offset as usize).min(size);
40
41        Self {
42            file: self.file.clone(),
43            size,
44            offset: abs_offset,
45        }
46    }
47    pub fn read_block(&mut self, offset: u64, buf: &mut [u8]) -> Result<usize> {
48        if self.size < offset as usize {
49            return Ok(0);
50        }
51
52        let bytes_to_read = buf.len().min(self.size - offset as usize);
53
54        self.file.read_block(self.offset + offset, buf)?;
55
56        Ok(bytes_to_read)
57    }
58}
59
60impl<T> Blob<T> {
61    pub(crate) fn new(file: RandFile<T>, offset: u64, size: usize) -> Self {
62        Self { file, size, offset }
63    }
64}
65
66#[cfg(all(feature = "mapped_io", not(target_arch = "wasm32")))]
67impl Blob<File> {
68    pub fn mmap(&self) -> Result<impl AsRef<[u8]>> {
69        self.file.mmap(self.offset, self.size)
70    }
71    pub fn mmap_mut(&mut self) -> Result<impl AsMut<[u8]>> {
72        self.file.mmap_mut(self.offset, self.size)
73    }
74}