diff --git a/tendril/src/stream.rs b/tendril/src/stream.rs index c0e53f4f..1ce72b79 100644 --- a/tendril/src/stream.rs +++ b/tendril/src/stream.rs @@ -77,20 +77,14 @@ where { const BUFFER_SIZE: u32 = 4 * 1024; loop { - let mut tendril = Tendril::::new(); - // FIXME: this exposes uninitialized bytes to a generic R type - // this is fine for R=File which never reads these bytes, - // but user-defined types might. - // The standard library pushes zeros to `Vec` for that reason. - unsafe { - tendril.push_uninitialized(BUFFER_SIZE); - } + let mut tendril = Tendril::::new(); + tendril.extend_with_byte(BUFFER_SIZE, 0); loop { match r.read(&mut tendril) { Ok(0) => return Ok(self.finish()), Ok(n) => { tendril.pop_back(BUFFER_SIZE - n as u32); - self.process(tendril); + self.process(unsafe { tendril.reinterpret_without_validating() }); break; }, Err(ref e) if e.kind() == io::ErrorKind::Interrupted => {}, diff --git a/tendril/src/tendril.rs b/tendril/src/tendril.rs index 5e90aaec..efa18ce8 100644 --- a/tendril/src/tendril.rs +++ b/tendril/src/tendril.rs @@ -1393,13 +1393,7 @@ where if new_write_size < DEFAULT_BUF_SIZE { new_write_size *= 2; } - // FIXME: this exposes uninitialized bytes to a generic R type - // this is fine for R=File which never reads these bytes, - // but user-defined types might. - // The standard library pushes zeros to `Vec` for that reason. - unsafe { - buf.push_uninitialized(new_write_size); - } + buf.extend_with_byte(new_write_size, 0); } match self.read(&mut buf[len..]) { @@ -1444,6 +1438,24 @@ where } } +impl Tendril +where + A: Atomicity, +{ + /// Extend the tendril with `n` copies of a given byte. + /// + /// This grows the tendril and initializes the new area with `byte`. + #[inline] + pub fn extend_with_byte(&mut self, n: u32, byte: u8) { + unsafe { + let start = self.len32(); + self.push_uninitialized(n); + let ptr = self[start as usize..].as_mut_ptr(); + std::ptr::write_bytes(ptr, byte, n as usize); + } + } +} + impl Tendril where A: Atomicity,