substrate/
debug.rs

1use std::sync::atomic::{AtomicBool, Ordering};
2
3pub static DEBUG_ENABLED: AtomicBool = AtomicBool::new(false);
4
5pub fn enable_debug() {
6    DEBUG_ENABLED.store(true, Ordering::Relaxed);
7}
8
9pub fn is_debug_enabled() -> bool {
10    DEBUG_ENABLED.load(Ordering::Relaxed)
11}
12
13#[cfg(feature = "debug")]
14pub fn log_hex(data: &[u8], stride: usize, mark: Option<&str>) {
15    if !is_debug_enabled() {
16        return;
17    }
18
19    const HEX_WIDTH: usize = 16;
20    let mut i = 0;
21
22    while i < data.len() {
23        if i % HEX_WIDTH == 0 {
24            if let Some(m) = mark {
25                print!("\n[{}] ", m);
26            }
27            print!("0x{:03x}:", i);
28        }
29
30        print!(" ");
31        for q in (0..stride).rev() {
32            if i + q < data.len() {
33                print!("{:02x}", data[i + stride - q - 1]);
34            }
35        }
36
37        i += stride;
38
39        if i % HEX_WIDTH == 0 && i <= data.len() {
40            print!(" ");
41            for j in (i.saturating_sub(HEX_WIDTH))..i.min(data.len()) {
42                let c = data[j];
43                let ch = if c >= 0x20 && c < 0x80 { c as char } else { '.' };
44                print!("{}", ch);
45            }
46            println!();
47        }
48    }
49
50    if i % HEX_WIDTH != 0 {
51        let remaining = HEX_WIDTH - (i % HEX_WIDTH);
52        for _ in 0..remaining {
53            print!("   ");
54        }
55        print!(" ");
56        for j in (i / HEX_WIDTH * HEX_WIDTH)..(i.min(data.len())) {
57            let c = data[j];
58            let ch = if c >= 0x20 && c < 0x80 { c as char } else { '.' };
59            print!("{}", ch);
60        }
61        println!();
62    }
63}
64
65#[cfg(not(feature = "debug"))]
66pub fn log_hex(_data: &[u8], _stride: usize, _mark: Option<&str>) {}