const BITS_IN_BYTE: u8 = 8;
pub struct QwordTable<'a> {
data: &'a Vec<u8>
}
impl<'a> QwordTable<'a> {
pub fn from_bytes(data: &Vec<u8>) -> QwordTable {
QwordTable {
data
}
}
pub fn format(self: &QwordTable<'a>) -> String {
let mut result = self.format_qword_table_header();
let num_qwords = self.data.len().div_euclid(BITS_IN_BYTE as usize);
for i in 0..num_qwords {
let from_byte_ix = i * BITS_IN_BYTE as usize;
let to_byte_ix = from_byte_ix + BITS_IN_BYTE as usize;
let qword_number: usize = i + 1;
result.push_str(&self.format_qword_row(qword_number, &self.data[from_byte_ix..to_byte_ix], BITS_IN_BYTE as usize));
}
let remaining_bytes = self.data.len().rem_euclid(BITS_IN_BYTE as usize);
let from_byte_ix: usize = num_qwords * BITS_IN_BYTE as usize;
let to_byte_ix: usize = from_byte_ix + remaining_bytes as usize;
let qword_number: usize = num_qwords + 1;
result.push_str(&self.format_qword_row(
qword_number,
&self.data[from_byte_ix..to_byte_ix],
remaining_bytes,
));
result
}
fn format_qword_table_header(self: &QwordTable<'a>) -> String {
let mut result = String::from(" +");
result.push_str(
&(0..BITS_IN_BYTE)
.map(|_| "--------+")
.collect::<String>(),
);
result.push_str("\n Bytes |");
result.push_str(
&(0..BITS_IN_BYTE)
.map(|i| format!(" Byte {} |", i))
.collect::<String>(),
);
result.push_str("\n+------+");
result.push_str(
&(0..BITS_IN_BYTE)
.map(|_| "--------+")
.collect::<String>(),
);
result.push_str("\n");
result
}
fn format_qword_row(self: &QwordTable<'a>, qword_number: usize, data: &[u8], num_bytes: usize) -> String {
if data.len() != num_bytes {
return format!("ERROR: Data must contain exactly {} bytes. QWORD: {}\n", num_bytes, qword_number);
}
let mut result = String::from("|QWORD |");
result.push_str(
&(0..num_bytes)
.map(|i| format!("{:0>8b}|", data[i]))
.collect::<String>(),
);
result.push_str(&format!("\n|{:^6}|", qword_number));
result.push_str(
&(0..num_bytes)
.map(|i| format!("{:>8}|", format!("({})", data[i])))
.collect::<String>(),
);
result.push_str("\n+------+");
result.push_str(
&(0..num_bytes)
.map(|_| "--------+")
.collect::<String>(),
);
result.push_str("\n");
result
}
}
#[cfg(test)]
mod tests {
}