1 // Copyright (c) 2017,2021 Linaro LTD
2 //
3 // SPDX-License-Identifier: Apache-2.0
4
5 // Printable hexdump.
6
7 pub trait HexDump {
8 // Output the data value in hex.
dump(&self)9 fn dump(&self);
10 }
11
12 struct Dumper {
13 hex: String,
14 ascii: String,
15 count: usize,
16 total_count: usize,
17 }
18
19 impl Dumper {
new() -> Dumper20 fn new() -> Dumper {
21 Dumper {
22 hex: String::with_capacity(49),
23 ascii: String::with_capacity(16),
24 count: 0,
25 total_count: 0,
26 }
27 }
28
add_byte(&mut self, ch: u8)29 fn add_byte(&mut self, ch: u8) {
30 if self.count == 16 {
31 self.ship();
32 }
33 if self.count == 8 {
34 self.hex.push(' ');
35 }
36 self.hex.push_str(&format!(" {:02x}", ch)[..]);
37 self.ascii.push(if (b' '..=b'~').contains(&ch) {
38 ch as char
39 } else {
40 '.'
41 });
42 self.count += 1;
43 }
44
ship(&mut self)45 fn ship(&mut self) {
46 if self.count == 0 {
47 return;
48 }
49
50 println!("{:06x} {:-49} |{}|", self.total_count, self.hex, self.ascii);
51
52 self.hex.clear();
53 self.ascii.clear();
54 self.total_count += 16;
55 self.count = 0;
56 }
57 }
58
59 impl<'a> HexDump for &'a [u8] {
dump(&self)60 fn dump(&self) {
61 let mut dump = Dumper::new();
62 for ch in self.iter() {
63 dump.add_byte(*ch);
64 }
65 dump.ship();
66 }
67 }
68
69 impl HexDump for Vec<u8> {
dump(&self)70 fn dump(&self) {
71 (&self[..]).dump()
72 }
73 }
74
75 #[test]
samples()76 fn samples() {
77 "Hello".as_bytes().dump();
78 "This is a much longer string".as_bytes().dump();
79 "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f".as_bytes().dump();
80 }
81