1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
use crate::sys;
use core::{
fmt::{self, Write},
mem,
};
const BUF_SIZE: usize = 16;
#[derive(Debug, Clone, Copy)]
pub struct Writer(
pub sys::FileDesc,
);
impl Writer {
pub fn write_fmt(
&self,
arguments: fmt::Arguments,
) -> Result<(), sys::Error> {
let mut adapter = Adapter::new(self.0);
let _ = adapter.write_fmt(arguments);
adapter.finish()
}
}
#[derive(Debug)]
struct Adapter {
desc: sys::FileDesc,
buffer: [u8; BUF_SIZE],
cursor: usize,
result: Result<(), sys::Error>,
}
impl Adapter {
fn new(desc: sys::FileDesc) -> Self {
Self { desc, buffer: [0; BUF_SIZE], cursor: 0, result: Ok(()) }
}
fn flush(&mut self) -> Result<(), sys::Error> {
sys::write(self.desc, &self.buffer[.. self.cursor])?;
self.buffer = [0; BUF_SIZE];
self.cursor = 0;
Ok(())
}
fn finish(mut self) -> Result<(), sys::Error> {
mem::replace(&mut self.result, Ok(()))
}
}
impl Write for Adapter {
fn write_str(&mut self, data: &str) -> fmt::Result {
let mut bytes = data.as_bytes();
while bytes.len() > 0 && self.result.is_ok() {
let start = self.cursor;
let size = (BUF_SIZE - self.cursor).min(bytes.len());
let end = start + size;
self.buffer[start .. end].copy_from_slice(&bytes[.. size]);
self.cursor = end;
bytes = &bytes[size ..];
if bytes.len() > 0 {
self.result = self.flush();
}
}
match self.result {
Ok(_) => Ok(()),
Err(_) => Err(fmt::Error),
}
}
}
impl Drop for Adapter {
fn drop(&mut self) {
let _ = self.flush();
let _ = sys::fsync(self.desc);
}
}