1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112
//! This module defines several low-level utility functions for general use by ArmorLib. You can //! use these functions in your own program, but they are designed for internal use. use std::num::ParseIntError; /// A utility function that converts a string of space-separated hexadecimal bytes into a `Vec<u8>` /// for use by preprocessors, scan modules, and other programs. /// /// # Examples /// /// ```rust /// use armorlib::util; /// assert_eq!( /// util::hex_to_vec("00 00 01 00 BA 3C 2B A9").unwrap(), /// [ /// 0x00_u8, 0x00_u8, 0x01_u8, 0x00_u8, 0xBA_u8, 0x3C_u8, 0x2B_u8, 0xA9_u8 /// ] /// ); /// /// match util::hex_to_vec("invalid HEX string") { /// Ok(_) => assert!(false), /// Err(_) => assert!(true), /// } /// ``` #[allow(dead_code)] pub fn hex_to_vec(hex: &str) -> Result<Vec<u8>, ParseIntError> { let mut bytes: Vec<u8> = Vec::new(); for byte in String::from(hex).to_uppercase().split(" ") { bytes.push(u8::from_str_radix(byte, 16)?); } Ok(bytes) } /// A utility function that, given two `u8`s, uses a bit shift operation and a binary `OR` /// operation to return a `u16`. The first 8 bits of this `u16` are those of the argument `first`, /// while the second 8 bits are those of the argument `second`. /// /// # Examples /// /// ```rust /// use armorlib::util; /// let first = 0x12_u8; /// let second = 0xAB_u8; /// assert_eq!(util::u8s_to_u16(first, second), 0x12AB_u16); /// ``` pub fn u8s_to_u16(first: u8, second: u8) -> u16 { let first: u16 = (first as u16) << 8; let second: u16 = second as u16; first | second } /// A utility function that, given four `u8`s, uses a bit shift operation and a binary `OR` /// operation to return a `u32`. The first 8 bits of this `u32` are those of the argument `first`, /// the second 8 bits are those of the argument `second`, the third eight bits from `third`, and /// the final 8 bits from `fourth`. /// /// # Examples /// /// ```rust /// use armorlib::util; /// let first = 0x12_u8; /// let second = 0xAB_u8; /// let third = 0xDE_u8; /// let fourth = 0x53_u8; /// assert_eq!(util::u8s_to_u32(first, second, third, fourth), 0x12ABDE53_u32); /// ``` pub fn u8s_to_u32(first: u8, second: u8, third: u8, fourth: u8) -> u32 { let first: u32 = (first as u32) << 24; let second: u32 = (second as u32) << 16; let third: u32 = (third as u32) << 8; let fourth: u32 = fourth as u32; first | second | third | fourth } #[cfg(test)] mod tests { use util::{hex_to_vec, u8s_to_u16, u8s_to_u32}; #[test] fn test_hex_to_vec() { assert_eq!( hex_to_vec("00 00 01 00 BA 3C 2B A9").unwrap(), [ 0x00_u8, 0x00_u8, 0x01_u8, 0x00_u8, 0xBA_u8, 0x3C_u8, 0x2B_u8, 0xA9_u8 ] ); match hex_to_vec("invalid HEX string") { Ok(_) => assert!(false), Err(_) => assert!(true), } } #[test] fn test_u8s_to_u16() { let first = 0xAB_u8; let second = 0xCD_u8; assert_eq!(u8s_to_u16(first, second), 0xABCD_u16); } #[test] fn test_u8s_to_u32() { let first = 0x01_u8; let second = 0x23_u8; let third = 0x45_u8; let fourth = 0x67_u8; assert_eq!(u8s_to_u32(first, second, third, fourth), 0x01234567_u32); } }