lspci/
util.rs

1// Copyright 2020 The Fuchsia Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5// Print a + or - based on whether a given field is true.
6pub fn is_set(field: bool) -> char {
7    match field {
8        true => '+',
9        false => '-',
10    }
11}
12
13// Turn bytes into a human readable value.
14pub fn format_bytes(size: u64) -> String {
15    let mut s = size;
16    let mut divs: u8 = 0;
17    while s / 1024 >= 1 {
18        s /= 1024;
19        divs += 1;
20    }
21
22    format!(
23        "{}{}",
24        s,
25        match divs {
26            0 => "B",
27            1 => "K",
28            2 => "M",
29            3 => "G",
30            4 => "T",
31            _ => return size.to_string(),
32        }
33    )
34}
35
36const SLICE_SIZE: usize = 16;
37pub struct Hexdumper<'a> {
38    pub bytes: &'a [u8],
39    pub show_header: bool,
40    pub show_ascii: bool,
41    pub offset: Option<u64>,
42}
43
44impl std::fmt::Display for Hexdumper<'_> {
45    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
46        let size = std::cmp::min(self.bytes.len(), SLICE_SIZE);
47        // Weep for those who do not use monospace terminal fonts.
48        if self.show_header {
49            write!(f, "        ")?;
50            for col in 0..size {
51                write!(f, " {:1x} ", col)?;
52                if col == 7 {
53                    write!(f, " ")?;
54                }
55            }
56            writeln!(f)?;
57        }
58
59        let start_addr = self.offset.unwrap_or(0) as usize;
60        for (addr, slice) in self.bytes.chunks(SLICE_SIZE).enumerate() {
61            write!(f, "  {:04x}: ", start_addr + (addr * SLICE_SIZE))?;
62            for (i, byte) in slice.iter().enumerate() {
63                write!(f, "{:02x} ", byte)?;
64                if i == 7 {
65                    write!(f, " ")?;
66                }
67            }
68            if self.show_ascii {
69                write!(f, " ")?;
70                for byte in slice {
71                    if byte.is_ascii_graphic() {
72                        write!(f, "{}", *byte as char)?;
73                    } else {
74                        write!(f, ".")?;
75                    }
76                }
77            }
78            writeln!(f)?;
79        }
80        Ok(())
81    }
82}