hdd/
utils.rs

1pub fn bytes_to_be_words(data: &Vec<u8>) -> Vec<u16> {
2	let mut output = vec![];
3
4	// XXX what if `data` contains odd number of u8s?
5	for i in 0 .. data.len()/2 {
6		if cfg!(target_endian = "little") {
7			output.push(
8				((data[2 * i + 1] as u16) << 8)
9				+ (data[2 * i] as u16)
10			);
11		} else {
12			output.push(
13				((data[2 * i] as u16) << 8)
14				+ (data[2 * i + 1] as u16)
15			);
16		}
17	}
18
19	output
20}
21
22fn pretty_char_from_u8(x: u8) -> char {
23	if x >= 0x20 && x <= 0x7f {
24		// safety: we already checked whether the u8 is a valid ascii printable (and therefore is a valid unicode codepoint)
25		unsafe { ::std::char::from_u32_unchecked(x as u32) }
26	} else {
27		// ' ' and '.' are ambiguous, and a string of '�'s is just unreadable
28		'░'
29	}
30}
31
32#[cfg_attr(feature = "cargo-clippy", allow(needless_range_loop))]
33pub fn hexdump_8(data: &[u8]) -> String {
34	// 3× (len rounded up to the multiple of 16) for ' {:02x}'
35	// len/16 for \n
36	// len/16 for ' ' before ascii
37	// len (really rounded up len, because I'm lazy) for ascii
38	// 2 to "round" (/16)s up and have lesser chance of reallocation
39	let l = data.len();
40	let mut dump = String::with_capacity(4*(l + 16 - l % 16) + l/8 + 2);
41	let mut ascii = String::with_capacity(16);
42
43	for i in 0..data.len() {
44		if i % 16 == 0 {
45			dump.push(' ');
46			dump.push_str(&ascii);
47			ascii.truncate(0);
48			dump.push('\n');
49		}
50		dump.push_str(&format!(" {:02x}", data[i]));
51		ascii.push(pretty_char_from_u8(data[i]));
52	}
53	// align trailing ascii
54	if data.len() % 16 != 0 {
55		for _ in 0..16 - data.len() % 16 {
56			dump.push_str("   ");
57		}
58	}
59	dump.push(' ');
60	dump.push_str(&ascii);
61	ascii.truncate(0);
62	dump.push('\n');
63	dump
64}
65
66#[cfg_attr(feature = "cargo-clippy", allow(needless_range_loop))]
67pub fn hexdump_16be(data: &[u16]) -> String {
68	// 5× (len rounded up to the multiple of 8) for ' {:04x}'
69	// len/8 for \n
70	// len/8 for ' ' before ascii
71	// 2× len (really rounded up len, because I'm lazy) for ascii
72	// 2 to "round" (/8)s up and have lesser chance of reallocation
73	let l = data.len();
74	let mut dump = String::with_capacity(7*(l + 8 - l%8) + data.len()/4 + 2);
75	let mut ascii = String::with_capacity(16);
76
77	for i in 0..data.len() {
78		if i % 8 == 0 {
79			dump.push(' ');
80			dump.push_str(&ascii);
81			ascii.truncate(0);
82			dump.push('\n');
83		}
84		dump.push_str(&format!(" {:04x}", data[i]));
85		ascii.push(pretty_char_from_u8((data[i] >> 8) as u8));
86		ascii.push(pretty_char_from_u8((data[i] & 0xff) as u8));
87	}
88	// align trailing ascii
89	if data.len() % 8 != 0 {
90		for _ in 0..8 - data.len() % 8 {
91			dump.push_str("     ");
92		}
93	}
94	dump.push(' ');
95	dump.push_str(&ascii);
96	ascii.truncate(0);
97	dump.push('\n');
98	dump
99}