added size-limits to all functions. Currently the size limits aren't actually enforced.

This commit is contained in:
TyOverby 2015-01-05 11:19:08 -08:00
parent 602d06d412
commit bfbaeaacd1
7 changed files with 58 additions and 26 deletions

View File

@ -22,6 +22,8 @@ library.
extern crate bincode; extern crate bincode;
extern crate "rustc-serialize" as rustc_serialize; extern crate "rustc-serialize" as rustc_serialize;
use bincode::SizeLimit;
#[derive(RustcEncodable, RustcDecodable, PartialEq)] #[derive(RustcEncodable, RustcDecodable, PartialEq)]
struct Entity { struct Entity {
x: f32, x: f32,
@ -38,10 +40,10 @@ fn main() {
entities: vec![Entity {x: 0.0, y: 4.0}, Entity {x: 10.0, y: 20.5}] entities: vec![Entity {x: 0.0, y: 4.0}, Entity {x: 10.0, y: 20.5}]
}; };
let encoded: Vec<u8> = bincode::encode(&world).unwrap(); let encoded: Vec<u8> = bincode::encode(&world, SizeLimit::Infinite).unwrap();
// 8 bytes for the length of the vector, 4 bytes per float. // 8 bytes for the length of the vector, 4 bytes per float.
assert_eq!(encoded.len(), 8 + 4 * 4); assert_eq!(encoded.len(), 8 + 4 * 4);
let decoded: World = bincode::decode(encoded).unwrap(); let decoded: World = bincode::decode(encoded, SizeLimit::Infinite).unwrap();
assert!(world == decoded); assert!(world == decoded);
} }

View File

@ -3,6 +3,8 @@
extern crate bincode; extern crate bincode;
extern crate "rustc-serialize" as rustc_serialize; extern crate "rustc-serialize" as rustc_serialize;
use bincode::SizeLimit;
#[derive(RustcEncodable, RustcDecodable, PartialEq)] #[derive(RustcEncodable, RustcDecodable, PartialEq)]
struct Entity { struct Entity {
x: f32, x: f32,
@ -19,10 +21,10 @@ fn main() {
entities: vec![Entity {x: 0.0, y: 4.0}, Entity {x: 10.0, y: 20.5}] entities: vec![Entity {x: 0.0, y: 4.0}, Entity {x: 10.0, y: 20.5}]
}; };
let encoded: Vec<u8> = bincode::encode(&world).unwrap(); let encoded: Vec<u8> = bincode::encode(&world, SizeLimit::Infinite).unwrap();
// 8 bytes for the length of the vector, 4 bytes per float. // 8 bytes for the length of the vector, 4 bytes per float.
assert_eq!(encoded.len(), 8 + 4 * 4); assert_eq!(encoded.len(), 8 + 4 * 4);
let decoded: World = bincode::decode(encoded).unwrap(); let decoded: World = bincode::decode(encoded, SizeLimit::Infinite).unwrap();
assert!(world == decoded); assert!(world == decoded);
} }

View File

