diff --git a/src/data.rs b/src/data.rs index ee382c0..db898d8 100644 --- a/src/data.rs +++ b/src/data.rs @@ -38,4 +38,49 @@ pub fn distance(p1: impl IntoUsize, p2: impl IntoUsize) -> usize { Ordering::Greater => p1 - p2, Ordering::Equal => 0, } -} \ No newline at end of file +} + +mod pointer_iterator { + + pub trait Pointer { + type IterType; + fn into_iter(self) -> Self::IterType; + } + + pub struct PIter(*const T); + pub struct PIterMut(*mut T); + + impl Iterator for PIter { + type Item = &'static T; + fn next(&mut self) -> Option { + unsafe { + let r = Some(&*self.0); + self.0 = self.0.offset(1isize); + r + } + } + } + + impl Iterator for PIterMut { + type Item = &'static mut T; + fn next(&mut self) -> Option { + unsafe { + let r = Some(&mut *self.0); + self.0 = self.0.offset(1isize); + r + } + } + } + impl Pointer for *const T { + type IterType = PIter; + fn into_iter(self) -> Self::IterType { PIter(self) } + } + impl Pointer for *mut T { + type IterType = PIterMut; + fn into_iter(self) -> Self::IterType { PIterMut(self) } + } +} + +pub fn iterate(pointer: T) -> T::IterType { + pointer.into_iter() +} diff --git a/src/lib.rs b/src/lib.rs index f427b2f..8df2041 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -30,7 +30,7 @@ pub use cffi::*; pub mod win32; #[cfg(feature = "win32")] -pub use win32::{ image_base, image_header, find_kernel32 }; +pub use win32::{ image_base, image_header, find_kernel32, process_executable }; /// re-export the signature macro diff --git a/tests/test_data.rs b/tests/test_data.rs index 448bb62..3f0a850 100644 --- a/tests/test_data.rs +++ b/tests/test_data.rs @@ -1,13 +1,27 @@ - #[test] pub fn test_distance() { + let _ = x::dur![ 5 days 4 hours 7 minutes 2 seconds 2 minutes ]; - let a = x::dur![ 5 days 4 hours 7 minutes 2 seconds 2 minutes ]; - - let a = [0u8,2,3]; + let a = [0u8, 2, 3]; let p1 = &a[0]; let p2 = &a[2]; assert_eq!(x::distance(p1, p2), 2); assert_eq!(x::distance(p2, p1), 2); assert_eq!(x::distance(p1, p1), 0); + + + let a = b"Hello World\0".as_ptr(); + assert_eq!(Some(11), x::iterate(a).position(|&a| a == 0)); + + let b = b"H\0e\0l\0l\0o\0 \0W\0o\0r\0l\0d\0\0\0".as_ptr() as *const u16; + let bytes: Vec = x::iterate(b) + .take_while(|&&c| c != 0) + .cloned().collect(); + assert_eq!("Hello World", String::from_utf16_lossy(bytes.as_slice())); + + + let hello_world: String = char::decode_utf16( + x::iterate(b).cloned().take_while(|&c| c != 0)) + .filter_map(|_r| _r.ok()).collect(); + assert_eq!("Hello World", hello_world); } \ No newline at end of file