Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support u/i128 encoding #40

Merged
merged 3 commits into from
Jun 12, 2024
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
152 changes: 143 additions & 9 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,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 @@ -258,15 +272,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 @@ -276,15 +290,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 @@ -412,11 +498,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 @@ -478,6 +574,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
Loading