|
1 | 1 | use crate::leb128::{self, read_signed_leb128, write_signed_leb128};
|
2 | 2 | use crate::serialize;
|
3 | 3 | use std::borrow::Cow;
|
| 4 | +use std::mem::MaybeUninit; |
| 5 | +use std::ptr; |
4 | 6 |
|
5 | 7 | // -----------------------------------------------------------------------------
|
6 | 8 | // Encoder
|
@@ -179,11 +181,19 @@ impl<'a> Decoder<'a> {
|
179 | 181 | }
|
180 | 182 |
|
181 | 183 | #[inline]
|
182 |
| - pub fn read_raw_bytes(&mut self, s: &mut [u8]) -> Result<(), String> { |
| 184 | + pub fn read_raw_bytes(&mut self, s: &mut [MaybeUninit<u8>]) -> Result<(), String> { |
183 | 185 | let start = self.position;
|
184 | 186 | let end = start + s.len();
|
| 187 | + assert!(end <= self.data.len()); |
185 | 188 |
|
186 |
| - s.copy_from_slice(&self.data[start..end]); |
| 189 | + // SAFETY: Both `src` and `dst` point to at least `s.len()` elements: |
| 190 | + // `src` points to at least `s.len()` elements by above assert, and |
| 191 | + // `dst` points to `s.len()` elements by derivation from `s`. |
| 192 | + unsafe { |
| 193 | + let src = self.data.as_ptr().add(start); |
| 194 | + let dst = s.as_mut_ptr() as *mut u8; |
| 195 | + ptr::copy_nonoverlapping(src, dst, s.len()); |
| 196 | + } |
187 | 197 |
|
188 | 198 | self.position = end;
|
189 | 199 |
|
@@ -316,3 +326,36 @@ impl<'a> serialize::Decoder for Decoder<'a> {
|
316 | 326 | err.to_string()
|
317 | 327 | }
|
318 | 328 | }
|
| 329 | + |
| 330 | +// Specializations for contiguous byte sequences follow. The default implementations for slices |
| 331 | +// encode and decode each element individually. This isn't necessary for `u8` slices when using |
| 332 | +// opaque encoders and decoders, because each `u8` is unchanged by encoding and decoding. |
| 333 | +// Therefore, we can use more efficient implementations that process the entire sequence at once. |
| 334 | + |
| 335 | +// Specialize encoding byte slices. This specialization also applies to encoding `Vec<u8>`s, etc., |
| 336 | +// since the default implementations call `encode` on their slices internally. |
| 337 | +impl serialize::Encodable<Encoder> for [u8] { |
| 338 | + fn encode(&self, e: &mut Encoder) -> EncodeResult { |
| 339 | + serialize::Encoder::emit_usize(e, self.len())?; |
| 340 | + e.emit_raw_bytes(self); |
| 341 | + Ok(()) |
| 342 | + } |
| 343 | +} |
| 344 | + |
| 345 | +// Specialize decoding `Vec<u8>`. This specialization also applies to decoding `Box<[u8]>`s, etc., |
| 346 | +// since the default implementations call `decode` to produce a `Vec<u8>` internally. |
| 347 | +impl<'a> serialize::Decodable<Decoder<'a>> for Vec<u8> { |
| 348 | + fn decode(d: &mut Decoder<'a>) -> Result<Self, String> { |
| 349 | + let len = serialize::Decoder::read_usize(d)?; |
| 350 | + |
| 351 | + let mut v = Vec::with_capacity(len); |
| 352 | + let buf = &mut v.spare_capacity_mut()[..len]; |
| 353 | + d.read_raw_bytes(buf)?; |
| 354 | + |
| 355 | + unsafe { |
| 356 | + v.set_len(len); |
| 357 | + } |
| 358 | + |
| 359 | + Ok(v) |
| 360 | + } |
| 361 | +} |
0 commit comments