Decoders return the number of bytes that they read

Closes #35
This commit is contained in:
Ty Overby 2015-05-01 09:17:18 -07:00
parent d87e7dad2d
commit 5fa0c2bd8a
5 changed files with 31 additions and 20 deletions

View File

@ -1,6 +1,6 @@
[package]
name = "bincode"
version = "0.1.3"
version = "0.2.0"
authors = ["Ty Overby <ty@pre-alpha.com>", "Francesco Mazzoli <f@mazzo.li>"]
repository = "https://github.com/TyOverby/bincode"

View File

@ -24,7 +24,7 @@ fn main() {
// 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[..]).unwrap();
assert!(world == decoded);
}

View File

@ -17,8 +17,8 @@
//! // The maximum size of the encoded message.
//! let limit = bincode::SizeLimit::Bounded(20);
//!
//! let encoded: Vec<u8> = bincode::encode(&target, limit).unwrap();
//! let decoded: Option<String> = bincode::decode(&encoded[..]).unwrap();
//! let encoded: Vec<u8> = bincode::encode(&target, limit).unwrap();
//! let (decoded, len): (Option<String>, u64) = bincode::decode(&encoded[..]).unwrap();
//! assert_eq!(target, decoded);
//! }
//! ```
@ -95,9 +95,12 @@ pub fn encode<T: Encodable>(t: &T, size_limit: SizeLimit) -> EncodingResult<Vec<
/// Decodes a slice of bytes into an object.
///
/// This method does not have a size-limit because if you already have the bytes
/// in memory, then you don't gain anything by having a limiter.
pub fn decode<T: Decodable>(b: &[u8]) -> DecodingResult<T> {
/// If successful, this function returns the decoded object along with the number
/// of bytes that were read.
///
/// This method does not have a size-limit because with all the bytes contiguous
/// in memory, then nothing is gained by having a limiter.
pub fn decode<T: Decodable>(b: &[u8]) -> DecodingResult<(T, u64)> {
let mut b = b;
decode_from(&mut b, SizeLimit::Infinite)
}
@ -125,7 +128,8 @@ pub fn encode_into<T: Encodable, W: Write>(t: &T,
t.encode(&mut writer::EncoderWriter::new(w))
}
/// Decoes an object directly from a `Buffer`ed Reader.
/// Decodes an object directly from a `Read`er. If successful, returns the
/// decoded object and the number of bytes read out of the `Read`er.
///
/// If the provided `SizeLimit` is reached, the decode will bail immediately.
/// A SizeLimit can help prevent an attacker from flooding your server with
@ -134,8 +138,11 @@ pub fn encode_into<T: Encodable, W: Write>(t: &T,
/// If this returns an `DecodingError`, assume that the buffer that you passed
/// in is in an invalid state, as the error could be returned during any point
/// in the reading.
pub fn decode_from<R: Read, T: Decodable>(r: &mut R, size_limit: SizeLimit) -> DecodingResult<T> {
Decodable::decode(&mut reader::DecoderReader::new(r, size_limit))
pub fn decode_from<R: Read, T: Decodable>(r: &mut R, size_limit: SizeLimit) -> DecodingResult<(T, u64)> {
let mut decoder_reader = reader::DecoderReader::new(r, size_limit);
let value = try!(Decodable::decode(&mut decoder_reader));
let bytes_read = decoder_reader.bytes_read();
Ok((value, bytes_read))
}

View File

@ -114,6 +114,10 @@ impl<'a, R: Read> DecoderReader<'a, R> {
read: 0
}
}
pub fn bytes_read(&self) -> u64 {
self.read
}
}
impl <'a, A> DecoderReader<'a, A> {

View File

@ -20,14 +20,14 @@ fn the_same<V>(element: V)
let rf = RefBox::new(v);
let encoded = encode(&rf, Infinite).unwrap();
let decoded: RefBox<'static, V> = decode(&encoded[..]).unwrap();
let (decoded, _): (RefBox<'static, V>, _) = decode(&encoded[..]).unwrap();
decoded.take().deref() == v
}
let size = encoded_size(&element);
let encoded = encode(&element, Infinite).unwrap();
let decoded = decode(&encoded[..]).unwrap();
let (decoded, _) = decode(&encoded[..]).unwrap();
assert!(element == decoded);
assert!(size == encoded.len() as u64);
assert!(ref_box_correct(&element))
@ -206,12 +206,12 @@ fn decoding_errors() {
fn too_big_decode() {
let encoded = vec![0,0,0,3];
let mut encoded_ref = &encoded[..];
let decoded: Result<u32, _> = decode_from(&mut encoded_ref, Bounded(3));
let decoded: Result<(u32, _), _> = decode_from(&mut encoded_ref, Bounded(3));
assert!(decoded.is_err());
let encoded = vec![0,0,0,3];
let mut encoded_ref = &encoded[..];
let decoded: Result<u32, _> = decode_from(&mut encoded_ref, Bounded(4));
let decoded: Result<(u32, _), _> = decode_from(&mut encoded_ref, Bounded(4));
assert!(decoded.is_ok());
}
@ -219,9 +219,9 @@ fn too_big_decode() {
fn too_big_char_decode() {
let encoded = vec![0x41];
let mut encoded_ref = &encoded[..];
let decoded: Result<char, _> = decode_from(&mut encoded_ref, Bounded(1));
let decoded: Result<(char, _), _> = decode_from(&mut encoded_ref, Bounded(1));
assert!(decoded.is_ok());
assert_eq!(decoded.unwrap(), 'A');
assert_eq!(decoded.unwrap().0, 'A');
}
#[test]
@ -268,9 +268,9 @@ fn test_refbox() {
// Test 1
{
let encoded = encode(&Message::M1(RefBox::new(&large_object)), Infinite).unwrap();
let decoded: Message<'static> = decode(&encoded[..]).unwrap();
let decoded: (Message<'static>, _) = decode(&encoded[..]).unwrap();
match decoded {
match decoded.0 {
Message::M1(b) => assert!(b.take().deref() == &large_object),
_ => assert!(false)
}
@ -279,9 +279,9 @@ fn test_refbox() {
// Test 2
{
let encoded = encode(&Message::M2(RefBox::new(&large_map)), Infinite).unwrap();
let decoded: Message<'static> = decode(&encoded[..]).unwrap();
let decoded: (Message<'static>, _) = decode(&encoded[..]).unwrap();
match decoded {
match decoded.0 {
Message::M2(b) => assert!(b.take().deref() == &large_map),
_ => assert!(false)
}