diff options
author | Nathan Ringo <nathan@remexre.com> | 2024-08-26 20:53:46 -0500 |
---|---|---|
committer | Nathan Ringo <nathan@remexre.com> | 2024-08-26 20:53:46 -0500 |
commit | d10960f7fc664189f70fb634581958a4a1fd99fa (patch) | |
tree | fa39b8939fff7694f7e9cbcdf4bbd70e53500b6f /kernel/src/util.rs | |
parent | 76f0764cebe313a75b9b170fa23fa940d9e5738a (diff) |
Refactor DeviceTree parsing.
Diffstat (limited to 'kernel/src/util.rs')
-rw-r--r-- | kernel/src/util.rs | 44 |
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); |