diff options
| author | John Kåre Alsaker <john.kare.alsaker@gmail.com> | 2018-06-04 22:14:02 +0200 |
|---|---|---|
| committer | John Kåre Alsaker <john.kare.alsaker@gmail.com> | 2018-06-27 11:43:15 +0200 |
| commit | 14d3c6e8f46735ad64e8dfb907824dd3ea77dbcd (patch) | |
| tree | 5f512c1961f7c154156a39f5669ec54e31c14dad /src/libserialize | |
| parent | 971f7d34d4e8afa663b3972b58528a069a25b436 (diff) | |
| download | rust-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.rs | 38 | ||||
| -rw-r--r-- | src/libserialize/lib.rs | 1 | ||||
| -rw-r--r-- | src/libserialize/opaque.rs | 50 |
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 { |
