pluginop_wasm/
fd.rs

1//! Plugin-side interface to file system API.
2
3use std::{
4    io::{Read, Write},
5    path::Path,
6};
7
8use pluginop_common::{WASMLen, WASMPtr};
9use std::convert::TryFrom;
10
11extern "C" {
12    fn create_file_from_plugin(path_ptr: u32, path_len: u32) -> i64;
13    fn write_file_from_plugin(fd: i64, ptr: u32, len: u32) -> i64;
14}
15
16pub enum FileDescriptorType {
17    File(i64),
18    Network,
19}
20
21/// A structure enabling a plugin to read from or write to an external entity, whether it is using
22/// the network (a.k.a. a socket) or is local to the host (a.k.a. a file).
23pub struct FileDescriptor {
24    fd: FileDescriptorType,
25}
26
27impl FileDescriptor {
28    pub fn open<P: AsRef<Path>>(_path: P) -> std::io::Result<Self> {
29        todo!()
30    }
31
32    pub fn create(path: &str) -> std::io::Result<Self> {
33        match unsafe { create_file_from_plugin(path.as_ptr() as WASMPtr, path.len() as WASMLen) } {
34            fd if fd >= 0 => Ok(FileDescriptor {
35                fd: FileDescriptorType::File(fd),
36            }),
37            _ => Err(std::io::Error::new(
38                std::io::ErrorKind::Other,
39                "Cannot create file",
40            )),
41        }
42    }
43}
44
45impl Read for FileDescriptor {
46    fn read(&mut self, _buf: &mut [u8]) -> std::io::Result<usize> {
47        todo!()
48    }
49}
50
51impl Write for FileDescriptor {
52    fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
53        match self.fd {
54            FileDescriptorType::File(fd) => {
55                match u32::try_from(unsafe {
56                    write_file_from_plugin(fd, buf.as_ptr() as u32, buf.len() as u32)
57                }) {
58                    Ok(written) => Ok(written as usize),
59                    Err(_) => Err(std::io::Error::new(
60                        std::io::ErrorKind::Other,
61                        "error when writing",
62                    )),
63                }
64            }
65            FileDescriptorType::Network => todo!("write not implemented on network"),
66        }
67    }
68
69    fn flush(&mut self) -> std::io::Result<()> {
70        // crate::print("Plugin calling flush, why?");
71        Ok(())
72    }
73}