67 lines
1.7 KiB
Rust
67 lines
1.7 KiB
Rust
use crate::byte_stream::ByteStream;
|
|
use serde::Deserialize;
|
|
use std::fmt::Write;
|
|
|
|
#[derive(Debug, Deserialize, Clone)]
|
|
#[serde(tag = "type")]
|
|
pub enum FieldType {
|
|
/// Unsigned Int
|
|
UInt { bit_width: usize },
|
|
/// Unsigned Int
|
|
Int { bit_width: usize },
|
|
/// Null Terminated String Field
|
|
String { max_len: usize },
|
|
/// Fixed Byte Length Field
|
|
Bytes { max_len: usize },
|
|
}
|
|
|
|
#[derive(Debug, Deserialize, Clone)]
|
|
pub struct Field {
|
|
/// Field Name
|
|
pub name: String,
|
|
/// Field Type
|
|
pub field_type: FieldType,
|
|
}
|
|
|
|
impl Field {
|
|
fn format_data(&self, byte_stream: &ByteStream, bit_ndx: usize) -> (String, usize) {
|
|
match self.field_type {
|
|
FieldType::UInt { bit_width } => {
|
|
let bytes = byte_stream.get_bytes(bit_ndx, bit_width).unwrap();
|
|
let mut string = String::with_capacity(bytes.len() * 2);
|
|
|
|
for byte in bytes.iter().rev() {
|
|
string.push_str(&format!("{:x}", byte))
|
|
}
|
|
|
|
(string, bit_width)
|
|
}
|
|
_ => ("".to_string(), 0),
|
|
}
|
|
}
|
|
}
|
|
|
|
#[derive(Debug, Deserialize, Clone)]
|
|
pub struct Format {
|
|
/// Format Name
|
|
pub name: String,
|
|
/// Elements of the format
|
|
pub fields: Vec<Field>,
|
|
}
|
|
|
|
impl Format {
|
|
pub fn format_data(&self, data: &[u8]) -> String {
|
|
let mut s = String::new();
|
|
let byte_stream = ByteStream::from(data);
|
|
let mut bit_ndx: usize = 0;
|
|
|
|
for field in &self.fields {
|
|
let (data_str, bit_width) = field.format_data(&byte_stream, bit_ndx);
|
|
bit_ndx += bit_width;
|
|
writeln!(s, "{}: {}", field.name, data_str).unwrap();
|
|
}
|
|
|
|
s
|
|
}
|
|
}
|