1use std::io::{BufReader, IoSliceMut, Read, BufRead, Error, ErrorKind, Seek, SeekFrom};
2use std::fs::File;
3use std::{io, fmt, result};
4use std::sync::{Mutex, Arc, MutexGuard};
5use std::thread::sleep;
6use std::time::Duration;
7
8
9enum Maybe<T> {
10 Real(T),
11}
12
13struct TailedFileRaw(BufReader<File>);
14pub struct TailedFile {
16 inner: Arc<Mutex<BufReader<Maybe<TailedFileRaw>>>>
17}
18
19impl TailedFile {
20 pub fn new(mut file: File) -> Self {
21 let _ = file.seek(SeekFrom::End(0));
22 let a = BufReader::new(file);
23 TailedFile {
24 inner: Arc::new(Mutex::new(BufReader::with_capacity(10000, Maybe::Real(TailedFileRaw(a)))))
25 }
26
27 }
28 pub fn lock(&self) -> TailedFileLock<'_> {
29 TailedFileLock { inner: self.inner.lock().unwrap_or_else(|e| e.into_inner()) }
30 }
31
32 }
38
39pub struct TailedFileLock<'a> {
40 inner: MutexGuard<'a, BufReader<Maybe<TailedFileRaw>>>,
41}
42
43impl fmt::Debug for TailedFileLock<'_> {
44 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
45 f.pad("TailedFileLock { .. }")
46 }
47}
48
49impl BufRead for TailedFileLock<'_> {
50 fn fill_buf(&mut self) -> io::Result<&[u8]> {
51 self.inner.fill_buf()
52 }
53
54 fn consume(&mut self, n: usize) {
55 self.inner.consume(n)
56 }
57
58 fn read_until(&mut self, byte: u8, buf: &mut Vec<u8>) -> io::Result<usize> {
59 self.inner.read_until(byte, buf)
60 }
61
62 fn read_line(&mut self, buf: &mut String) -> io::Result<usize> {
63append_to_string(buf, |b| read_until(self, b'\n', b))
67
68 }
69}
70
71fn read_until<R: BufRead + ?Sized>(r: &mut R, delim: u8, buf: &mut Vec<u8>) -> Result<usize> {
72 let mut read = 0;
73 loop {
74 let (done, used) = {
75 let available = match r.fill_buf() {
76 Ok(n) if !n.is_empty() => n,
77 Err(ref e) if e.kind() == ErrorKind::Interrupted => {sleep(Duration::from_millis(1)); continue;},
78 Err(e) => return Err(e),
79 _ => {continue}
80 };
81 match memchr::memchr(delim, available) {
82 Some(i) => {
83 buf.extend_from_slice(&available[..=i]);
84 (true, i + 1)
85 }
86 None => {
87 buf.extend_from_slice(available);
88 (false, available.len())
89 }
90 }
91 };
92 r.consume(used);
93 read += used;
94 if done || used == 0 {
95 return Ok(read);
96 }
97 }
98}
99
100struct Guard<'a> {
101 buf: &'a mut Vec<u8>,
102 len: usize,
103}
104
105impl Drop for Guard<'_> {
106 fn drop(&mut self) {
107 unsafe {
108 self.buf.set_len(self.len);
109 }
110 }
111}
112
113
114pub type Result<T> = result::Result<T, Error>;
115fn append_to_string<F>(buf: &mut String, f: F) -> Result<usize>
116 where
117 F: FnOnce(&mut Vec<u8>) -> Result<usize>,
118{
119 unsafe {
120 let mut g = Guard { len: buf.len(), buf: buf.as_mut_vec() };
121 let ret = f(g.buf);
122 if std::str::from_utf8(&g.buf[g.len..]).is_err() {
123 ret.and_then(|_| {
124 Err(Error::new(ErrorKind::InvalidData, "stream did not contain valid UTF-8"))
125 })
126 } else {
127 g.len = g.buf.len();
128 ret
129 }
130 }
131}
132
133impl Read for TailedFileLock<'_> {
134 fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
135 self.inner.read(buf)
136 }
137
138 fn read_vectored(&mut self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
139 self.inner.read_vectored(bufs)
140 }
141
142 fn read_to_end(&mut self, buf: &mut Vec<u8>) -> io::Result<usize> {
150 self.inner.read_to_end(buf)
151 }
152
153 fn read_to_string(&mut self, buf: &mut String) -> io::Result<usize> {
154 self.inner.read_to_string(buf)
155 }
156
157 fn read_exact(&mut self, buf: &mut [u8]) -> io::Result<()> {
158 self.inner.read_exact(buf)
159 }
160}
161
162impl Read for TailedFileRaw {
163 fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
164 self.0.read(buf)
165 }
166
167 fn read_vectored(&mut self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
168 self.0.read_vectored(bufs)
169 }
170
171 fn read_to_end(&mut self, buf: &mut Vec<u8>) -> io::Result<usize> {
177 self.0.read_to_end(buf)
178 }
179
180 fn read_to_string(&mut self, buf: &mut String) -> io::Result<usize> {
181 self.0.read_to_string(buf)
182 }
183
184 fn read_exact(&mut self, buf: &mut [u8]) -> io::Result<()> {
185 self.0.read_exact(buf)
186 }
187}
188
189impl<R: io::Read> io::Read for Maybe<R> {
190 fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
191 match *self {
192 Maybe::Real(ref mut r) => handle_ebadf(r.read(buf), 0),
193 }
194 }
195
196 fn read_vectored(&mut self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
197 match self {
198 Maybe::Real(r) => handle_ebadf(r.read_vectored(bufs), 0),
199 }
200 }
201
202}
203
204fn handle_ebadf<T>(r: io::Result<T>, default: T) -> io::Result<T> {
205
206 match r {
207 Err(ref _e) => Ok(default),
209 r => r,
210 }
211}