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> { pub trait Printf<T: ?Sized> {
/// Since rust does not support varargs in functions, it is recommended to call format! /// 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<A: AsRef<T>>(handle: usize, fmt: A);
fn printf_unsafe<A: AsRef<T>>(&mut self, fmt: A);
} }
pub struct FString(pub TArray); 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 { impl<'a> Container<&'a U16CStr> for FString {

View file

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