about summary refs log tree commit diff
path: root/src/libserialize
diff options
context:
space:
mode:
authorJohn Kåre Alsaker <john.kare.alsaker@gmail.com>2018-06-04 22:14:02 +0200
committerJohn Kåre Alsaker <john.kare.alsaker@gmail.com>2018-06-27 11:43:15 +0200
commit14d3c6e8f46735ad64e8dfb907824dd3ea77dbcd (patch)
tree5f512c1961f7c154156a39f5669ec54e31c14dad /src/libserialize
parent971f7d34d4e8afa663b3972b58528a069a25b436 (diff)
downloadrust-14d3c6e8f46735ad64e8dfb907824dd3ea77dbcd.tar.gz
rust-14d3c6e8f46735ad64e8dfb907824dd3ea77dbcd.zip
Make opaque::Encoder append-only and make it infallible
Diffstat (limited to 'src/libserialize')
-rw-r--r--src/libserialize/leb128.rs38
-rw-r--r--src/libserialize/lib.rs1
-rw-r--r--src/libserialize/opaque.rs50
3 files changed, 34 insertions, 55 deletions
diff --git a/src/libserialize/leb128.rs b/src/libserialize/leb128.rs
index 1786e296082..ae7f25c7fed 100644
--- a/src/libserialize/leb128.rs
+++ b/src/libserialize/leb128.rs
@@ -9,12 +9,8 @@
 // except according to those terms.
 
 #[inline]
