FIX: Support uninitalized data in encode_utf8, and update try_push

We were using &mut [u8] in encode_utf8, but this is not right according
to the developing unsafe coding guidelines. We need to use raw pointers
to write to possibly uninit memory.

We use a raw pointer form for encode_utf8. It was first attempted to
encapsulate the trusted-to-be-valid raw pointer in a simple { *mut u8,
usize } struct, but the current way of passing ptr and len separately
was the only way to not regress performance.

This impl maintains the same performance in arraystring benches.

Add exhaustive-style tests for encode_utf8
This commit is contained in:
bluss
2019-10-09 10:50:38 +02:00
parent f665142854
commit 090a5c50cb
2 changed files with 62 additions and 21 deletions
+3 -6
View File
@@ -171,7 +171,9 @@ impl<A> ArrayString<A>
pub fn try_push(&mut self, c: char) -> Result<(), CapacityError<char>> {
let len = self.len();
unsafe {
match encode_utf8(c, &mut self.raw_mut_bytes()[len..]) {
let ptr = self.xs.ptr_mut().add(len);
let remaining_cap = self.capacity() - len;
match encode_utf8(c, ptr, remaining_cap) {
Ok(n) => {
self.set_len(len + n);
Ok(())
@@ -346,11 +348,6 @@ impl<A> ArrayString<A>
pub fn as_str(&self) -> &str {
self
}
/// Return a mutable slice of the whole strings buffer
unsafe fn raw_mut_bytes(&mut self) -> &mut [u8] {
slice::from_raw_parts_mut(self.xs.ptr_mut(), self.capacity())
}
}
impl<A> Deref for ArrayString<A>