blob: b2f403fd7771e5f71044e02c69bc2ab77b9bb311 [file] [log] [blame]
David Brownc8d62012021-10-27 15:03:48 -06001// Copyright (c) 2017,2021 Linaro LTD
David Browne2acfae2020-01-21 16:45:01 -07002//
3// SPDX-License-Identifier: Apache-2.0
4
David Brownde7729e2017-01-09 10:41:35 -07005// Printable hexdump.
6
7pub trait HexDump {
8 // Output the data value in hex.
9 fn dump(&self);
10}
11
12struct Dumper {
13 hex: String,
14 ascii: String,
15 count: usize,
16 total_count: usize,
17}
18
19impl Dumper {
20 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
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)[..]);
David Brown2547c002021-03-10 05:20:17 -070037 self.ascii.push(if (b' '..=b'~').contains(&ch) {
David Brownde7729e2017-01-09 10:41:35 -070038 ch as char
39 } else {
40 '.'
41 });
42 self.count += 1;
43 }
44
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
59impl<'a> HexDump for &'a [u8] {
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
69impl HexDump for Vec<u8> {
70 fn dump(&self) {
71 (&self[..]).dump()
72 }
73}
74
75#[test]
76fn 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}