From ae65fb6808a2de39646d9cf0fa878ae7ed1b6b4a Mon Sep 17 00:00:00 2001 From: Burkhard Mittelbach Date: Sun, 14 Jul 2024 15:47:37 +0200 Subject: [PATCH] Add size and len for PageRange, PhysFrameRange etc --- Changelog.md | 4 +++ src/structures/paging/frame.rs | 49 ++++++++++++++++++++++++++++++++++ src/structures/paging/page.rs | 45 +++++++++++++++++++++++++++++++ 3 files changed, 98 insertions(+) diff --git a/Changelog.md b/Changelog.md index 10772bf7..f517e673 100644 --- a/Changelog.md +++ b/Changelog.md @@ -1,5 +1,9 @@ # Unreleased +## New Features + +- [add `size` and `len` for `PageRange`, `PhysFrameRange`, `PageRangeInclusive` and `PhysFrameRangeInclusive`](https://github.com/rust-osdev/x86_64/pull/491) + # 0.15.1 – 2024-03-19 ## New Features diff --git a/src/structures/paging/frame.rs b/src/structures/paging/frame.rs index 1e5862b6..c4a8c97a 100644 --- a/src/structures/paging/frame.rs +++ b/src/structures/paging/frame.rs @@ -148,6 +148,22 @@ impl PhysFrameRange { pub fn is_empty(&self) -> bool { self.start >= self.end } + + /// Returns the number of frames in the range. + #[inline] + pub fn len(&self) -> u64 { + if !self.is_empty() { + self.end - self.start + } else { + 0 + } + } + + /// Returns the size in bytes of all frames within the range. + #[inline] + pub fn size(&self) -> u64 { + S::SIZE * self.len() + } } impl Iterator for PhysFrameRange { @@ -190,6 +206,22 @@ impl PhysFrameRangeInclusive { pub fn is_empty(&self) -> bool { self.start > self.end } + + /// Returns the number of frames in the range. + #[inline] + pub fn len(&self) -> u64 { + if !self.is_empty() { + self.end - self.start + 1 + } else { + 0 + } + } + + /// Returns the size in bytes of all frames within the range. + #[inline] + pub fn size(&self) -> u64 { + S::SIZE * self.len() + } } impl Iterator for PhysFrameRangeInclusive { @@ -215,3 +247,20 @@ impl fmt::Debug for PhysFrameRangeInclusive { .finish() } } + +#[cfg(test)] +mod tests { + use super::*; + #[test] + pub fn test_frame_range_len() { + let start_addr = PhysAddr::new(0xdead_beaf); + let start = PhysFrame::::containing_address(start_addr); + let end = start + 50; + + let range = PhysFrameRange { start, end }; + assert_eq!(range.len(), 50); + + let range_inclusive = PhysFrameRangeInclusive { start, end }; + assert_eq!(range_inclusive.len(), 51); + } +} diff --git a/src/structures/paging/page.rs b/src/structures/paging/page.rs index 445abd26..55720cf4 100644 --- a/src/structures/paging/page.rs +++ b/src/structures/paging/page.rs @@ -327,6 +327,22 @@ impl PageRange { pub fn is_empty(&self) -> bool { self.start >= self.end } + + /// Returns the number of pages in the range. + #[inline] + pub fn len(&self) -> u64 { + if !self.is_empty() { + self.end - self.start + } else { + 0 + } + } + + /// Returns the size in bytes of all pages within the range. + #[inline] + pub fn size(&self) -> u64 { + S::SIZE * self.len() + } } impl Iterator for PageRange { @@ -380,6 +396,22 @@ impl PageRangeInclusive { pub fn is_empty(&self) -> bool { self.start > self.end } + + /// Returns the number of frames in the range. + #[inline] + pub fn len(&self) -> u64 { + if !self.is_empty() { + self.end - self.start + 1 + } else { + 0 + } + } + + /// Returns the size in bytes of all frames within the range. + #[inline] + pub fn size(&self) -> u64 { + S::SIZE * self.len() + } } impl Iterator for PageRangeInclusive { @@ -484,4 +516,17 @@ mod tests { } assert_eq!(range_inclusive.next(), None); } + + #[test] + pub fn test_page_range_len() { + let start_addr = VirtAddr::new(0xdead_beaf); + let start = Page::::containing_address(start_addr); + let end = start + 50; + + let range = PageRange { start, end }; + assert_eq!(range.len(), 50); + + let range_inclusive = PageRangeInclusive { start, end }; + assert_eq!(range_inclusive.len(), 51); + } }