summaryrefslogtreecommitdiff
path: root/kernel/src/util.rs
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/src/util.rs')
-rw-r--r--kernel/src/util.rs44
1 files changed, 44 insertions, 0 deletions
diff --git a/kernel/src/util.rs b/kernel/src/util.rs
index 93c684d..29042c8 100644
--- a/kernel/src/util.rs
+++ b/kernel/src/util.rs
@@ -1,5 +1,7 @@
//! Miscellaneous utilities.
+use core::mem::size_of;
+
#[cold]
#[inline(always)]
fn cold() {}
@@ -48,3 +50,45 @@ macro_rules! dbg {
($($crate::dbg!($expr)),+,)
};
}
+
+/// A trait for types that can be converted to from big-endian or little-endian byte slices.
+pub trait FromEndianBytes {
+ /// Converts from a big-endian byte slice.
+ fn from_big_endian_bytes(bytes: &[u8]) -> Self;
+
+ /// Converts from a little-endian byte slice.
+ fn from_little_endian_bytes(bytes: &[u8]) -> Self;
+}
+
+macro_rules! impl_FromEndianBytes {
+ ($($ty:ty),* $(,)?) => {
+ $(impl FromEndianBytes for $ty {
+ fn from_big_endian_bytes(bytes: &[u8]) -> $ty {
+ let chunk = match bytes.last_chunk() {
+ Some(chunk) => *chunk,
+ None => {
+ let mut chunk = [0; size_of::<$ty>()];
+ chunk[size_of::<$ty>() - bytes.len()..]
+ .copy_from_slice(bytes);
+ chunk
+ },
+ };
+ <$ty>::from_be_bytes(chunk)
+ }
+
+ fn from_little_endian_bytes(bytes: &[u8]) -> $ty {
+ let chunk = match bytes.first_chunk() {
+ Some(chunk) => *chunk,
+ None => {
+ let mut chunk = [0; size_of::<$ty>()];
+ chunk[.. bytes.len()].copy_from_slice(bytes);
+ chunk
+ },
+ };
+ <$ty>::from_le_bytes(chunk)
+ }
+ })*
+ };
+}
+
+impl_FromEndianBytes!(i8, i16, i32, i64, isize, u8, u16, u32, u64, usize);