Allow unsafe string manipulation

This commit is contained in:
xavo95 2025-04-20 20:14:56 +07:00
parent 07330a27e1
commit efe6f6173b
Signed by: xavo95
GPG key ID: CBF8ADED6DEBB783
2 changed files with 24 additions and 2 deletions

View file

@ -12,6 +12,7 @@ static FSTRING_PRINTF: OnceLock<usize> = OnceLock::new();
pub trait Printf<T: ?Sized> {
/// Since rust does not support varargs in functions, it is recommended to call format!
fn printf<A: AsRef<T>>(handle: usize, fmt: A);
fn printf_unsafe<A: AsRef<T>>(&mut self, fmt: A);
}
pub struct FString(pub TArray);
@ -33,6 +34,27 @@ impl Printf<str> for FString {
);
}
}
#[inline(always)]
fn printf_unsafe<A: AsRef<str>>(&mut self, fmt: A) {
let tmp = U16CString::from_str(fmt).unwrap();
let new_len = tmp.len();
if new_len > self.0.cap as usize {
// TODO: use Result instead
panic!("New string is too long and no printf ffi binding has been provided");
}
let mut tmp_bytes = tmp.into_vec_with_nul();
tmp_bytes.resize(self.0.cap as usize, 0);
unsafe {
std::ptr::copy_nonoverlapping(
tmp_bytes.as_ptr(),
self.0.data_ptr as *mut u16,
self.0.cap as usize,
);
}
self.0.len = new_len as u32;
self.0.write();
}
}
impl<'a> Container<&'a U16CStr> for FString {
@ -70,4 +92,4 @@ impl Display for FString {
#[inline(always)]
fn fstring_printf() -> &'static usize {
FSTRING_PRINTF.get().unwrap()
}
}

View file

@ -81,7 +81,7 @@ impl TArray {
}
#[inline(always)]
fn write(&self) {
pub(crate) fn write(&self) {
let data = unsafe {
std::slice::from_raw_parts_mut(self.ptr as *mut u8, T_ARRAY_HEADER_SIZE)
};