linux_procfs/
util.rs

1//#![allow(dead_code)]
2use 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
150//
151/*
152pub fn _0_find_to_opt(haystack: &[u8], needle: &[u8]) -> Option<usize> {
153    haystack
154        .windows(needle.len())
155        .position(|window| window == needle)
156}
157*/
158
159pub 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            /*
169            eprintln!("haystack:: \"{}\"", String::from_utf8_lossy(haystack));
170            eprintln!("needle:: \"{}\"", String::from_utf8_lossy(needle));
171             */
172            unreachable!();
173        }
174    }
175}
176
177//
178pub 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            /*
188            eprintln!("haystack:: \"{}\"", String::from_utf8_lossy(haystack));
189            eprintln!("needle:: \"{}\"", String::from_utf8_lossy(needle));
190            */
191            unreachable!();
192        }
193    }
194}
195
196//
197/*
198pub fn _0_skip_to_opt(buffer: &[u8], byte: u8) -> Option<usize> {
199    buffer.iter().position(|&x| x != byte)
200}
201*/
202
203pub 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            /*
213            eprintln!("buffer:: \"{}\"", String::from_utf8_lossy(buffer));
214            eprintln!("byte:: \"{}\"", String::from_utf8_lossy(byte));
215            */
216            unreachable!();
217        }
218    }
219}