summaryrefslogtreecommitdiff
path: root/src/devices/file/circular_path_buffer.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/devices/file/circular_path_buffer.rs')
-rw-r--r--src/devices/file/circular_path_buffer.rs66
1 files changed, 66 insertions, 0 deletions
diff --git a/src/devices/file/circular_path_buffer.rs b/src/devices/file/circular_path_buffer.rs
new file mode 100644
index 0000000..f828f73
--- /dev/null
+++ b/src/devices/file/circular_path_buffer.rs
@@ -0,0 +1,66 @@
+use std::ffi::OsString;
+use std::os::unix::ffi::OsStringExt;
+use std::path::PathBuf;
+
+pub struct CircularPathBuffer {
+ buffer: [u8; 256],
+ pointer: u8,
+}
+
+impl CircularPathBuffer {
+ pub fn new() -> Self {
+ Self { buffer: [0; 256] , pointer: 0 }
+ }
+
+ pub fn clear(&mut self) {
+ self.buffer.fill(0);
+ self.pointer = 0;
+ }
+
+ pub fn populate(&mut self, bytes: &[u8]) {
+ self.clear();
+ if bytes.len() > 255 {
+ unreachable!(
+ "Attempted to populate CircularPathBuffer with {} bytes: {:?}",
+ bytes.len(), String::from_utf8_lossy(bytes)
+ )
+ }
+ let self_slice = &mut self.buffer[..bytes.len()];
+ self_slice.copy_from_slice(&bytes);
+ }
+
+ pub fn set_pointer(&mut self, value: u8) {
+ self.pointer = 0;
+ if value != 0x00 {
+ for (i, c) in self.buffer.iter().enumerate() {
+ match c {
+ b'/' => self.pointer = (i + 1) as u8,
+ 0x00 => break,
+ _ => continue,
+ }
+ }
+ }
+ }
+
+ pub fn read_byte(&mut self) -> u8 {
+ let pointer = self.pointer as usize;
+ self.pointer = self.pointer.wrapping_add(1);
+ self.buffer[pointer]
+ }
+
+ // Returns an unsanitized relative path.
+ pub fn push_byte(&mut self, value: u8) -> Option<PathBuf> {
+ if value == 0x00 {
+ let pointer = self.pointer as usize;
+ let vec = self.buffer[..pointer].to_vec();
+ self.clear();
+ let os_string: OsString = OsStringExt::from_vec(vec);
+ Some(os_string.into())
+ } else {
+ let pointer = self.pointer as usize;
+ self.pointer = self.pointer.wrapping_add(1);
+ self.buffer[pointer] = value;
+ None
+ }
+ }
+}