1use crate::cio::{find_available_channel, Cmd, Mode, IOCB};
2
3pub struct File {
4    pub channel: u8,
5}
6
7impl File {
8    pub fn create(filename: &[u8]) -> Result<File, u8> {
11        File::open_with_mode(filename, Mode::Write)
12    }
13
14    pub fn open(filename: &[u8]) -> Result<File, u8> {
17        File::open_with_mode(filename, Mode::Read)
18    }
19
20    pub fn open_with_mode(filename: &[u8], mode: Mode) -> Result<File, u8> {
21        let channel = find_available_channel()?;
22        let ret = IOCB::new(channel)
23            .cmd(Cmd::Open as u8)
24            .buffer(filename)
25            .icax1(mode as u8)
26            .icax2(0)
27            .call();
28        if ret >= 128 {
29            return Err(ret);
30        }
31        Ok(File { channel })
32    }
33
34    pub fn write(&mut self, data: &[u8]) -> Result<(), u8> {
36        let ret = IOCB::new(self.channel)
37            .cmd(Cmd::PutBytes as u8)
38            .buffer(data)
39            .call();
40        if ret >= 128 {
41            return Err(ret);
42        }
43        Ok(())
44    }
45
46    pub fn read(&mut self, data: &mut [u8]) -> Result<usize, u8> {
49        let mut iocb = IOCB::new(self.channel);
50        iocb.cmd(Cmd::GetBytes as u8).buffer(data);
51        let ret = iocb.call();
52        if ret >= 128 && ret != 136 {
53            return Err(ret);
54        }
55        Ok(iocb.get_buf_len())
56    }
57
58    pub fn close(&mut self) {
61        if self.channel < 128 {
62            IOCB::new(self.channel).cmd(Cmd::Close as u8).call();
63            self.channel |= 128; }
65    }
66}
67
68impl Drop for File {
69    fn drop(&mut self) {
70        self.close();
71    }
72}