Skip to content

Commit

Permalink
Added 7bit encoded integer, String size changed to use 7bit
Browse files Browse the repository at this point in the history
Applied clippy suggestions
  • Loading branch information
Rishat Zakirov committed Jun 9, 2024
1 parent 2b334a9 commit 2cbb1d2
Show file tree
Hide file tree
Showing 3 changed files with 227 additions and 19 deletions.
148 changes: 133 additions & 15 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -105,12 +105,28 @@ impl<'a> BinaryReader<'a> {
let chars = if cfg!(feature = "wasm32") {
let str_len = self.read_u32()?;
let mut chars: Vec<u8> = vec![0; str_len as usize];
self.stream.read(&mut chars)?;
self.stream.read_exact(&mut chars)?;
chars
} else {
let str_len = self.read_usize()?;
let mut chars: Vec<u8> = vec![0; str_len];
self.stream.read(&mut chars)?;
self.stream.read_exact(&mut chars)?;
chars
};
Ok(String::from_utf8(chars)?)
}

/// Read a 7bit encoded length-prefixed `String` from the stream.
pub fn read_7bit_encoded_len_string(&mut self) -> Result<String> {
let chars = if cfg!(feature = "wasm32") {
let str_len = self.read_7bit_encoded_u32()?;
let mut chars: Vec<u8> = vec![0; str_len as usize];
self.stream.read_exact(&mut chars)?;
chars
} else {
let str_len = self.read_7bit_encoded_usize()?;
let mut chars: Vec<u8> = vec![0; str_len];
self.stream.read_exact(&mut chars)?;
chars
};
Ok(String::from_utf8(chars)?)
Expand Down Expand Up @@ -139,14 +155,14 @@ impl<'a> BinaryReader<'a> {
/// Read a `f32` from the stream.
pub fn read_f32(&mut self) -> Result<f32> {
let mut buffer: [u8; 4] = [0; 4];
self.stream.read(&mut buffer)?;
self.stream.read_exact(&mut buffer)?;
decode!(self.endian, buffer, f32);
}

/// Read a `f64` from the stream.
pub fn read_f64(&mut self) -> Result<f64> {
let mut buffer: [u8; 8] = [0; 8];
self.stream.read(&mut buffer)?;
self.stream.read_exact(&mut buffer)?;
decode!(self.endian, buffer, f64);
}

Expand All @@ -162,7 +178,7 @@ impl<'a> BinaryReader<'a> {
#[cfg(not(target_arch = "wasm32"))]
pub fn read_isize(&mut self) -> Result<isize> {
let mut buffer: [u8; 8] = [0; 8];
self.stream.read(&mut buffer)?;
self.stream.read_exact(&mut buffer)?;
decode!(self.endian, buffer, isize);
}

Expand All @@ -178,70 +194,124 @@ impl<'a> BinaryReader<'a> {
#[cfg(not(target_arch = "wasm32"))]
pub fn read_usize(&mut self) -> Result<usize> {
let mut buffer: [u8; 8] = [0; 8];
self.stream.read(&mut buffer)?;
self.stream.read_exact(&mut buffer)?;
decode!(self.endian, buffer, usize);
}

/// Read a `u64` from the stream.
pub fn read_u64(&mut self) -> Result<u64> {
let mut buffer: [u8; 8] = [0; 8];
self.stream.read(&mut buffer)?;
self.stream.read_exact(&mut buffer)?;
decode!(self.endian, buffer, u64);
}

/// Read an `i64` from the stream.
pub fn read_i64(&mut self) -> Result<i64> {
let mut buffer: [u8; 8] = [0; 8];
self.stream.read(&mut buffer)?;
self.stream.read_exact(&mut buffer)?;
decode!(self.endian, buffer, i64);
}

/// Read a `u32` from the stream.
pub fn read_u32(&mut self) -> Result<u32> {
let mut buffer: [u8; 4] = [0; 4];
self.stream.read(&mut buffer)?;
self.stream.read_exact(&mut buffer)?;
decode!(self.endian, buffer, u32);
}

/// Read an `i32` from the stream.
pub fn read_i32(&mut self) -> Result<i32> {
let mut buffer: [u8; 4] = [0; 4];
self.stream.read(&mut buffer)?;
self.stream.read_exact(&mut buffer)?;
decode!(self.endian, buffer, i32);
}

/// Read a `u16` from the stream.
pub fn read_u16(&mut self) -> Result<u16> {
let mut buffer: [u8; 2] = [0; 2];
self.stream.read(&mut buffer)?;
self.stream.read_exact(&mut buffer)?;
decode!(self.endian, buffer, u16);
}

/// Read an `i16` from the stream.
pub fn read_i16(&mut self) -> Result<i16> {
let mut buffer: [u8; 2] = [0; 2];
self.stream.read(&mut buffer)?;
self.stream.read_exact(&mut buffer)?;
decode!(self.endian, buffer, i16);
}

/// Read a `u8` from the stream.
pub fn read_u8(&mut self) -> Result<u8> {
let mut buffer: [u8; 1] = [0; 1];
self.stream.read(&mut buffer)?;
self.stream.read_exact(&mut buffer)?;
decode!(self.endian, buffer, u8);
}

/// Read an `i8` from the stream.
pub fn read_i8(&mut self) -> Result<i8> {
let mut buffer: [u8; 1] = [0; 1];
self.stream.read(&mut buffer)?;
self.stream.read_exact(&mut buffer)?;
decode!(self.endian, buffer, i8);
}

/// Read 7bit encoded `i32` from the stream
pub fn read_7bit_encoded_i32(&mut self) -> Result<i32> {
let mut result: i32 = 0;
let mut shift: u32 = 0;

loop {
let byte = self.read_u8()?;

result |= (byte as i32 & 0x7F) << shift;
shift += 7;

if byte & 0x80 == 0 {
break;
}
}
Ok(result)
}

/// Read 7bit encoded `usize` from the stream
pub fn read_7bit_encoded_usize(&mut self) -> Result<usize> {
let mut result: usize = 0;
let mut shift: usize = 0;

loop {
let byte = self.read_u8()?;

result |= (byte as usize & 0x7F) << shift;
shift += 7;

if byte & 0x80 == 0 {
break;
}
}
Ok(result)
}

/// Read 7bit encoded `u32` from the stream
pub fn read_7bit_encoded_u32(&mut self) -> Result<u32> {
let mut result: u32 = 0;
let mut shift: usize = 0;

loop {
let byte = self.read_u8()?;

result |= (byte as u32 & 0x7F) << shift;
shift += 7;

if byte & 0x80 == 0 {
break;
}
}
Ok(result)
}

/// Read bytes from the stream into a buffer.
pub fn read_bytes(&mut self, length: usize) -> Result<Vec<u8>> {
let mut buffer: Vec<u8> = vec![0; length];
self.stream.read(&mut buffer)?;
self.stream.read_exact(&mut buffer)?;
Ok(buffer)
}
}
Expand Down Expand Up @@ -287,6 +357,21 @@ impl<'a> BinaryWriter<'a> {
Ok(self.stream.write(&bytes.to_vec())?)
}

/// Write a 7bit encoded length-prefixed `String` to the stream.
///
/// The length of the `String` is written as a 7bit encoded `usize`
/// unless the `wasm32` feature is enabled
/// in which case the length is a 7bit encoded `u32`.
pub fn write_7bit_encoded_len_string<S: AsRef<str>>(&mut self, value: S) -> Result<usize> {
let bytes = value.as_ref().as_bytes();
if cfg!(feature = "wasm32") {
self.write_7bit_encoded_u32(bytes.len() as u32)?;
} else {
self.write_7bit_encoded_usize(bytes.len())?;
}
Ok(self.stream.write(&bytes.to_vec())?)
}

/// Write a character to the stream.
pub fn write_char<V: Borrow<char>>(&mut self, v: V) -> Result<usize> {
self.write_u32(*v.borrow() as u32)
Expand Down Expand Up @@ -370,6 +455,39 @@ impl<'a> BinaryWriter<'a> {
Ok(self.write_bytes(buff)?)
}

/// Write 7bit encoded i32 to the stream
pub fn write_7bit_encoded_i32(&mut self, value: i32) -> Result<usize> {
self.write_7bit_encoded_u32(value as u32)
}

/// Write 7bit encoded u32 to the stream
pub fn write_7bit_encoded_u32(&mut self, value: u32) -> Result<usize> {
let mut v = value; // support negative numbers
let mut length: usize = 0;
while v >= 0x80 {
length += 1;
self.write_u8((v | 0x80) as u8)?;
v >>= 7;
}
self.write_u8(v as u8)?;

Ok(length + 1)
}

/// Write 7bit encoded usize to the stream
pub fn write_7bit_encoded_usize(&mut self, value: usize) -> Result<usize> {
let mut v = value; // support negative numbers
let mut length: usize = 0;
while v >= 0x80 {
length += 1;
self.write_u8((v | 0x80) as u8)?;
v >>= 7;
}
self.write_u8(v as u8)?;

Ok(length + 1)
}

/// Swap endianness to allow for reversing the writing mid stream
pub fn swap_endianness(&mut self) {
if self.endian == Endian::Big {
Expand Down
3 changes: 2 additions & 1 deletion src/stream/file.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,8 @@ impl Read for FileStream {
BinaryError::ReadPastEof,
));
}
Ok(self.file.read(buffer)?)

self.file.read(buffer)
}
}

Expand Down
95 changes: 92 additions & 3 deletions tests/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -113,9 +113,10 @@ fn slice_test() -> Result<()> {
let mut writer = BinaryWriter::new(&mut stream, Endian::Big);
writer.write_u32(42)?;
writer.write_string("foo")?;
writer.write_7bit_encoded_len_string("bar")?;
writer.write_char('b')?;

assert_eq!(19, writer.len()?);
assert_eq!(23, writer.len()?);

let buffer: Vec<u8> = stream.into();

Expand All @@ -131,10 +132,13 @@ fn slice_test() -> Result<()> {
let value = reader.read_string()?;
assert_eq!("foo", &value);

let value = reader.read_7bit_encoded_len_string()?;
assert_eq!("bar", &value);

let value = reader.read_char()?;
assert_eq!('b', value);

assert_eq!(19, reader.len()?);
assert_eq!(23, reader.len()?);

Ok(())
}
Expand Down Expand Up @@ -402,6 +406,75 @@ fn read_write_test_u8() -> Result<()> {
Ok(())
}

#[test]
fn read_write_test_7bit_encoded_i32() -> Result<()> {
let values: [(i32, usize); 6] = [(-2147483647, 5), (-100, 5), (50, 1), (270, 2), (70000, 3), (2147483647, 5)];

for (temp, size_expected) in values {
let mut stream = create_writer_stream("7bit_encoded_i32");
let mut writer = BinaryWriter::new(&mut stream, Default::default());

let size = writer.write_7bit_encoded_i32(temp)?;
assert_eq!(size_expected, size);

let mut stream = create_reader_stream("7bit_encoded_i32");
let mut reader = BinaryReader::new(&mut stream, Default::default());

let read_temp = reader.read_7bit_encoded_i32()?;

assert_eq!(temp, read_temp);

cleanup("7bit_encoded_i32");
}
Ok(())
}

#[test]
fn read_write_test_7bit_encoded_u32() -> Result<()> {
let values: [(u32, usize); 4] = [(50, 1), (270, 2), (70000, 3), (2147483647, 5)];

for (temp, size_expected) in values {
let mut stream = create_writer_stream("7bit_encoded_u32");
let mut writer = BinaryWriter::new(&mut stream, Default::default());

let size = writer.write_7bit_encoded_u32(temp)?;
assert_eq!(size_expected, size);

let mut stream = create_reader_stream("7bit_encoded_u32");
let mut reader = BinaryReader::new(&mut stream, Default::default());

let read_temp = reader.read_7bit_encoded_u32()?;

assert_eq!(temp, read_temp);

cleanup("7bit_encoded_u32");
}
Ok(())
}

#[test]
fn read_write_test_7bit_encoded_usize() -> Result<()> {
let values: [(usize, usize); 4] = [(50, 1), (270, 2), (70000, 3), (2147483647, 5)];

for (temp, size_expected) in values {
let mut stream = create_writer_stream("7bit_encoded_usize");
let mut writer = BinaryWriter::new(&mut stream, Default::default());

let size = writer.write_7bit_encoded_usize(temp)?;
assert_eq!(size_expected, size);

let mut stream = create_reader_stream("7bit_encoded_usize");
let mut reader = BinaryReader::new(&mut stream, Default::default());

let read_temp = reader.read_7bit_encoded_usize()?;

assert_eq!(temp, read_temp);

cleanup("7bit_encoded_usize");
}
Ok(())
}

#[test]
fn read_write_bytes() -> Result<()> {
let count = 20;
Expand Down Expand Up @@ -456,6 +529,22 @@ fn read_write_string() -> Result<()> {
Ok(())
}

#[test]
fn read_write_7bit_encoded_string() -> Result<()> {
let temp = "Hello World";
let mut stream = create_writer_stream("read_7bit_encoded_len_string");
let mut writer = BinaryWriter::new(&mut stream, Default::default());
writer.write_7bit_encoded_len_string(temp.to_string())?;

let mut stream = create_reader_stream("read_7bit_encoded_len_string");
let mut reader = BinaryReader::new(&mut stream, Default::default());
let string = reader.read_7bit_encoded_len_string()?;
assert_eq!(temp, string);

cleanup("read_7bit_encoded_len_string");
Ok(())
}

#[test]
fn read_write_test_bool() -> Result<()> {
let positive = true;
Expand Down Expand Up @@ -538,7 +627,7 @@ fn write_bytes_with_value() -> Result<()> {
let mut stream = MemoryStream::new();
let mut writer = BinaryWriter::new(&mut stream, Default::default());
writer.write_bytes_with_value(3, 1)?;

assert_eq!(3, writer.len()?);
Ok(())
}
Expand Down

0 comments on commit 2cbb1d2

Please sign in to comment.