use std::fmt::Write;
#[derive(Clone, Copy, PartialEq, Eq)]
pub enum Endian {
Little,
Big,
}
impl Endian {
pub fn label(&self) -> &str {
match self {
Endian::Little => "LE",
Endian::Big => "BE",
}
}
}
#[derive(Clone)]
pub struct DecodedValue {
pub label: String,
pub value: String,
pub range: Option<(usize, usize)>,
pub color_index: Option<usize>,
}
impl DecodedValue {
pub(crate) fn new(label: impl Into<String>, value: impl Into<String>) -> Self {
Self {
label: label.into(),
value: value.into(),
range: None,
color_index: None,
}
}
#[allow(dead_code)]
pub fn with_range(mut self, offset: usize, length: usize) -> Self {
self.range = Some((offset, length));
self
}
}
pub const RANGE_COLORS: &[(u8, u8, u8)] = &[
(100, 180, 240), (240, 160, 80), (120, 220, 120), (220, 120, 220), (240, 220, 80), (100, 220, 220), (240, 120, 120), (180, 140, 240), (140, 220, 180), (240, 180, 160), ];
pub(crate) fn read_u16(bytes: &[u8], endian: Endian) -> u16 {
let b: [u8; 2] = [bytes[0], bytes[1]];
match endian {
Endian::Little => u16::from_le_bytes(b),
Endian::Big => u16::from_be_bytes(b),
}
}
pub(crate) fn read_u32(bytes: &[u8], endian: Endian) -> u32 {
let b: [u8; 4] = [bytes[0], bytes[1], bytes[2], bytes[3]];
match endian {
Endian::Little => u32::from_le_bytes(b),
Endian::Big => u32::from_be_bytes(b),
}
}
pub(crate) fn read_u64(bytes: &[u8], endian: Endian) -> u64 {
let b: [u8; 8] = [
bytes[0], bytes[1], bytes[2], bytes[3], bytes[4], bytes[5], bytes[6], bytes[7],
];
match endian {
Endian::Little => u64::from_le_bytes(b),
Endian::Big => u64::from_be_bytes(b),
}
}
pub(crate) fn format_hex(bytes: &[u8]) -> String {
let mut hex = String::new();
for (i, b) in bytes.iter().enumerate() {
if i > 0 {
hex.push(' ');
}
write!(hex, "{:02X}", b).ok();
if i >= 31 {
hex.push_str("...");
break;
}
}
hex
}
pub(crate) fn format_binary(bytes: &[u8]) -> String {
let mut bin = String::new();
for (i, b) in bytes.iter().enumerate() {
if i > 0 {
bin.push(' ');
}
write!(bin, "{:08b}", b).ok();
if i >= 7 {
bin.push_str("...");
break;
}
}
bin
}
pub(crate) fn format_octal(bytes: &[u8]) -> String {
let mut oct = String::new();
for (i, b) in bytes.iter().enumerate() {
if i > 0 {
oct.push(' ');
}
write!(oct, "{:03o}", b).ok();
if i >= 15 {
oct.push_str("...");
break;
}
}
oct
}