1use memx::memnechr;
3use naive_opt::{string_rsearch_bytes, string_search_bytes};
4use std::fs;
5use std::io;
6use std::io::Read;
7use std::path::Path;
8
9use super::Pid;
10
11pub struct FileBuffer {
12 buffer: Vec<u8>,
13}
14
15impl FileBuffer {
16 pub fn new() -> Self {
17 Self {
18 buffer: Vec::with_capacity(3000),
19 }
20 }
21 pub fn least_capacity(&mut self, n: usize) {
22 if self.buffer.capacity() < n {
23 self.buffer.clear();
24 self.buffer.reserve(n);
25 }
26 }
27 pub fn clear(&mut self) {
28 self.buffer.clear();
29 }
30 pub fn read_from_file(&mut self, file_handle: &mut fs::File) -> io::Result<usize> {
31 self.buffer.clear();
32 #[cfg(not(windows))]
33 {
34 file_handle.read_to_end(&mut self.buffer)
35 }
36 #[cfg(windows)]
37 {
38 let mut buf: Vec<u8> = vec![];
39 let _ = file_handle.read_to_end(&mut buf)?;
40 for &a in buf.iter() {
41 if a != b'\r' {
42 self.buffer.push(a);
43 }
44 }
45 Ok(self.buffer.len())
46 }
47 }
48}
49impl Default for FileBuffer {
50 fn default() -> Self {
51 Self::new()
52 }
53}
54pub struct ProcFb {
55 pub name: &'static str,
56 pub capacity: usize,
57}
58
59impl ProcFb {
60 pub fn update<'a>(&self, base_path: &Path, fb: &'a mut FileBuffer) -> &'a [u8] {
61 fb.clear();
62 fb.least_capacity(self.capacity);
63 {
64 let name = format!("{}/proc/{}", base_path.to_str().unwrap(), self.name);
65 let mut fh = match fs::OpenOptions::new().read(true).open(&name) {
66 Ok(fh) => fh,
67 Err(_) => return fb.buffer.as_slice(),
68 };
69 let _len = match fb.read_from_file(&mut fh) {
70 Ok(len) => len,
71 Err(err) => {
72 eprintln!("{}: `{}`", err, &name);
73 return fb.buffer.as_slice();
74 }
75 };
76 }
77 fb.buffer.as_slice()
78 }
79}
80
81pub struct PidFb {
82 pub name: &'static str,
83 pub capacity: usize,
84}
85
86impl PidFb {
87 pub fn update_with_pid<'a>(
88 &self,
89 base_path: &Path,
90 fb: &'a mut FileBuffer,
91 pid: Pid,
92 ) -> &'a [u8] {
93 fb.clear();
94 fb.least_capacity(self.capacity);
95 {
96 let name = format!("{}/proc/{}/{}", base_path.to_str().unwrap(), pid, self.name);
97 let mut fh = match fs::OpenOptions::new().read(true).open(&name) {
98 Ok(fh) => fh,
99 Err(_) => return fb.buffer.as_slice(),
100 };
101 let _len = match fb.read_from_file(&mut fh) {
102 Ok(len) => len,
103 Err(err) => {
104 eprintln!("{}: `{}`", err, &name);
105 return fb.buffer.as_slice();
106 }
107 };
108 }
109 fb.buffer.as_slice()
110 }
111}
112
113pub struct SysCpuFb {
114 pub name: &'static str,
115 pub capacity: usize,
116}
117
118impl SysCpuFb {
119 pub fn update_with_cpu_num<'a>(
120 &self,
121 base_path: &Path,
122 fb: &'a mut FileBuffer,
123 cpu_num: usize,
124 ) -> &'a [u8] {
125 fb.clear();
126 fb.least_capacity(self.capacity);
127 {
128 let name = format!(
129 "{}/sys/devices/system/cpu/cpu{}/{}",
130 base_path.to_str().unwrap(),
131 cpu_num,
132 self.name
133 );
134 let mut fh = match fs::OpenOptions::new().read(true).open(&name) {
135 Ok(fh) => fh,
136 Err(_) => return fb.buffer.as_slice(),
137 };
138 let _len = match fb.read_from_file(&mut fh) {
139 Ok(len) => len,
140 Err(err) => {
141 eprintln!("{}: `{}`", err, &name);
142 return fb.buffer.as_slice();
143 }
144 };
145 }
146 fb.buffer.as_slice()
147 }
148}
149
150pub fn find_to_opt(haystack: &[u8], needle: &[u8]) -> Option<usize> {
160 string_search_bytes(haystack, needle)
161}
162
163pub fn find_to_pos(haystack: &[u8], needle: &[u8]) -> usize {
164 let o = find_to_opt(haystack, needle);
165 match o {
166 Some(pos) => pos,
167 None => {
168 unreachable!();
173 }
174 }
175}
176
177pub fn rfind_to_opt(haystack: &[u8], needle: &[u8]) -> Option<usize> {
179 string_rsearch_bytes(haystack, needle)
180}
181
182pub fn rfind_to_pos(haystack: &[u8], needle: &[u8]) -> usize {
183 let o = rfind_to_opt(haystack, needle);
184 match o {
185 Some(pos) => pos,
186 None => {
187 unreachable!();
192 }
193 }
194}
195
196pub fn skip_to_opt(buffer: &[u8], byte: u8) -> Option<usize> {
204 memnechr(buffer, byte)
205}
206
207pub fn skip_to_pos(buffer: &[u8], byte: u8) -> usize {
208 let o = skip_to_opt(buffer, byte);
209 match o {
210 Some(pos) => pos,
211 None => {
212 unreachable!();
217 }
218 }
219}