]> git.proxmox.com Git - rustc.git/blobdiff - compiler/rustc_serialize/src/opaque.rs
New upstream version 1.53.0+dfsg1
[rustc.git] / compiler / rustc_serialize / src / opaque.rs
index 3e37fc87ce6f9a92e30a81c3852b7474f3bff182..6e36184aff051776552c22f1bfb8b4272261c271 100644 (file)
@@ -1,6 +1,7 @@
 use crate::leb128::{self, max_leb128_len};
-use crate::serialize;
+use crate::serialize::{self, Encoder as _};
 use std::borrow::Cow;
+use std::convert::TryInto;
 use std::fs::File;
 use std::io::{self, Write};
 use std::mem::MaybeUninit;
@@ -30,11 +31,6 @@ impl Encoder {
     pub fn position(&self) -> usize {
         self.data.len()
     }
-
-    #[inline]
-    pub fn emit_raw_bytes(&mut self, s: &[u8]) {
-        self.data.extend_from_slice(s);
-    }
 }
 
 macro_rules! write_leb128 {
@@ -154,7 +150,12 @@ impl serialize::Encoder for Encoder {
     #[inline]
     fn emit_str(&mut self, v: &str) -> EncodeResult {
         self.emit_usize(v.len())?;
-        self.emit_raw_bytes(v.as_bytes());
+        self.emit_raw_bytes(v.as_bytes())
+    }
+
+    #[inline]
+    fn emit_raw_bytes(&mut self, s: &[u8]) -> EncodeResult {
+        self.data.extend_from_slice(s);
         Ok(())
     }
 }
@@ -208,11 +209,6 @@ impl FileEncoder {
         self.flushed + self.buffered
     }
 
-    #[inline]
-    pub fn emit_raw_bytes(&mut self, s: &[u8]) -> FileEncodeResult {
-        self.write_all(s)
-    }
-
     pub fn flush(&mut self) -> FileEncodeResult {
         // This is basically a copy of `BufWriter::flush`. If `BufWriter` ever
         // offers a raw buffer access API, we can use it, and remove this.
@@ -508,6 +504,11 @@ impl serialize::Encoder for FileEncoder {
         self.emit_usize(v.len())?;
         self.emit_raw_bytes(v.as_bytes())
     }
+
+    #[inline]
+    fn emit_raw_bytes(&mut self, s: &[u8]) -> FileEncodeResult {
+        self.write_all(s)
+    }
 }
 
 // -----------------------------------------------------------------------------
@@ -541,23 +542,10 @@ impl<'a> Decoder<'a> {
     }
 
     #[inline]
-    pub fn read_raw_bytes(&mut self, s: &mut [MaybeUninit<u8>]) -> Result<(), String> {
+    pub fn read_raw_bytes(&mut self, bytes: usize) -> &'a [u8] {
         let start = self.position;
-        let end = start + s.len();
-        assert!(end <= self.data.len());
-
-        // SAFETY: Both `src` and `dst` point to at least `s.len()` elements:
-        // `src` points to at least `s.len()` elements by above assert, and
-        // `dst` points to `s.len()` elements by derivation from `s`.
-        unsafe {
-            let src = self.data.as_ptr().add(start);
-            let dst = s.as_mut_ptr() as *mut u8;
-            ptr::copy_nonoverlapping(src, dst, s.len());
-        }
-
-        self.position = end;
-
-        Ok(())
+        self.position += bytes;
+        &self.data[start..self.position]
     }
 }
 
@@ -677,6 +665,14 @@ impl<'a> serialize::Decoder for Decoder<'a> {
     fn error(&mut self, err: &str) -> Self::Error {
         err.to_string()
     }
+
+    #[inline]
+    fn read_raw_bytes_into(&mut self, s: &mut [u8]) -> Result<(), String> {
+        let start = self.position;
+        self.position += s.len();
+        s.copy_from_slice(&self.data[start..self.position]);
+        Ok(())
+    }
 }
 
 // Specializations for contiguous byte sequences follow. The default implementations for slices
@@ -689,8 +685,7 @@ impl<'a> serialize::Decoder for Decoder<'a> {
 impl serialize::Encodable<Encoder> for [u8] {
     fn encode(&self, e: &mut Encoder) -> EncodeResult {
         serialize::Encoder::emit_usize(e, self.len())?;
-        e.emit_raw_bytes(self);
-        Ok(())
+        e.emit_raw_bytes(self)
     }
 }
 
@@ -706,15 +701,48 @@ impl serialize::Encodable<FileEncoder> for [u8] {
 impl<'a> serialize::Decodable<Decoder<'a>> for Vec<u8> {
     fn decode(d: &mut Decoder<'a>) -> Result<Self, String> {
         let len = serialize::Decoder::read_usize(d)?;
+        Ok(d.read_raw_bytes(len).to_owned())
+    }
+}
 
-        let mut v = Vec::with_capacity(len);
-        let buf = &mut v.spare_capacity_mut()[..len];
-        d.read_raw_bytes(buf)?;
+// An integer that will always encode to 8 bytes.
+pub struct IntEncodedWithFixedSize(pub u64);
 
-        unsafe {
-            v.set_len(len);
-        }
+impl IntEncodedWithFixedSize {
+    pub const ENCODED_SIZE: usize = 8;
+}
+
+impl serialize::Encodable<Encoder> for IntEncodedWithFixedSize {
+    #[inline]
+    fn encode(&self, e: &mut Encoder) -> EncodeResult {
+        let _start_pos = e.position();
+        e.emit_raw_bytes(&self.0.to_le_bytes())?;
+        let _end_pos = e.position();
+        debug_assert_eq!((_end_pos - _start_pos), IntEncodedWithFixedSize::ENCODED_SIZE);
+        Ok(())
+    }
+}
+
+impl serialize::Encodable<FileEncoder> for IntEncodedWithFixedSize {
+    #[inline]
+    fn encode(&self, e: &mut FileEncoder) -> FileEncodeResult {
+        let _start_pos = e.position();
+        e.emit_raw_bytes(&self.0.to_le_bytes())?;
+        let _end_pos = e.position();
+        debug_assert_eq!((_end_pos - _start_pos), IntEncodedWithFixedSize::ENCODED_SIZE);
+        Ok(())
+    }
+}
+
+impl<'a> serialize::Decodable<Decoder<'a>> for IntEncodedWithFixedSize {
+    #[inline]
+    fn decode(decoder: &mut Decoder<'a>) -> Result<IntEncodedWithFixedSize, String> {
+        let _start_pos = decoder.position();
+        let bytes = decoder.read_raw_bytes(IntEncodedWithFixedSize::ENCODED_SIZE);
+        let _end_pos = decoder.position();
+        debug_assert_eq!((_end_pos - _start_pos), IntEncodedWithFixedSize::ENCODED_SIZE);
 
-        Ok(v)
+        let value = u64::from_le_bytes(bytes.try_into().unwrap());
+        Ok(IntEncodedWithFixedSize(value))
     }
 }