bitflags::bitflags! {
#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)]
pub struct Protection : u8 {
const R = 0b001;
const W = 0b010;
const X = 0b100;
const RW = 0b011;
const RX = 0b101;
const RWX = 0b111;
}
}
impl Protection {
#[inline]
pub const fn read(&self) -> bool {
self.contains(Self::R)
}
#[inline]
pub const fn write(&self) -> bool {
self.contains(Self::W)
}
#[inline]
pub const fn execute(&self) -> bool {
self.contains(Self::X)
}
pub fn parse(s: &str) -> Self {
assert!(
s.len() == 3
&& s.is_ascii()
&& s.chars()
.all(|c| c == '-' || c == 'r' || c == 'w' || c == 'x')
);
let mut prot = Self::empty();
if s.as_bytes()[0] == b'r' {
prot |= Self::R;
}
if s.as_bytes()[1] == b'w' {
prot |= Self::W;
}
if s.as_bytes()[2] == b'x' {
prot |= Self::X;
}
prot
}
#[cfg(all(windows, feature = "std"))]
pub fn from_os(value: windows::Win32::System::Memory::PAGE_PROTECTION_FLAGS) -> Option<Self> {
use windows::Win32::System::Memory::{
PAGE_EXECUTE_READ, PAGE_EXECUTE_READWRITE, PAGE_NOACCESS, PAGE_READONLY, PAGE_READWRITE,
};
match value {
PAGE_NOACCESS => Some(Self::empty()),
PAGE_READONLY => Some(Self::R),
PAGE_READWRITE => Some(Self::RW),
PAGE_EXECUTE_READWRITE => Some(Self::RWX),
PAGE_EXECUTE_READ => Some(Self::RX),
_ => None,
}
}
#[cfg(all(windows, feature = "std"))]
pub fn to_os(&self) -> windows::Win32::System::Memory::PAGE_PROTECTION_FLAGS {
use windows::Win32::System::Memory::{
PAGE_EXECUTE_READ, PAGE_EXECUTE_READWRITE, PAGE_NOACCESS, PAGE_READONLY, PAGE_READWRITE,
};
match (self.read(), self.write(), self.execute()) {
(true, false, false) => PAGE_READONLY, (true, false, true) => PAGE_EXECUTE_READ, (true, true, false) => PAGE_READWRITE, (true, true, true) => PAGE_EXECUTE_READWRITE, (false, _, _) => PAGE_NOACCESS,
}
}
#[cfg(all(unix, feature = "std"))]
pub const fn to_os(&self) -> i32 {
self.bits() as i32
}
#[cfg(all(unix, feature = "std"))]
pub const fn from_os(prot: i32) -> Self {
Self::from_bits_truncate(prot as u8)
}
}