aboutsummaryrefslogtreecommitdiff
path: root/utils/src/read_ext.rs
diff options
context:
space:
mode:
Diffstat (limited to 'utils/src/read_ext.rs')
-rw-r--r--utils/src/read_ext.rs38
1 files changed, 38 insertions, 0 deletions
diff --git a/utils/src/read_ext.rs b/utils/src/read_ext.rs
new file mode 100644
index 0000000..7695ada
--- /dev/null
+++ b/utils/src/read_ext.rs
@@ -0,0 +1,38 @@
+use std::convert::TryInto;
+
+pub trait ReadExt {
+ fn read_exact(&mut self, n: usize) -> Option<&[u8]>;
+
+ fn read_le_i32(&mut self) -> Option<i32> {
+ self.read_exact(4).map(|bytes| i32::from_le_bytes(bytes.try_into().unwrap()))
+ }
+
+ fn read_le_u32(&mut self) -> Option<u32> {
+ self.read_exact(4).map(|bytes| u32::from_le_bytes(bytes.try_into().unwrap()))
+ }
+
+ fn read_le_u64(&mut self) -> Option<u64> {
+ self.read_exact(8).map(|bytes| u64::from_le_bytes(bytes.try_into().unwrap()))
+ }
+
+ fn read_pascal_blob(&mut self) -> Option<&[u8]> {
+ let len = self.read_le_u64()?;
+ self.read_exact(len as usize)
+ }
+
+ fn read_pascal_string(&mut self) -> Option<Result<String, std::string::FromUtf8Error>> {
+ self.read_pascal_blob().map(|b| String::from_utf8(b.to_vec()))
+ }
+}
+
+impl ReadExt for &[u8] {
+ fn read_exact(&mut self, n: usize) -> Option<&[u8]> {
+ if self.len() >= n {
+ let (res, newlist) = self.split_at(n);
+ *self = newlist;
+ Some(res)
+ } else {
+ None
+ }
+ }
+}