Skip to content

Commit

Permalink
Add encode_to_slice (#32)
Browse files Browse the repository at this point in the history
* add encode_to_slice

* change signature of `encode_to_slice`, to accept T: AsRef<[u8]>
  • Loading branch information
Luro02 authored and KokaKiwi committed Dec 28, 2019
1 parent 32cad94 commit c669098
Showing 1 changed file with 73 additions and 0 deletions.
73 changes: 73 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -302,10 +302,83 @@ pub fn decode_to_slice<T: AsRef<[u8]>>(data: T, out: &mut [u8]) -> Result<(), Fr
Ok(())
}

// generates an iterator like this
// (0, 1)
// (2, 3)
// (4, 5)
// (6, 7)
// ...
fn generate_iter(len: usize) -> impl Iterator<Item = (usize, usize)> {
(0..len).step_by(2).zip((0..len).skip(1).step_by(2))
}

// the inverse of `val`.
fn byte2hex(byte: u8, table: &[u8; 16]) -> (u8, u8) {
let high = table[((byte & 0xf0) >> 4) as usize];
let low = table[(byte & 0x0f) as usize];

(high, low)
}

/// Encodes some bytes into a mutable slice of bytes.
///
/// The output buffer, has to be able to hold at least `input.len() * 2` bytes,
/// otherwise this function will return an error.
///
/// # Example
///
/// ```
/// # use hex::FromHexError;
/// # fn main() -> Result<(), FromHexError> {
/// let mut bytes = [0u8; 4 * 2];
///
/// hex::encode_to_slice(b"kiwi", &mut bytes)?;
/// assert_eq!(&bytes, b"6b697769");
/// # Ok(())
/// # }
/// ```
pub fn encode_to_slice<T: AsRef<[u8]>>(input: T, output: &mut [u8]) -> Result<(), FromHexError> {
if input.as_ref().len() * 2 != output.len() {
return Err(FromHexError::InvalidStringLength);
}

for (byte, (i, j)) in input
.as_ref()
.iter()
.zip(generate_iter(input.as_ref().len() * 2))
{
let (high, low) = byte2hex(*byte, HEX_CHARS_LOWER);
output[i] = high;
output[j] = low;
}

Ok(())
}

#[cfg(test)]
mod test {
use super::*;

#[test]
fn test_gen_iter() {
let mut result = Vec::new();
result.push((0, 1));
result.push((2, 3));

assert_eq!(generate_iter(5).collect::<Vec<_>>(), result);
}

#[test]
fn test_encode_to_slice() {
let mut output_1 = [0; 4 * 2];
encode_to_slice(b"kiwi", &mut output_1).unwrap();
assert_eq!(&output_1, b"6b697769");

let mut output_2 = [0; 5 * 2];
encode_to_slice(b"kiwis", &mut output_2).unwrap();
assert_eq!(&output_2, b"6b69776973")
}

#[test]
fn test_encode() {
assert_eq!(encode("foobar"), "666f6f626172");
Expand Down

0 comments on commit c669098

Please sign in to comment.