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 "rustc-serialize" as rustc_serialize;
use bincode::SizeLimit;
#[derive(RustcEncodable, RustcDecodable, PartialEq)]
struct Entity {
x: f32,
@ -38,10 +40,10 @@ fn main() {
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.
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);
}

View File

@ -3,6 +3,8 @@
extern crate bincode;
extern crate "rustc-serialize" as rustc_serialize;
use bincode::SizeLimit;
#[derive(RustcEncodable, RustcDecodable, PartialEq)]
struct Entity {
x: f32,
@ -19,10 +21,10 @@ fn main() {
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.
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);
}

View File

@ -4,6 +4,8 @@ extern crate serialize;
use std::collections::HashMap;
use std::io::{Truncate, ReadWrite, File, BufferedReader};
use bincode::SizeLimit;
fn main() {
let mut word_counts = HashMap::new();
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 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();
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);
}

View File

@ -19,32 +19,42 @@ pub use reader::DecoderReader;
mod writer;
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();
match encode_into(t, &mut w) {
match encode_into(t, &mut w, size_limit) {
Ok(()) => Ok(w.into_inner()),
Err(e) => Err(e)
}
}
pub fn decode<'a, T: Decodable<DecoderReader<'a, MemReader>, IoError>>(b: Vec<u8>) -> IoResult<T> {
decode_from(&mut MemReader::new(b))
pub fn decode<'a, T>(b: Vec<u8>, size_limit: SizeLimit) -> IoResult<T>
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
// the current json encoder in the stdlib
// 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 {
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
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 {
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 rustc_serialize::Decoder;
use super::SizeLimit;
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> {
pub fn new(r: &'a mut R) -> DecoderReader<'a, R> {
pub fn new(r: &'a mut R, size_limit: SizeLimit) -> DecoderReader<'a, R> {
DecoderReader {
reader: r
reader: r,
size_limit: size_limit
}
}
}

View File

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

View File

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