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