Fix in_area helper, add in_area_inclusive helper and compare_bytes helper
@@ -19,11 +19,31 @@ pub fn distance_absolute<T: Sized>(a: *const T, b: *const T) -> usize {
unsafe { a.offset_from(b).abs() as usize }
}
-/// Returns true if `ptr` is in the memory region between `start` and `end`
+/// Returns true if `ptr` is in the memory region between `start` and `end`,
+/// specifically if `ptr` falls in the range including `start` but excluding `end`
///
/// NOTE: If any of the given pointers are null, then false will be returned
#[inline]
pub fn in_area<T, U>(ptr: *const T, start: *const U, end: *const U) -> bool {
+ // If any pointers are null, the only sensible answer is false
+ if ptr.is_null() || start.is_null() || end.is_null() {
+ false
+ } else {
+ debug_assert!(start as usize <= end as usize);
+
+ let start = start as usize;
+ let end = end as usize;
+ let ptr = ptr as usize;
+ start <= ptr && ptr < end
+ }
+}
+
+/// Returns true if `ptr` is in the memory region between `start` and `end`,
+/// specifically if `ptr` falls in the range including `start` _and_ `end`
+///
+/// NOTE: If any of the given pointers are null, then false will be returned
+#[inline]
+pub fn in_area_inclusive<T, U>(ptr: *const T, start: *const U, end: *const U) -> bool {
// If any pointers are null, the only sensible answer is false
if ptr.is_null() || start.is_null() || end.is_null() {
false
@@ -37,6 +57,22 @@ pub fn in_area<T, U>(ptr: *const T, start: *const U, end: *const U) -> bool {
}
}
+/// Performs a byte-by-byte comparison of the values pointed to by `src` and `dst`,
+/// returning `Ok` if they are equal, and `Err(index)` if they are not equal, where
+/// `index` is the byte where the values differ
+///
+/// # Safety
+///
+/// This function will fail with a segmentation fault if the memory regions represented
+/// by the given pointers + size in bytes is not allocated. The caller must ensure that
+/// is the case before calling this.
+#[inline]
+pub unsafe fn compare_bytes<T: PartialEq + Sized>(src: *const T, dst: *const T, size: usize) -> bool {
+ let lhs = core::slice::from_raw_parts(src, size);
+ let rhs = core::slice::from_raw_parts(dst, size);
+ lhs.eq(rhs)
+}
+
#[cfg(test)]
mod tests {
use super::*;