@ -4,6 +4,8 @@ extern crate serialize;
use std::collections::HashMap; use std::collections::HashMap;
use std::io::{Truncate, ReadWrite, File, BufferedReader}; use std::io::{Truncate, ReadWrite, File, BufferedReader};
use bincode::SizeLimit;
fn main() { fn main() {
let mut word_counts = HashMap::new(); let mut word_counts = HashMap::new();
word_counts.insert("foo".to_string(), 3u); word_counts.insert("foo".to_string(), 3u);
@ -11,11 +13,11 @@ fn main() {
let file = File::open_mode(&Path::new("store.bin"), Truncate, ReadWrite); let file = File::open_mode(&Path::new("store.bin"), Truncate, ReadWrite);
let mut file = file.unwrap(); let mut file = file.unwrap();
bincode::encode_into(&word_counts, &mut file).unwrap(); bincode::encode_into(&word_counts, &mut file, SizeLimit::Infinite).unwrap();
file.fsync().unwrap(); file.fsync().unwrap();
let out: HashMap<String, uint> = let out: HashMap<String, uint> =
bincode::decode_from(&mut BufferedReader::new(file)).unwrap(); bincode::decode_from(&mut BufferedReader::new(file), SizeLimit::Infinite).unwrap();
assert!(out == word_counts); assert!(out == word_counts);
} }

View File

@ -19,32 +19,42 @@ pub use reader::DecoderReader;
mod writer; mod writer;
mod reader; mod reader;
pub fn encode<'a, T: Encodable<EncoderWriter<'a, MemWriter>, IoError>>(t: &T) ->IoResult<Vec<u8>> { #[derive(Clone, Copy)]
pub enum SizeLimit {
Infinite,
UpperBound(u64)
}
pub fn encode<'a, T>(t: &T, size_limit: SizeLimit) -> IoResult<Vec<u8>>
where T: Encodable<EncoderWriter<'a, MemWriter>, IoError> {
let mut w = MemWriter::new(); let mut w = MemWriter::new();
match encode_into(t, &mut w) { match encode_into(t, &mut w, size_limit) {
Ok(()) => Ok(w.into_inner()), Ok(()) => Ok(w.into_inner()),
Err(e) => Err(e) Err(e) => Err(e)
} }
} }
pub fn decode<'a, T: Decodable<DecoderReader<'a, MemReader>, IoError>>(b: Vec<u8>) -> IoResult<T> { pub fn decode<'a, T>(b: Vec<u8>, size_limit: SizeLimit) -> IoResult<T>
decode_from(&mut MemReader::new(b)) where T: Decodable<DecoderReader<'a, MemReader>, IoError> {
decode_from(&mut MemReader::new(b), size_limit)
} }
// In order to be able to pass MemReaders/MemWriters by reference, I borrowed the method used in // In order to be able to pass MemReaders/MemWriters by reference, I borrowed the method used in
// the current json encoder in the stdlib // the current json encoder in the stdlib
// TODO: Make code safe https://github.com/rust-lang/rust/issues/14302 // TODO: Make code safe https://github.com/rust-lang/rust/issues/14302
pub fn encode_into<'a, W: 'a+Writer, T: Encodable<EncoderWriter<'a, W>, IoError>>(t: &T, w: &mut W) -> IoResult<()> { pub fn encode_into<'a, W, T>(t: &T, w: &mut W, size_limit: SizeLimit) -> IoResult<()>
where W: 'a + Writer, T: Encodable<EncoderWriter<'a, W>, IoError>{
unsafe { unsafe {
t.encode(std::mem::transmute(&mut writer::EncoderWriter::new(w))) t.encode(std::mem::transmute(&mut writer::EncoderWriter::new(w, size_limit)))
} }
} }
// TODO: Make code safe https://github.com/rust-lang/rust/issues/14302 // TODO: Make code safe https://github.com/rust-lang/rust/issues/14302
pub fn decode_from<'a, R: 'a+Reader+Buffer, T: Decodable<DecoderReader<'a, R>, IoError>>(r: &mut R) -> IoResult<T> { pub fn decode_from<'a, R, T>(r: &mut R, size_limit: SizeLimit) -> IoResult<T>
where R: 'a + Reader + Buffer, T: Decodable<DecoderReader<'a, R>, IoError>{
unsafe { unsafe {
Decodable::decode(std::mem::transmute(&mut reader::DecoderReader::new(r))) Decodable::decode(std::mem::transmute(&mut reader::DecoderReader::new(r, size_limit)))
} }
} }

View File

@ -1,14 +1,19 @@
use std::io::{Buffer, Reader, IoError, IoResult, OtherIoError}; use std::io::{Buffer, Reader, IoError, IoResult, OtherIoError};
use rustc_serialize::Decoder; use rustc_serialize::Decoder;
use super::SizeLimit;
pub struct DecoderReader<'a, R: 'a> { pub struct DecoderReader<'a, R: 'a> {
reader: &'a mut R reader: &'a mut R,
size_limit: SizeLimit
} }
impl<'a, R: Reader+Buffer> DecoderReader<'a, R> { impl<'a, R: Reader+Buffer> DecoderReader<'a, R> {
pub fn new(r: &'a mut R) -> DecoderReader<'a, R> { pub fn new(r: &'a mut R, size_limit: SizeLimit) -> DecoderReader<'a, R> {
DecoderReader { DecoderReader {
reader: r reader: r,
size_limit: size_limit
} }
} }
} }

View File

@ -13,16 +13,20 @@ use rustc_serialize::{
Decodable Decodable
}; };
use super::EncoderWriter; use super::{
use super::DecoderReader; EncoderWriter,
use super::encode; DecoderReader,
use super::decode; encode,
decode,
SizeLimit
};
use super::SizeLimit::Infinite;
fn the_same<'a, fn the_same<'a,
V: Encodable<EncoderWriter<'a, MemWriter>, IoError> + V: Encodable<EncoderWriter<'a, MemWriter>, IoError> +
Decodable<DecoderReader<'a, MemReader>, IoError> + Decodable<DecoderReader<'a, MemReader>, IoError> +
PartialEq + Show>(element: V) { PartialEq + Show>(element: V) {
assert!(element == decode(encode(&element).unwrap()).unwrap()); assert!(element == decode(encode(&element, Infinite).unwrap(), Infinite).unwrap());
} }
#[test] #[test]

View File

@ -1,16 +1,23 @@
use std::io::{Writer, IoError, IoResult}; use std::io::{Writer, IoError, IoResult};
use rustc_serialize::Encoder;
use std::num::Int; use std::num::Int;
use rustc_serialize::Encoder;
use super::SizeLimit;
type EwResult = IoResult<()>; type EwResult = IoResult<()>;
pub struct EncoderWriter<'a, W: 'a> { pub struct EncoderWriter<'a, W: 'a> {
writer: &'a mut W writer: &'a mut W,
size_limit: SizeLimit
} }
impl <'a, W: Writer> EncoderWriter<'a, W> { impl <'a, W: Writer> EncoderWriter<'a, W> {
pub fn new(w: &'a mut W) -> EncoderWriter<'a, W> { pub fn new(w: &'a mut W, size_limit: SizeLimit) -> EncoderWriter<'a, W> {
EncoderWriter{ writer: w } EncoderWriter {
writer: w,
size_limit: size_limit
}
} }
} }