use crate::{
AStr, ConvertError, ConvertResult, WStr,
raw::{PSTR, PWSTR, USHORT},
};
use core::ops;
#[allow(non_snake_case, non_camel_case_types)]
#[repr(C)]
#[derive(Debug, Clone)]
pub struct UNICODE_STRING {
pub Length: USHORT,
pub MaximumLength: USHORT,
pub Buffer: PWSTR,
}
#[allow(non_snake_case, non_camel_case_types)]
#[repr(C)]
#[derive(Debug, Clone)]
pub struct ANSI_STRING {
pub Length: USHORT,
pub MaximumLength: USHORT,
pub Buffer: PSTR,
}
#[derive(Debug, Clone)]
pub struct UnicodeString<'a> {
us: UNICODE_STRING,
s: &'a WStr,
}
impl<'a> UnicodeString<'a> {
pub fn new(s: &'a WStr) -> ConvertResult<Self> {
if s.as_u8_bytes_with_nul().len() > u16::MAX as usize {
return Err(ConvertError::TryFromIntError);
}
let us = UNICODE_STRING {
Length: s.as_u8_bytes().len() as u16,
MaximumLength: s.as_u8_bytes_with_nul().len() as u16,
Buffer: s.as_ptr() as *mut u16,
};
Ok(Self { us, s })
}
pub fn as_raw(&self) -> &UNICODE_STRING { &self.us }
pub unsafe fn as_raw_mut(&mut self) -> &mut UNICODE_STRING { &mut self.us }
pub fn as_ptr(&self) -> *const UNICODE_STRING { &self.us }
pub fn as_wstr(&self) -> &'a WStr { self.s }
}
impl<'a> ops::Deref for UnicodeString<'a> {
type Target = WStr;
fn deref(&self) -> &Self::Target { self.s }
}
impl PartialEq for UnicodeString<'_> {
fn eq(&self, other: &Self) -> bool { self.s.eq(other.s) }
}
impl Eq for UnicodeString<'_> {}
pub type ACPAnsiString<'a> = AnsiString<'a, 0>;
#[derive(Debug, Clone)]
pub struct AnsiString<'a, const CP: u32> {
us: ANSI_STRING,
s: &'a AStr<CP>,
}
impl<'a, const CP: u32> AnsiString<'a, CP> {
pub fn new(s: &'a AStr<CP>) -> ConvertResult<Self> {
if s.as_bytes_with_nul().len() > u16::MAX as usize {
return Err(ConvertError::TryFromIntError);
}
let us = ANSI_STRING {
Length: s.as_bytes().len() as u16,
MaximumLength: s.as_bytes_with_nul().len() as u16,
Buffer: s.as_ptr() as *mut i8,
};
Ok(Self { us, s })
}
pub fn as_raw(&self) -> &ANSI_STRING { &self.us }
pub unsafe fn as_raw_mut(&mut self) -> &mut ANSI_STRING { &mut self.us }
pub fn as_ptr(&self) -> *const ANSI_STRING { &self.us as _ }
pub fn as_astr(&self) -> &'a AStr<CP> { self.s }
}
impl<'a, const CP: u32> ops::Deref for AnsiString<'a, CP> {
type Target = AStr<CP>;
fn deref(&self) -> &Self::Target { self.s }
}
impl<'a, const CP: u32> PartialEq for AnsiString<'a, CP> {
fn eq(&self, other: &Self) -> bool { self.s.eq(other.s) }
}
impl<'a, const CP: u32> Eq for AnsiString<'a, CP> {}