Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
//!
//! let b: i32 = -111;
//! let encoded_byte_vec = b.encode_var_vec();
//! assert_eq!((b, 2), i32::decode_var(&encoded_byte_vec));
//! assert_eq!(Some((b, 2)), i32::decode_var(&encoded_byte_vec));
//! }
//! ```

Expand All @@ -29,14 +29,14 @@ pub use varint::VarInt;

#[cfg(any(feature = "tokio_async", feature = "futures_async"))]
pub use reader::FixedIntAsyncReader;
pub use reader::FixedIntReader;
#[cfg(any(feature = "tokio_async", feature = "futures_async"))]
pub use reader::VarIntAsyncReader;
pub use reader::FixedIntReader;
pub use reader::VarIntReader;

#[cfg(any(feature = "tokio_async", feature = "futures_async"))]
pub use writer::FixedIntAsyncWriter;
pub use writer::FixedIntWriter;
#[cfg(any(feature = "tokio_async", feature = "futures_async"))]
pub use writer::VarIntAsyncWriter;
pub use writer::FixedIntWriter;
pub use writer::VarIntWriter;
8 changes: 4 additions & 4 deletions src/reader.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,10 +50,10 @@ impl VarIntProcessor {
Ok(())
}
fn finished(&self) -> bool {
(self.i > 0 && (self.buf[self.i - 1] & MSB == 0))
self.i > 0 && (self.buf[self.i - 1] & MSB == 0)
}
fn decode<VI: VarInt>(&self) -> VI {
VI::decode_var(&self.buf[0..self.i]).0
fn decode<VI: VarInt>(&self) -> Option<VI> {
Some(VI::decode_var(&self.buf[0..self.i])?.0)
}
}

Expand Down Expand Up @@ -101,7 +101,7 @@ impl<R: Read> VarIntReader for R {
p.push(buf[0])?;
}

Ok(p.decode())
p.decode().ok_or_else(|| io::Error::new(io::ErrorKind::UnexpectedEof, "Reached EOF"))
}
}

Expand Down
40 changes: 26 additions & 14 deletions src/varint.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@

/// Most-significant byte, == 0x80
pub const MSB: u8 = 0b1000_0000;
const DROP_MSB: u8 = 0b0111_1111;
Expand Down Expand Up @@ -31,7 +30,8 @@ pub trait VarInt: Sized + Copy {
fn required_space(self) -> usize;
/// Decode a value from the slice. Returns the value and the number of bytes read from the
/// slice (can be used to read several consecutive values from a big slice)
fn decode_var(src: &[u8]) -> (Self, usize);
/// return None if all bytes has MSB set.
fn decode_var(src: &[u8]) -> Option<(Self, usize)>;
/// Encode a value into the slice. The slice must be at least `required_space()` bytes long.
/// The number of bytes taken by the encoded integer is returned.
fn encode_var(self, src: &mut [u8]) -> usize;
Expand Down Expand Up @@ -66,9 +66,9 @@ macro_rules! impl_varint {
required_encoded_space_unsigned(self as u64)
}

fn decode_var(src: &[u8]) -> (Self, usize) {
let (n, s) = u64::decode_var(src);
(n as Self, s)
fn decode_var(src: &[u8]) -> Option<(Self, usize)> {
let (n, s) = u64::decode_var(src)?;
Some((n as Self, s))
}

fn encode_var(self, dst: &mut [u8]) -> usize {
Expand All @@ -82,9 +82,9 @@ macro_rules! impl_varint {
required_encoded_space_signed(self as i64)
}

fn decode_var(src: &[u8]) -> (Self, usize) {
let (n, s) = i64::decode_var(src);
(n as Self, s)
fn decode_var(src: &[u8]) -> Option<(Self, usize)> {
let (n, s) = i64::decode_var(src)?;
Some((n as Self, s))
}

fn encode_var(self, dst: &mut [u8]) -> usize {
Expand Down Expand Up @@ -112,10 +112,16 @@ impl VarInt for u64 {
required_encoded_space_unsigned(self)
}

fn decode_var(src: &[u8]) -> (Self, usize) {
fn decode_var(src: &[u8]) -> Option<(Self, usize)> {
let mut result: u64 = 0;
let mut shift = 0;

if let Some(b) = src.last() {
if b & MSB != 0 {
return None;
}
}

for b in src.iter() {
let msb_dropped = b & DROP_MSB;
result |= (msb_dropped as u64) << shift;
Expand All @@ -126,7 +132,7 @@ impl VarInt for u64 {
}
}

(result, shift / 7 as usize)
Some((result, shift / 7 as usize))
}

#[inline]
Expand All @@ -142,7 +148,7 @@ impl VarInt for u64 {
}

dst[i] = n as u8;
i+1
i + 1
}
}

Expand All @@ -151,10 +157,16 @@ impl VarInt for i64 {
required_encoded_space_signed(self)
}

fn decode_var(src: &[u8]) -> (Self, usize) {
fn decode_var(src: &[u8]) -> Option<(Self, usize)> {
let mut result: u64 = 0;
let mut shift = 0;

if let Some(b) = src.last() {
if b & MSB != 0 {
return None;
}
}

for b in src.iter() {
let msb_dropped = b & DROP_MSB;
result |= (msb_dropped as u64) << shift;
Expand All @@ -165,7 +177,7 @@ impl VarInt for i64 {
}
}

(zigzag_decode(result) as Self, shift / 7 as usize)
Some((zigzag_decode(result) as Self, shift / 7 as usize))
}

#[inline]
Expand All @@ -181,6 +193,6 @@ impl VarInt for i64 {
}

dst[i] = n as u8;
i+1
i + 1
}
}
12 changes: 6 additions & 6 deletions src/varint_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,18 +28,18 @@ mod tests {
#[test]
fn test_identity_u64() {
for i in 1 as u64..100 {
assert_eq!(u64::decode_var(i.encode_var_vec().as_slice()), (i, 1));
assert_eq!(u64::decode_var(i.encode_var_vec().as_slice()).unwrap(), (i, 1));
}
for i in 16400 as u64..16500 {
assert_eq!(u64::decode_var(&i.encode_var_vec().as_slice()), (i, 3));
assert_eq!(u64::decode_var(&i.encode_var_vec().as_slice()).unwrap(), (i, 3));
}
}

#[test]
fn test_decode_max_u64() {
let max_vec_encoded = vec![0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x01];
assert_eq!(
u64::decode_var(max_vec_encoded.as_slice()).0,
u64::decode_var(max_vec_encoded.as_slice()).unwrap().0,
u64::max_value()
);
}
Expand Down Expand Up @@ -70,7 +70,7 @@ mod tests {
fn test_decode_min_i64() {
let min_vec_encoded = vec![0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x01];
assert_eq!(
i64::decode_var(min_vec_encoded.as_slice()).0,
i64::decode_var(min_vec_encoded.as_slice()).unwrap().0,
i64::min_value()
);
}
Expand All @@ -79,7 +79,7 @@ mod tests {
fn test_decode_max_i64() {
let max_vec_encoded = vec![0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x01];
assert_eq!(
i64::decode_var(max_vec_encoded.as_slice()).0,
i64::decode_var(max_vec_encoded.as_slice()).unwrap().0,
i64::max_value()
);
}
Expand Down Expand Up @@ -158,6 +158,6 @@ mod tests {
fn test_unterminated_varint_2() {
let buf = [0xff, 0xff];
let mut read = &buf[..];
assert_eq!(16383, read.read_varint::<u64>().unwrap());
assert!(read.read_varint::<u64>().is_err());
}
}