pubfn copy_nul_terminated_string(
&self,
address: usize,
) -> Result<CString, CopyFromProcessError> { // Try copying the string word-by-word first, this is considerably // faster than one byte at a time. iflet Ok(string) = self.copy_nul_terminated_string_word_by_word(address) { return Ok(string);
}
// Reading the string one word at a time failed, let's try again one // byte at a time. It's slow but it might work in situations where the // string alignment causes word-by-word access to straddle page // boundaries. letmut string = Vec::<u8>::new(); letmut c = 1u8;
while c != 0 { self.read(address + string.len(), std::slice::from_mut(&mut c))?;
string.push(c);
}
// SAFETY: If we reach this point we've read at least one byte and we // know that the last one we read is nul.
Ok(unsafe { CString::from_vec_with_nul_unchecked(string) })
}
loop { let read_byte_len = self.read(address + string.len(), &mut word_bytes)?; // SAFETY: at most WORD_SIZE bytes are indexed letmut read_bytes = unsafe { word_bytes.get_unchecked(..std::cmp::min(read_byte_len, WORD_SIZE)) }; let nul_terminator = read_bytes.iter().position(|&e| e == 0); iflet Some(nul_terminator) = nul_terminator { // +1 to include the nul terminator
read_bytes = &read_bytes[..nul_terminator + 1];
}
string.extend(read_bytes);
if nul_terminator.is_some() { break;
}
}
// SAFETY: If we reach this point we've read at least one byte and we // know that the last one we read is nul.
Ok(unsafe { CString::from_vec_with_nul_unchecked(string) })
}
/// # Safety /// The caller must ensure that the object will be in an initialized, valid state. #[inline] pubunsafefn copy_object<T>(&self, src: usize) -> Result<T, CopyFromProcessError> { self.copy_object_uninit(src)
.map(|object| unsafe { object.assume_init() })
}
/// # Safety /// The caller must ensure that the objects will be in an initialized, valid state. #[inline] pubunsafefn copy_array<T>(
&self,
src: usize,
num: usize,
) -> Result<Vec<T>, CopyFromProcessError> { self.copy_array_uninit(src, num)
.map(|v| unsafe { std::mem::transmute::<Vec<MaybeUninit<T>>, Vec<T>>(v) })
}
}
fn uninit_as_bytes_mut<T>(elem: &mut MaybeUninit<T>) -> &mut [u8] { // SAFETY: elem is at least size_of::<T>() bytes, and MaybeUninit<T> has no validity guarantees // (so providing a mutable slice of bytes is sound) unsafe { std::slice::from_raw_parts_mut(elem.as_mut_ptr() as *mut u8, size_of::<T>()) }
}
fn uninit_slice_as_bytes_mut<T>(slice: &mut [MaybeUninit<T>]) -> &n style='color:red'>mut [u8] { // SAFETY: the slice is at least size_of::<T>()*len() bytes, and MaybeUninit<T> has no validity // guarantees (so providing a mutable slice of bytes is sound) unsafe {
std::slice::from_raw_parts_mut(slice.as_mut_ptr() as *mut u8, size_of::<T>() * slice.len())
}
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.