Skip to content

Commit

Permalink
Added u/i128 encoding support
Browse files Browse the repository at this point in the history
  • Loading branch information
Rishat Zakirov committed Jun 11, 2024
1 parent 77c72da commit dbc21e6
Show file tree
Hide file tree
Showing 2 changed files with 286 additions and 9 deletions.
152 changes: 143 additions & 9 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,20 @@ impl<'a> BinaryReader<'a> {
decode!(self.endian, buffer, usize);
}

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

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

/// Read a `u64` from the stream.
pub fn read_u64(&mut self) -> Result<u64> {
let mut buffer: [u8; 8] = [0; 8];
Expand Down Expand Up @@ -254,15 +268,15 @@ impl<'a> BinaryReader<'a> {
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;
/// 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 i32 & 0x7F) << shift;
result |= (byte as usize & 0x7F) << shift;
shift += 7;

if byte & 0x80 == 0 {
Expand All @@ -272,15 +286,87 @@ impl<'a> BinaryReader<'a> {
Ok(result)
}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

/// 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: usize = 0;

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

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

if byte & 0x80 == 0 {
Expand Down Expand Up @@ -408,11 +494,21 @@ impl<'a> BinaryWriter<'a> {
encode!(self.endian, value.borrow(), self.stream);
}

/// Write a `u128` to the stream.
pub fn write_u128<V: Borrow<u128>>(&mut self, value: V) -> Result<usize> {
encode!(self.endian, value.borrow(), self.stream);
}

/// Write an `i64` to the stream.
pub fn write_i64<V: Borrow<i64>>(&mut self, value: V) -> Result<usize> {
encode!(self.endian, value.borrow(), self.stream);
}

/// Write a `i128` to the stream.
pub fn write_i128<V: Borrow<i128>>(&mut self, value: V) -> Result<usize> {
encode!(self.endian, value.borrow(), self.stream);
}

/// Write a `u32` to the stream.
pub fn write_u32<V: Borrow<u32>>(&mut self, value: V) -> Result<usize> {
encode!(self.endian, value.borrow(), self.stream);
Expand Down Expand Up @@ -474,6 +570,44 @@ impl<'a> BinaryWriter<'a> {
Ok(length + 1)
}

/// Write 7bit encoded i64 to the stream
pub fn write_7bit_encoded_i64(&mut self, value: i64) -> Result<usize> {
self.write_7bit_encoded_u64(value as u64)
}

/// Write 7bit encoded u64 to the stream
pub fn write_7bit_encoded_u64(&mut self, value: u64) -> 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 i128 to the stream
pub fn write_7bit_encoded_i128(&mut self, value: i128) -> Result<usize> {
self.write_7bit_encoded_u128(value as u128)
}

/// Write 7bit encoded u128 to the stream
pub fn write_7bit_encoded_u128(&mut self, value: u128) -> 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
Expand Down
143 changes: 143 additions & 0 deletions tests/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,11 @@ fn borrow_test() -> Result<()> {
writer.write_i64(-64)?;
writer.write_i64(&-64)?;

writer.write_u128(128)?;
writer.write_u128(&128)?;
writer.write_i128(-128)?;
writer.write_i128(&-128)?;

writer.write_usize(64)?;
writer.write_usize(&64)?;
writer.write_isize(-64)?;
Expand Down Expand Up @@ -87,6 +92,11 @@ fn borrow_test() -> Result<()> {
let value = (reader.read_i64()?, reader.read_i64()?);
assert_eq!((-64, -64), value);

let value = (reader.read_u128()?, reader.read_u128()?);
assert_eq!((128, 128), value);
let value = (reader.read_i128()?, reader.read_i128()?);
assert_eq!((-128, -128), value);

let value = (reader.read_usize()?, reader.read_usize()?);
assert_eq!((64, 64), value);
let value = (reader.read_isize()?, reader.read_isize()?);
Expand Down Expand Up @@ -253,6 +263,46 @@ fn read_write_test_usize() -> Result<()> {
Ok(())
}

#[test]
fn read_write_test_i128() -> Result<()> {
let temp: i128 = 1 << 127;
let mut stream = create_writer_stream("i128");
let mut writer = BinaryWriter::new(&mut stream, Default::default());

writer.write_i128(temp)?;

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

let read_temp = reader.read_i128()?;

assert_eq!(temp, read_temp);

cleanup("i128");

Ok(())
}

#[test]
fn read_write_test_u128() -> Result<()> {
let temp: u128 = 1 << 127;
let mut stream = create_writer_stream("u128");
let mut writer = BinaryWriter::new(&mut stream, Default::default());

writer.write_u128(temp)?;

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

let read_temp = reader.read_u128()?;

assert_eq!(temp, read_temp);

cleanup("u128");

Ok(())
}

#[test]
fn read_write_test_i64() -> Result<()> {
let temp: i64 = 50;
Expand Down Expand Up @@ -412,6 +462,99 @@ fn read_write_test_u8() -> Result<()> {
Ok(())
}

#[test]
fn read_write_test_7bit_encoded_u128() -> Result<()> {
let values: [(u128, usize); 6] = [(50, 1), (270, 2), (70000, 3), (2147483647, 5), (1 << 63, 10), (1 << 127, 19)];

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

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

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

let read_temp = reader.read_7bit_encoded_u128()?;

assert_eq!(temp, read_temp);

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


#[test]
fn read_write_test_7bit_encoded_i128() -> Result<()> {
let values: [(i128, usize); 8] = [(-2147483647, 19), (-100, 19), (50, 1), (270, 2), (70000, 3), (2147483647, 5), (1 << 63, 10), (1 << 127, 19)];
for (temp, size_expected) in values {

let mut stream = create_writer_stream("7bit_encoded_i128");
let mut writer = BinaryWriter::new(&mut stream, Default::default());

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

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

let read_temp = reader.read_7bit_encoded_i128()?;

assert_eq!(temp, read_temp);

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

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

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

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

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

let read_temp = reader.read_7bit_encoded_u64()?;

assert_eq!(temp, read_temp);

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

#[test]
fn read_write_test_7bit_encoded_i64() -> Result<()> {
let values: [(i64, usize); 7] = [(-2147483647, 10), (-100, 10), (50, 1), (270, 2), (70000, 3), (2147483647, 5), (1 << 63, 10)];

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

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

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

let read_temp = reader.read_7bit_encoded_i64()?;

assert_eq!(temp, read_temp);

cleanup("7bit_encoded_i64");
}
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)];
Expand Down

0 comments on commit dbc21e6

Please sign in to comment.