diff --git a/src/lib.rs b/src/lib.rs index 7d1e253..3f46a7f 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -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 { + 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 { + 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 { let mut buffer: [u8; 8] = [0; 8]; @@ -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 { - 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 { + 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 { @@ -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 { - let mut result: usize = 0; + /// Read 7bit encoded `i64` from the stream + pub fn read_7bit_encoded_i64(&mut self) -> Result { + 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 { + 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 { + 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 { + 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 { + 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 { @@ -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>(&mut self, value: V) -> Result { + encode!(self.endian, value.borrow(), self.stream); + } + /// Write an `i64` to the stream. pub fn write_i64>(&mut self, value: V) -> Result { encode!(self.endian, value.borrow(), self.stream); } + /// Write a `i128` to the stream. + pub fn write_i128>(&mut self, value: V) -> Result { + encode!(self.endian, value.borrow(), self.stream); + } + /// Write a `u32` to the stream. pub fn write_u32>(&mut self, value: V) -> Result { encode!(self.endian, value.borrow(), self.stream); @@ -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 { + 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 { + 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 { + 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 { + 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 { let mut v = value; // support negative numbers diff --git a/tests/lib.rs b/tests/lib.rs index 9f9be91..8ffcd90 100644 --- a/tests/lib.rs +++ b/tests/lib.rs @@ -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)?; @@ -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()?); @@ -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; @@ -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)];