Finish docs for decoder
This commit is contained in:
parent
ac3ab5b47a
commit
2552a9c203
|
@ -18,7 +18,7 @@ impl<'b> Decoder<'b> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Encode any type that implements [`Decode`].
|
/// Decode any type that implements [`Decode`].
|
||||||
pub fn decode<T: Decode<'b>>(&mut self) -> Result<T, Error> {
|
pub fn decode<T: Decode<'b>>(&mut self) -> Result<T, Error> {
|
||||||
T::decode(self)
|
T::decode(self)
|
||||||
}
|
}
|
||||||
|
@ -35,9 +35,10 @@ impl<'b> Decoder<'b> {
|
||||||
Ok(zigzag::to_isize(self.word()?))
|
Ok(zigzag::to_isize(self.word()?))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Decode a single bit of the buffer to get a bool
|
/// Decode a single bit of the buffer to get a bool.
|
||||||
/// We mask out a single bit of the buffer based on used bits
|
/// We mask out a single bit of the buffer based on used bits.
|
||||||
/// and check if it is 0 for false or 1 for true
|
/// and check if it is 0 for false or 1 for true.
|
||||||
|
// TODO: use bit() instead of this custom implementation.
|
||||||
pub fn bool(&mut self) -> Result<bool, Error> {
|
pub fn bool(&mut self) -> Result<bool, Error> {
|
||||||
let current_byte = self.buffer[self.pos];
|
let current_byte = self.buffer[self.pos];
|
||||||
let b = 0 != (current_byte & (128 >> self.used_bits));
|
let b = 0 != (current_byte & (128 >> self.used_bits));
|
||||||
|
@ -99,16 +100,26 @@ impl<'b> Decoder<'b> {
|
||||||
String::from_utf8(Vec::<u8>::decode(self)?).map_err(Error::from)
|
String::from_utf8(Vec::<u8>::decode(self)?).map_err(Error::from)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Decodes a filler of max one byte size.
|
||||||
|
/// Decodes bits until we hit a bit that is 1.
|
||||||
|
/// Expects that the 1 is at the end of the current byte in the buffer.
|
||||||
pub fn filler(&mut self) -> Result<(), Error> {
|
pub fn filler(&mut self) -> Result<(), Error> {
|
||||||
while self.zero()? {}
|
while self.zero()? {}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Decode a word of any size.
|
||||||
|
/// This is byte alignment agnostic.
|
||||||
|
/// First we decode the next 8 bits of the buffer.
|
||||||
|
/// We take the 7 least significant bits as the 7 least significant bits of the current unsigned integer.
|
||||||
|
/// If the most significant bit of the 8 bits is 1 then we take the next 8 and repeat the process above,
|
||||||
|
/// filling in the next 7 least significant bits of the unsigned integer and so on.
|
||||||
|
/// If the most significant bit was instead 0 we stop decoding any more bits.
|
||||||
pub fn word(&mut self) -> Result<usize, Error> {
|
pub fn word(&mut self) -> Result<usize, Error> {
|
||||||
let mut leading_bit = 1;
|
let mut leading_bit = 1;
|
||||||
let mut final_word: usize = 0;
|
let mut final_word: usize = 0;
|
||||||
let mut shl: usize = 0;
|
let mut shl: usize = 0;
|
||||||
// continue looping if lead bit is 1 otherwise exit
|
// continue looping if lead bit is 1 which is 128 as a u8 otherwise exit
|
||||||
while leading_bit > 0 {
|
while leading_bit > 0 {
|
||||||
let word8 = self.bits8(8)?;
|
let word8 = self.bits8(8)?;
|
||||||
let word7 = word8 & 127;
|
let word7 = word8 & 127;
|
||||||
|
@ -119,6 +130,13 @@ impl<'b> Decoder<'b> {
|
||||||
Ok(final_word)
|
Ok(final_word)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Decode a list of items with a decoder function.
|
||||||
|
/// This is byte alignment agnostic.
|
||||||
|
/// Decode a bit from the buffer.
|
||||||
|
/// If 0 then stop.
|
||||||
|
/// Otherwise we decode an item in the list with the decoder function passed in.
|
||||||
|
/// Then decode the next bit in the buffer and repeat above.
|
||||||
|
/// Returns a list of items decoded with the decoder function.
|
||||||
pub fn decode_list_with<T: Decode<'b>>(
|
pub fn decode_list_with<T: Decode<'b>>(
|
||||||
&mut self,
|
&mut self,
|
||||||
decoder_func: for<'r> fn(&'r mut Decoder) -> Result<T, Error>,
|
decoder_func: for<'r> fn(&'r mut Decoder) -> Result<T, Error>,
|
||||||
|
@ -130,12 +148,20 @@ impl<'b> Decoder<'b> {
|
||||||
Ok(vec_array)
|
Ok(vec_array)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Decode the next bit in the buffer.
|
||||||
|
/// If the bit was 0 then return true.
|
||||||
|
/// Otherwise return false.
|
||||||
|
/// Throws EndOfBuffer error if used at the end of the array.
|
||||||
fn zero(&mut self) -> Result<bool, Error> {
|
fn zero(&mut self) -> Result<bool, Error> {
|
||||||
let current_bit = self.bit()?;
|
let current_bit = self.bit()?;
|
||||||
|
|
||||||
Ok(!current_bit)
|
Ok(!current_bit)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Decode the next bit in the buffer.
|
||||||
|
/// If the bit was 1 then return true.
|
||||||
|
/// Otherwise return false.
|
||||||
|
/// Throws EndOfBuffer error if used at the end of the array.
|
||||||
fn bit(&mut self) -> Result<bool, Error> {
|
fn bit(&mut self) -> Result<bool, Error> {
|
||||||
if self.pos >= self.buffer.len() {
|
if self.pos >= self.buffer.len() {
|
||||||
return Err(Error::EndOfBuffer);
|
return Err(Error::EndOfBuffer);
|
||||||
|
@ -148,6 +174,13 @@ impl<'b> Decoder<'b> {
|
||||||
Ok(b)
|
Ok(b)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Decode a byte array.
|
||||||
|
/// Throws a BufferNotByteAligned error if the buffer is not byte aligned
|
||||||
|
/// Decodes the next byte to get the array length up to a max of 255.
|
||||||
|
/// We decode bytes equal to the array length to form the byte array.
|
||||||
|
/// If the following byte for array length is not 0 we decode it and repeat above to continue decoding the byte array.
|
||||||
|
/// We stop once we hit a byte array length of 0.
|
||||||
|
/// If array length is 0 for first byte array length the we return a empty array.
|
||||||
fn byte_array(&mut self) -> Result<Vec<u8>, Error> {
|
fn byte_array(&mut self) -> Result<Vec<u8>, Error> {
|
||||||
if self.used_bits != 0 {
|
if self.used_bits != 0 {
|
||||||
return Err(Error::BufferNotByteAligned);
|
return Err(Error::BufferNotByteAligned);
|
||||||
|
@ -178,7 +211,14 @@ impl<'b> Decoder<'b> {
|
||||||
Ok(blk_array)
|
Ok(blk_array)
|
||||||
}
|
}
|
||||||
|
|
||||||
// can decode up to a max of 8 bits
|
/// Decode up to 8 bits.
|
||||||
|
/// This is byte alignment agnostic.
|
||||||
|
/// If num_bits is greater than the 8 we throw an IncorrectNumBits error.
|
||||||
|
/// First we decode the next num_bits of bits in the buffer.
|
||||||
|
/// If there are less unused bits in the current byte in the buffer than num_bits,
|
||||||
|
/// then we decode the remaining bits from the most significant bits in the next byte in the buffer.
|
||||||
|
/// Otherwise we decode the unused bits from the current byte.
|
||||||
|
/// Returns the decoded value up to a byte in size.
|
||||||
pub fn bits8(&mut self, num_bits: usize) -> Result<u8, Error> {
|
pub fn bits8(&mut self, num_bits: usize) -> Result<u8, Error> {
|
||||||
if num_bits > 8 {
|
if num_bits > 8 {
|
||||||
return Err(Error::IncorrectNumBits);
|
return Err(Error::IncorrectNumBits);
|
||||||
|
@ -201,6 +241,8 @@ impl<'b> Decoder<'b> {
|
||||||
Ok(x)
|
Ok(x)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Ensures the buffer has the required bytes passed in by required_bytes.
|
||||||
|
/// Throws a NotEnoughBytes error if there are less bytes remaining in the buffer than required_bytes.
|
||||||
fn ensure_bytes(&mut self, required_bytes: usize) -> Result<(), Error> {
|
fn ensure_bytes(&mut self, required_bytes: usize) -> Result<(), Error> {
|
||||||
if required_bytes as isize > self.buffer.len() as isize - self.pos as isize {
|
if required_bytes as isize > self.buffer.len() as isize - self.pos as isize {
|
||||||
Err(Error::NotEnoughBytes(required_bytes))
|
Err(Error::NotEnoughBytes(required_bytes))
|
||||||
|
@ -209,6 +251,8 @@ impl<'b> Decoder<'b> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Ensures the buffer has the required bits passed in by required_bits.
|
||||||
|
/// Throws a NotEnoughBits error if there are less bits remaining in the buffer than required_bits.
|
||||||
fn ensure_bits(&mut self, required_bits: usize) -> Result<(), Error> {
|
fn ensure_bits(&mut self, required_bits: usize) -> Result<(), Error> {
|
||||||
if required_bits as isize
|
if required_bits as isize
|
||||||
> (self.buffer.len() as isize - self.pos as isize) * 8 - self.used_bits as isize
|
> (self.buffer.len() as isize - self.pos as isize) * 8 - self.used_bits as isize
|
||||||
|
@ -219,12 +263,18 @@ impl<'b> Decoder<'b> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Increment buffer by num_bits.
|
||||||
|
/// If num_bits + used bits is greater than 8,
|
||||||
|
/// then increment position by (num_bits + used bits) / 8
|
||||||
|
/// Use the left over remainder as the new amount of used bits.
|
||||||
fn drop_bits(&mut self, num_bits: usize) {
|
fn drop_bits(&mut self, num_bits: usize) {
|
||||||
let all_used_bits = num_bits as i64 + self.used_bits;
|
let all_used_bits = num_bits as i64 + self.used_bits;
|
||||||
self.used_bits = all_used_bits % 8;
|
self.used_bits = all_used_bits % 8;
|
||||||
self.pos += all_used_bits as usize / 8;
|
self.pos += all_used_bits as usize / 8;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Increment used bits by 1.
|
||||||
|
/// If all 8 bits are used then increment buffer position by 1.
|
||||||
fn increment_buffer_by_bit(&mut self) {
|
fn increment_buffer_by_bit(&mut self) {
|
||||||
if self.used_bits == 7 {
|
if self.used_bits == 7 {
|
||||||
self.pos += 1;
|
self.pos += 1;
|
||||||
|
|
Loading…
Reference in New Issue