mirror of https://git.sr.ht/~stygianentity/bincode
added size-limits to all functions. Currently the size limits aren't actually enforced.
This commit is contained in:
parent
602d06d412
commit
bfbaeaacd1
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
26
src/lib.rs
26
src/lib.rs
|
|
@ -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)))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
14
src/test.rs
14
src/test.rs
|
|
@ -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]
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue