virtual_file_system/
file.rs

1use core::fmt::Debug;
2
3use alloc::vec::Vec;
4use futures::block_on;
5use task::TaskIdentifier;
6
7use file_system::{
8    Flags, Path, Position, Result, Size, Statistics_type, Status, UniqueFileIdentifier,
9};
10
11use super::VirtualFileSystem;
12
13/// File structure.
14///
15/// This structure is used to represent a file in the virtual file system.
16/// This is a wrapper around the virtual file system file identifier.
17pub struct File<'a> {
18    file_identifier: UniqueFileIdentifier,
19    file_system: &'a VirtualFileSystem<'a>,
20    task: TaskIdentifier,
21}
22
23impl Debug for File<'_> {
24    fn fmt(&self, formatter: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
25        formatter
26            .debug_struct("File")
27            .field("File_identifier", &self.file_identifier)
28            .field("File_system", &(self.file_system as *const _))
29            .finish()
30    }
31}
32
33impl<'a> File<'a> {
34    pub async fn open(
35        file_system: &'a VirtualFileSystem<'a>,
36        path: impl AsRef<Path>,
37        flags: Flags,
38    ) -> Result<Self> {
39        let task = task::get_instance().get_current_task_identifier().await;
40
41        let file_identifier = file_system.open(&path, flags, task).await?;
42
43        Ok(File {
44            file_identifier,
45            file_system,
46            task,
47        })
48    }
49
50    pub async fn create_unnamed_pipe(
51        file_system: &'a VirtualFileSystem<'a>,
52        size: usize,
53        status: Status,
54        task: TaskIdentifier,
55    ) -> Result<(Self, Self)> {
56        let (file_identifier_read, file_identifier_write) =
57            file_system.create_unnamed_pipe(task, status, size).await?;
58
59        Ok((
60            File {
61                file_identifier: file_identifier_read,
62                file_system,
63                task,
64            },
65            File {
66                file_identifier: file_identifier_write,
67                file_system,
68                task,
69            },
70        ))
71    }
72
73    // - Setters
74    pub async fn set_position(&self, position: &Position) -> Result<Size> {
75        self.file_system
76            .set_position(self.get_file_identifier(), position, self.task)
77            .await
78    }
79
80    // - Getters
81    pub const fn get_file_identifier(&self) -> UniqueFileIdentifier {
82        self.file_identifier
83    }
84
85    // - Operations
86
87    pub async fn write(&self, buffer: &[u8]) -> Result<Size> {
88        self.file_system
89            .write(self.get_file_identifier(), buffer, self.task)
90            .await
91    }
92
93    pub async fn write_line(&self, buffer: &[u8]) -> Result<Size> {
94        let size = self.write(buffer).await? + self.write(b"\n").await?;
95        Ok(size)
96    }
97
98    pub async fn read(&self, buffer: &mut [u8]) -> Result<Size> {
99        self.file_system
100            .read(self.get_file_identifier(), buffer, self.task)
101            .await
102    }
103    pub async fn read_line(&self, buffer: &mut [u8]) -> Result<()> {
104        let mut index = 0;
105        loop {
106            let size: usize = self.read(&mut buffer[index..index + 1]).await?.into();
107            if size == 0 {
108                break;
109            }
110            if buffer[index] == b'\n' {
111                break;
112            }
113            index += 1;
114        }
115        Ok(())
116    }
117
118    pub async fn read_to_end(&self, buffer: &mut Vec<u8>) -> Result<Size> {
119        self.file_system
120            .read_to_end(self.get_file_identifier(), self.task, buffer)
121            .await
122    }
123
124    pub async fn get_statistics(&self) -> Result<Statistics_type> {
125        self.file_system
126            .get_statistics(self.get_file_identifier(), self.task)
127            .await
128    }
129}
130
131impl Drop for File<'_> {
132    fn drop(&mut self) {
133        let _ = block_on(
134            self.file_system
135                .close(self.get_file_identifier(), self.task),
136        );
137    }
138}