axfs_ramfs/
file.rs

1use alloc::vec::Vec;
2use axfs_vfs::{impl_vfs_non_dir_default, VfsNodeAttr, VfsNodeOps, VfsResult};
3use spin::RwLock;
4
5/// The file node in the RAM filesystem.
6///
7/// It implements [`axfs_vfs::VfsNodeOps`].
8pub struct FileNode {
9    content: RwLock<Vec<u8>>,
10}
11
12impl FileNode {
13    pub(super) const fn new() -> Self {
14        Self {
15            content: RwLock::new(Vec::new()),
16        }
17    }
18}
19
20impl VfsNodeOps for FileNode {
21    fn get_attr(&self) -> VfsResult<VfsNodeAttr> {
22        Ok(VfsNodeAttr::new_file(self.content.read().len() as _, 0))
23    }
24
25    fn truncate(&self, size: u64) -> VfsResult {
26        let mut content = self.content.write();
27        if size < content.len() as u64 {
28            content.truncate(size as _);
29        } else {
30            content.resize(size as _, 0);
31        }
32        Ok(())
33    }
34
35    fn read_at(&self, offset: u64, buf: &mut [u8]) -> VfsResult<usize> {
36        let content = self.content.read();
37        let start = content.len().min(offset as usize);
38        let end = content.len().min(offset as usize + buf.len());
39        let src = &content[start..end];
40        buf[..src.len()].copy_from_slice(src);
41        Ok(src.len())
42    }
43
44    fn write_at(&self, offset: u64, buf: &[u8]) -> VfsResult<usize> {
45        let offset = offset as usize;
46        let mut content = self.content.write();
47        if offset + buf.len() > content.len() {
48            content.resize(offset + buf.len(), 0);
49        }
50        let dst = &mut content[offset..offset + buf.len()];
51        dst.copy_from_slice(&buf[..dst.len()]);
52        Ok(buf.len())
53    }
54
55    impl_vfs_non_dir_default! {}
56}