flex_page/
file_ext.rs

1use std::os;
2
3#[cfg(target_family = "unix")]
4pub use os::unix::fs::FileExt;
5
6#[cfg(target_family = "wasm")]
7pub use os::wasi::fs::FileExt;
8
9#[cfg(target_family = "windows")]
10pub trait FileExt {
11    fn read_at(&self, buf: &mut [u8], offset: u64) -> Result<usize>;
12    fn write_at(&self, buf: &[u8], offset: u64) -> Result<usize>;
13
14    fn read_exact_at(&self, mut buf: &mut [u8], mut offset: u64) -> Result<()> {
15        while !buf.is_empty() {
16            match self.read_at(buf, offset) {
17                Ok(0) => break,
18                Ok(n) => {
19                    let tmp = buf;
20                    buf = &mut tmp[n..];
21                    offset += n as u64;
22                }
23                Err(ref e) if e.kind() == ErrorKind::Interrupted => {}
24                Err(e) => return Err(e),
25            }
26        }
27        if !buf.is_empty() {
28            Err(Error::new(
29                ErrorKind::UnexpectedEof,
30                "failed to fill whole buffer",
31            ))
32        } else {
33            Ok(())
34        }
35    }
36
37    fn write_all_at(&self, mut buf: &[u8], mut offset: u64) -> Result<()> {
38        while !buf.is_empty() {
39            match self.write_at(buf, offset) {
40                Ok(0) => {
41                    return Err(Error::new(
42                        ErrorKind::WriteZero,
43                        "failed to write whole buffer",
44                    ));
45                }
46                Ok(n) => {
47                    buf = &buf[n..];
48                    offset += n as u64
49                }
50                Err(ref e) if e.kind() == ErrorKind::Interrupted => {}
51                Err(e) => return Err(e),
52            }
53        }
54        Ok(())
55    }
56}
57
58#[cfg(target_family = "windows")]
59use std::{
60    fs::File,
61    io::{Error, ErrorKind, Result},
62};
63
64#[cfg(target_family = "windows")]
65impl FileExt for File {
66    #[inline]
67    fn read_at(&self, buf: &mut [u8], offset: u64) -> Result<usize> {
68        os::windows::fs::FileExt::seek_read(self, buf, offset)
69    }
70
71    #[inline]
72    fn write_at(&self, buf: &[u8], offset: u64) -> Result<usize> {
73        os::windows::fs::FileExt::seek_write(self, buf, offset)
74    }
75}