1use alloc::vec::Vec;
2use axfs_vfs::{impl_vfs_non_dir_default, VfsNodeAttr, VfsNodeOps, VfsResult};
3use spin::RwLock;
4
5pub 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}