-pub fn write_to_vec(vec: &mut Vec<u8>, position: usize, byte: u8) {
-    if position == vec.len() {
-        vec.push(byte);
-    } else {
-        vec[position] = byte;
-    }
+pub fn write_to_vec(vec: &mut Vec<u8>, byte: u8) {
+    vec.push(byte);
 }
 
 #[cfg(target_pointer_width = "32")]
@@ -33,8 +29,7 @@ macro_rules! leb128_size {
 macro_rules! impl_write_unsigned_leb128 {
     ($fn_name:ident, $int_ty:ident) => (
         #[inline]
-        pub fn $fn_name(out: &mut Vec<u8>, start_position: usize, mut value: $int_ty) -> usize {
-            let mut position = start_position;
+        pub fn $fn_name(out: &mut Vec<u8>, mut value: $int_ty) {
             for _ in 0 .. leb128_size!($int_ty) {
                 let mut byte = (value & 0x7F) as u8;
                 value >>= 7;
@@ -42,15 +37,12 @@ macro_rules! impl_write_unsigned_leb128 {
                     byte |= 0x80;
                 }
 
-                write_to_vec(out, position, byte);
-                position += 1;
+                write_to_vec(out, byte);
 
                 if value == 0 {
                     break;
                 }
             }
-
-            position - start_position
         }
     )
 }
@@ -105,11 +97,9 @@ impl_read_unsigned_leb128!(read_usize_leb128, usize);
 /// The callback `write` is called once for each position
 /// that is to be written to with the byte to be encoded
 /// at that position.
-pub fn write_signed_leb128_to<W>(mut value: i128, mut write: W) -> usize
-    where W: FnMut(usize, u8)
+pub fn write_signed_leb128_to<W>(mut value: i128, mut write: W)
+    where W: FnMut(u8)
 {
-    let mut position = 0;
-
     loop {
         let mut byte = (value as u8) & 0x7f;
         value >>= 7;
@@ -120,18 +110,16 @@ pub fn write_signed_leb128_to<W>(mut value: i128, mut write: W) -> usize
             byte |= 0x80; // Mark this byte to show that more bytes will follow.
         }
 
-        write(position, byte);
-        position += 1;
+        write(byte);
 
         if !more {
             break;
         }
     }
-    position
 }
 
-pub fn write_signed_leb128(out: &mut Vec<u8>, start_position: usize, value: i128) -> usize {
-    write_signed_leb128_to(value, |i, v| write_to_vec(out, start_position+i, v))
+pub fn write_signed_leb128(out: &mut Vec<u8>, value: i128) {
+    write_signed_leb128_to(value, |v| write_to_vec(out, v))
 }
 
 #[inline]
@@ -167,9 +155,7 @@ macro_rules! impl_test_unsigned_leb128 {
             let mut stream = Vec::new();
 
             for x in 0..62 {
-                let pos = stream.len();
-                let bytes_written = $write_fn_name(&mut stream, pos, (3u64 << x) as $int_ty);
-                assert_eq!(stream.len(), pos + bytes_written);
+                $write_fn_name(&mut stream, (3u64 << x) as $int_ty);
             }
 
             let mut position = 0;
@@ -195,9 +181,7 @@ fn test_signed_leb128() {
     let values: Vec<_> = (-500..500).map(|i| i * 0x12345789ABCDEF).collect();
     let mut stream = Vec::new();
     for &x in &values {
-        let pos = stream.len();
-        let bytes_written = write_signed_leb128(&mut stream, pos, x);
-        assert_eq!(stream.len(), pos + bytes_written);
+        write_signed_leb128(&mut stream, x);
     }
     let mut pos = 0;
     for &x in &values {
diff --git a/src/libserialize/lib.rs b/src/libserialize/lib.rs
index 22d27b6697a..a5f4b32b329 100644
--- a/src/libserialize/lib.rs
+++ b/src/libserialize/lib.rs
@@ -23,6 +23,7 @@ Core encoding and decoding interfaces.
 #![feature(box_syntax)]
 #![feature(core_intrinsics)]
 #![feature(specialization)]
+#![feature(never_type)]
 #![cfg_attr(test, feature(test))]
 
 pub use self::serialize::{Decoder, Encoder, Decodable, Encodable};
diff --git a/src/libserialize/opaque.rs b/src/libserialize/opaque.rs
index 077efadd60a..a77d1d9b88b 100644
--- a/src/libserialize/opaque.rs
+++ b/src/libserialize/opaque.rs
@@ -10,50 +10,48 @@
 
 use leb128::{self, read_signed_leb128, write_signed_leb128};
 use std::borrow::Cow;
-use std::io::{self, Write};
 use serialize;
 
 // -----------------------------------------------------------------------------
 // Encoder
 // -----------------------------------------------------------------------------
 
-pub type EncodeResult = io::Result<()>;
+pub type EncodeResult = Result<(), !>;
 
-pub struct Encoder<'a> {
-    pub cursor: &'a mut io::Cursor<Vec<u8>>,
+pub struct Encoder {
+    pub data: Vec<u8>,
 }
 
-impl<'a> Encoder<'a> {
-    pub fn new(cursor: &'a mut io::Cursor<Vec<u8>>) -> Encoder<'a> {
-        Encoder { cursor: cursor }
+impl Encoder {
+    pub fn new(data: Vec<u8>) -> Encoder {
+        Encoder { data }
     }
 
-    pub fn emit_raw_bytes(&mut self, s: &[u8]) -> EncodeResult {
-        self.cursor.write_all(s)
+    pub fn into_inner(self) -> Vec<u8> {
+        self.data
     }
-}
 
+    pub fn emit_raw_bytes(&mut self, s: &[u8]) {
+        self.data.extend_from_slice(s);
+    }
+}
 
 macro_rules! write_uleb128 {
     ($enc:expr, $value:expr, $fun:ident) => {{
-        let pos = $enc.cursor.position() as usize;
-        let bytes_written = leb128::$fun($enc.cursor.get_mut(), pos, $value);
-        $enc.cursor.set_position((pos + bytes_written) as u64);
+        leb128::$fun(&mut $enc.data, $value);
         Ok(())
     }}
 }
 
 macro_rules! write_sleb128 {
     ($enc:expr, $value:expr) => {{
-        let pos = $enc.cursor.position() as usize;
-        let bytes_written = write_signed_leb128($enc.cursor.get_mut(), pos, $value as i128);
-        $enc.cursor.set_position((pos + bytes_written) as u64);
+        write_signed_leb128(&mut $enc.data, $value as i128);
         Ok(())
     }}
 }
 
-impl<'a> serialize::Encoder for Encoder<'a> {
-    type Error = io::Error;
+impl serialize::Encoder for Encoder {
+    type Error = !;
 
     #[inline]
     fn emit_nil(&mut self) -> EncodeResult {
@@ -87,9 +85,7 @@ impl<'a> serialize::Encoder for Encoder<'a> {
 
     #[inline]
     fn emit_u8(&mut self, v: u8) -> EncodeResult {
-        let pos = self.cursor.position() as usize;
-        leb128::write_to_vec(self.cursor.get_mut(), pos, v);
-        self.cursor.set_position((pos + 1) as u64);
+        self.data.push(v);
         Ok(())
     }
 
@@ -153,15 +149,15 @@ impl<'a> serialize::Encoder for Encoder<'a> {
     #[inline]
     fn emit_str(&mut self, v: &str) -> EncodeResult {
         self.emit_usize(v.len())?;
-        let _ = self.cursor.write_all(v.as_bytes());
+        self.emit_raw_bytes(v.as_bytes());
         Ok(())
     }
 }
 
-impl<'a> Encoder<'a> {
+impl Encoder {
     #[inline]
     pub fn position(&self) -> usize {
-        self.cursor.position() as usize
+        self.data.len()
     }
 }
 
@@ -339,7 +335,6 @@ impl<'a> serialize::Decoder for Decoder<'a> {
 #[cfg(test)]
 mod tests {
     use serialize::{Encodable, Decodable};
-    use std::io::Cursor;
     use std::fmt::Debug;
     use super::{Encoder, Decoder};
 
@@ -368,14 +363,13 @@ mod tests {
 
 
     fn check_round_trip<T: Encodable + Decodable + PartialEq + Debug>(values: Vec<T>) {
-        let mut cursor = Cursor::new(Vec::new());
+        let mut encoder = Encoder::new(Vec::new());
 
         for value in &values {
-            let mut encoder = Encoder::new(&mut cursor);
             Encodable::encode(&value, &mut encoder).unwrap();
         }
 
-        let data = cursor.into_inner();
+        let data = encoder.into_inner();
         let mut decoder = Decoder::new(&data[..], 0);
 
         for value in values {