#![allow(unused_macros)]
macro_rules! impl_default {
($name:ident $(, $life:lifetime)*) => {
impl<$($life),*> Default for $name<$($life),*> {
fn default() -> Self {
unsafe { std::mem::zeroed::<Self>() }
}
}
};
}
macro_rules! impl_default_with_size {
($name:ident, $field:ident $(, $life:lifetime)*) => {
impl<$($life),*> Default for $name<$($life),*> {
fn default() -> Self {
let mut obj = unsafe { std::mem::zeroed::<Self>() };
obj.$field = std::mem::size_of::<Self>() as _;
obj
}
}
};
}
macro_rules! impl_intunderlying {
($name:ident, $ntype:ty) => {
unsafe impl Send for $name {}
impl From<$name> for $ntype {
fn from(v: $name) -> Self {
v.0
}
}
impl AsRef<$ntype> for $name {
fn as_ref(&self) -> &$ntype {
&self.0
}
}
impl crate::prelude::IntUnderlying for $name {
type Raw = $ntype;
unsafe fn as_mut(&mut self) -> &mut Self::Raw {
&mut self.0
}
}
impl $name {
#[must_use]
pub const unsafe fn from_raw(v: $ntype) -> Self {
Self(v)
}
#[must_use]
pub const fn raw(&self) -> $ntype {
self.0
}
}
};
}
macro_rules! pub_fn_bool_get_set {
($field:ident, $setter:ident) => {
#[must_use]
pub const fn $field(&self) -> bool {
self.$field != 0
}
pub fn $setter(&mut self, val: bool) {
self.$field = val as _
}
};
}
macro_rules! pub_fn_resource_id_get_set {
($field:ident, $setter:ident) => {
#[must_use]
pub fn $field(&self) -> u16 {
self.$field as _
}
pub fn $setter(&mut self, val: u16) {
self.$field = val as _;
}
};
}
macro_rules! pub_fn_string_ptr_get_set {
($life:lifetime, $field:ident, $setter:ident) => {
#[must_use]
pub fn $field(&self) -> Option<String> {
unsafe { self.$field.as_mut() }.map(|psz| {
unsafe { WString::from_wchars_nullt(psz) }.to_string()
})
}
pub fn $setter(&mut self, buf: Option<&$life mut WString>) {
self.$field = buf.map_or(
std::ptr::null_mut(),
|buf| unsafe { buf.as_mut_ptr() },
);
}
};
}
macro_rules! pub_fn_string_ptrlen_get_set {
($life:lifetime, $field:ident, $setter:ident, $length:ident) => {
#[must_use]
pub fn $field(&self) -> Option<String> {
unsafe { self.$field.as_mut() }.map(|psz| {
WString::from_wchars_count(psz, self.$length as _).to_string()
})
}
pub fn $setter(&mut self, buf: Option<&$life mut WString>) {
self.$length = buf.as_ref().map_or(0, |buf| buf.str_len() as _);
self.$field = buf.map_or(
std::ptr::null_mut(),
|buf| unsafe { buf.as_mut_ptr() },
);
}
};
}
macro_rules! pub_fn_string_arr_get_set {
($field:ident, $setter:ident) => {
#[must_use]
pub fn $field(&self) -> String {
crate::kernel::decl::WString::from_wchars_slice(&self.$field).to_string()
}
pub fn $setter(&mut self, text: &str) {
crate::kernel::decl::WString::from_str(text).copy_to_slice(&mut self.$field);
}
};
}
macro_rules! pub_fn_string_buf_get_set {
($life:lifetime, $field:ident, $setter:ident, $raw:ident, $cch:ident) => {
#[must_use]
pub const fn $raw(&self) -> (*mut u16, i32) {
(self.$field, self.$cch as _) }
#[must_use]
pub fn $field(&self) -> Option<String> {
unsafe { self.$field.as_mut() }.map(|psz| {
unsafe { WString::from_wchars_nullt(psz) }.to_string()
})
}
pub fn $setter(&mut self, buf: Option<&$life mut WString>) {
self.$cch = buf.as_ref().map_or(0, |buf| buf.buf_len() as _);
self.$field = buf.map_or(std::ptr::null_mut(), |buf| {
if buf.is_allocated() {
unsafe { buf.as_mut_ptr() }
} else {
std::ptr::null_mut()
}
});
}
};
}
macro_rules! pub_fn_ptr_get_set {
($life:lifetime, $field:ident, $setter:ident, $ty:ty) => {
#[must_use]
pub fn $field(&self) -> Option<&$life mut $ty> {
unsafe { self.$field.as_mut() }
}
pub fn $setter(&mut self, obj: Option<&$life mut $ty>) {
self.$field = obj.map_or(std::ptr::null_mut(), |obj| obj);
}
};
}
macro_rules! pub_fn_array_buf_get_set {
($life:lifetime, $field:ident, $setter:ident, $cch:ident, $ty:ty) => {
#[must_use]
pub fn $field(&self) -> Option<&$life mut [$ty]> {
unsafe {
self.$field.as_mut().map(|p| {
std::slice::from_raw_parts_mut(p, self.$cch as _)
})
}
}
pub fn $setter(&mut self, buf: Option<&$life mut [$ty]>) {
match buf {
Some(buf) => {
self.$field = buf as *mut _ as _;
self.$cch = buf.len() as _;
},
None => {
self.$field = std::ptr::null_mut();
self.$cch = 0;
},
}
}
};
}
macro_rules! pub_fn_comptr_get_set {
($field:ident, $setter:ident, $trait:ident) => {
#[must_use]
pub fn $field<T>(&self) -> Option<T>
where T: $trait,
{
if self.$field.is_null() {
None
} else {
let obj = std::mem::ManuallyDrop::new( unsafe { T::from_ptr(self.$field) },
);
let cloned = T::clone(&obj); Some(cloned)
}
}
pub fn $setter<T>(&mut self, obj: Option<&T>)
where T: $trait,
{
let _ = unsafe { T::from_ptr(self.$field) }; self.$field = match obj {
Some(obj) => {
let mut cloned = T::clone(obj);
cloned.leak() },
None => std::ptr::null_mut(),
};
}
};
}
macro_rules! impl_drop_comptr {
($field:ident, $name:ident $(, $life:lifetime)*) => {
impl<$($life),*> Drop for $name<$($life),*> {
fn drop(&mut self) {
if !self.$field.is_null() {
let _ = unsafe {
<crate::IUnknown as crate::prelude::ole_IUnknown>
::from_ptr(self.$field) };
}
}
}
};
}
macro_rules! pub_fn_mem_block {
() => {
#[must_use]
pub const fn as_ptr(&self) -> *const std::ffi::c_void {
self.pmem
}
#[must_use]
pub fn as_mut_ptr(&mut self) -> *mut std::ffi::c_void {
self.pmem
}
#[must_use]
pub const fn as_slice(&self) -> &[u8] {
unsafe { std::slice::from_raw_parts(self.pmem as _, self.sz) }
}
#[must_use]
pub fn as_mut_slice(&mut self) -> &mut [u8] {
unsafe { std::slice::from_raw_parts_mut(self.pmem as _, self.sz) }
}
#[must_use]
pub const unsafe fn as_slice_aligned<T>(&self) -> &[T] {
std::slice::from_raw_parts(
self.pmem as _,
self.sz / std::mem::size_of::<T>(),
)
}
#[must_use]
pub unsafe fn as_mut_slice_aligned<T>(&mut self) -> &mut [T] {
std::slice::from_raw_parts_mut(
self.pmem as _,
self.sz / std::mem::size_of::<T>(),
)
}
#[must_use]
pub const fn len(&self) -> usize {
self.sz
}
};
}