Skip to main content

rust_profanos/libs/std/
fs.rs

1extern crate alloc;
2
3use alloc::ffi::CString;
4
5use crate::libs::libc::{self, CFILE, SEEK};
6
7use super::io::Read;
8
9#[derive(Debug)]
10pub struct File {
11    inner: *mut CFILE,
12    metadata: Metadata
13}
14
15#[derive(Debug, Clone, Copy)]
16pub struct Metadata {
17    length: usize,
18}
19
20impl Metadata {
21    pub fn len(&self) -> usize {
22        self.length
23    }
24}
25
26impl File {
27    pub fn open(path: &str) -> Option<File> {
28        let filepath = CString::new(path).unwrap();
29        let mode = CString::new("r").unwrap();
30
31        use crate::libs::libc::fopen_c;
32
33        unsafe {
34            // we open with the C interface
35            let inner_file = fopen_c(filepath.as_ptr() as *const u8, mode.as_ptr() as *const u8);
36            
37            // we get the length of the file
38            let base_pos = libc::ftell_c(inner_file);
39            libc::fseek_c(inner_file, 0, SEEK::SEEK_END as usize);
40            let size = libc::ftell_c(inner_file);
41            libc::fseek_c(inner_file, 0, base_pos);
42
43            // we transmute into a File
44            let myfile = File {
45                inner: inner_file,
46                metadata: Metadata {
47                    length: size
48                }
49            };
50
51            Some(myfile)
52        }
53    }
54
55    pub fn metadata(&self) -> Option<Metadata> {
56        Some(self.metadata)
57    }
58}
59
60
61impl Read for File {
62    fn read(&mut self, buf: &mut [u8]) -> Option<usize> {
63        let fd = self.inner;
64        
65        let bytes_read = unsafe {
66            libc::fread_c(
67                buf.as_mut_ptr(),
68                1,
69                buf.len(), 
70                fd
71            ) as usize
72        };
73        
74        // If `bytes_read` is 0, we hit the end of the file
75        if bytes_read == 0 {
76            Some(0)
77        } else if bytes_read < buf.len() {
78            // Partially read data
79            Some(bytes_read)
80        } else {
81            // Successfully read into the buffer
82            Some(bytes_read)
83        }
84    }
85}