Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
65 changes: 5 additions & 60 deletions scripts/tdf_decoder.rs.jinja
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
use std::io::{Cursor, Read, Result, Error, ErrorKind};

use byteorder::{LittleEndian, BigEndian, ReadBytesExt};

pub fn tdf_name(tdf_id: &u16) -> String
{
match tdf_id {
Expand All @@ -12,17 +10,7 @@ pub fn tdf_name(tdf_id: &u16) -> String
}
}

pub fn tdf_fields(tdf_id: &u16) -> Vec<&'static str>
{
match tdf_id {
{% for tdf_id, info in definitions.items() %}
{{ tdf_id }} => vec![{{ info['rust_head'] }}],
{% endfor %}
_ => vec!["unknown"],
}
}

fn vla_bytes_remaining(cursor: &mut Cursor<&[u8]>, cursor_start: u64, size: u8) -> Result<usize>
pub fn vla_bytes_remaining(cursor: &mut Cursor<&[u8]>, cursor_start: u64, size: u8) -> Result<usize>
{
let cursor_current = cursor.position();
let cursor_read = cursor_current - cursor_start;
Expand All @@ -37,7 +25,7 @@ fn vla_bytes_remaining(cursor: &mut Cursor<&[u8]>, cursor_start: u64, size: u8)
Ok(bytes_remaining as usize)
}

fn tdf_field_read_string(cursor: &mut Cursor<&[u8]>, cursor_start: u64, num: u8, size: u8) -> Result<String>
pub fn tdf_field_read_string(cursor: &mut Cursor<&[u8]>, cursor_start: u64, num: u8, size: u8) -> Result<Vec<u8>>
{
let string_length = match num {
0 => vla_bytes_remaining(cursor, cursor_start, size)?,
Expand All @@ -47,57 +35,14 @@ fn tdf_field_read_string(cursor: &mut Cursor<&[u8]>, cursor_start: u64, num: u8,
let mut buf = vec![0u8; string_length];
cursor.read_exact(&mut buf)?;

match String::from_utf8(buf) {
Ok(val) => Ok(format!("\"{}\"", val.trim_matches(char::from(0)))),
Err(..) => Ok(String::from("\"\""))
}
Ok(buf)
}

fn tdf_field_read_vla(cursor: &mut Cursor<&[u8]>, cursor_start: u64, size: u8) -> Result<String>
pub fn tdf_field_read_vla(cursor: &mut Cursor<&[u8]>, cursor_start: u64, size: u8) -> Result<Vec<u8>>
{
let bytes_remaining = vla_bytes_remaining(cursor, cursor_start, size)?;
let mut buf = vec![0u8; bytes_remaining];

cursor.read_exact(&mut buf)?;
Ok(format!("{}", hex::encode(buf)))
}

pub fn tdf_read_into_str(tdf_id: &u16, size: u8, cursor: &mut Cursor<&[u8]>) -> Result<String>
{
let cursor_start = cursor.position();

let res = match tdf_id {
{% for tdf_id, info in definitions.items() %}
{{ tdf_id }} =>
Ok(format!(
"{{ info['rust_fmt'] }}",
{% for conv in info['rust_convs'] %}
{{ conv[1] }},
{% endfor %}
)),
{% endfor %}
_ => {
let mut buf = vec![0; size as usize];
cursor.read_exact(&mut buf)?;
Ok(format!("{}", hex::encode(buf)))
}
};
let cursor_end = cursor.position();
let cursor_read = cursor_end - cursor_start;

if (size as u64) < cursor_read {
// Hande read overflow (more data read than specified)
return Result::Err(Error::new(
ErrorKind::InvalidData,
"Read overflow, corrupt data/metadata",
));
}

let underflow = size as u64 - cursor_read;

// Handle read underflow (more data specified than expected)
if underflow > 0 {
tdf_field_read_string(cursor, cursor_start, 0, underflow as u8)?;
}
res
Ok(buf)
}
30 changes: 20 additions & 10 deletions scripts/tdf_decoder_build.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,8 @@ def decoders_gen(tdf_defs, output):
trim_blocks=True,
lstrip_blocks=True,
)
tdf_template = env.get_template("tdf_decoder.rs.jinja")
common_template = env.get_template("tdf_decoder.rs.jinja")
csv_template = env.get_template("tdf_decoder_csv.rs.jinja")

def field_conv_func(field, name_prefix=None):
t = rust_type[field["type"]]
Expand Down Expand Up @@ -80,12 +81,14 @@ def field_conv_func(field, name_prefix=None):
return [
(
n,
f"tdf_field_read_string(cursor, cursor_start, {field['num']}, size)?",
f"tdf_field_read_string_to_str(cursor, cursor_start, {field['num']}, size)?",
)
]
else:
if field["num"] == 0:
return [(n, "tdf_field_read_vla(cursor, cursor_start, size)?")]
return [
(n, "tdf_field_read_vla_to_str(cursor, cursor_start, size)?")
]
else:
return [(n + f"[{idx}]", func) for idx in range(field["num"])]
else:
Expand Down Expand Up @@ -117,7 +120,7 @@ def field_fmt(field):
struct_fmts[f"struct {name}"] = fmts

# Generate rust conversion functions
for tdf_id, info in tdf_defs["definitions"].items():
for _tdf_id, info in tdf_defs["definitions"].items():
info["rust_convs"] = []
fmt = []
for f in info["fields"]:
Expand All @@ -133,13 +136,20 @@ def field_fmt(field):
info["rust_head"] = ",".join([f'"{c[0]}"' for c in info["rust_convs"]])
info["rust_fmt"] = ",".join(fmt)

tdf_output = pathlib.Path(output) / "decoders.rs"
with tdf_output.open("w") as f:
f.write(
tdf_template.render(
structs=tdf_defs["structs"], definitions=tdf_defs["definitions"]
)
common_output = pathlib.Path(output) / "decoders.rs"
csv_output = pathlib.Path(output) / "decoders_csv.rs"
with common_output.open("w") as f:
rendered = common_template.render(
structs=tdf_defs["structs"], definitions=tdf_defs["definitions"]
)
f.write(rendered)
f.write(os.linesep)

with csv_output.open("w") as f:
rendered = csv_template.render(
structs=tdf_defs["structs"], definitions=tdf_defs["definitions"]
)
f.write(rendered)
f.write(os.linesep)


Expand Down
70 changes: 70 additions & 0 deletions scripts/tdf_decoder_csv.rs.jinja
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
use std::io::{Cursor, Read, Result, Error, ErrorKind};

use byteorder::{LittleEndian, BigEndian, ReadBytesExt};

pub fn tdf_fields(tdf_id: &u16) -> Vec<&'static str>
{
match tdf_id {
{% for tdf_id, info in definitions.items() %}
{{ tdf_id }} => vec![{{ info['rust_head'] }}],
{% endfor %}
_ => vec!["unknown"],
}
}

fn tdf_field_read_string_to_str(cursor: &mut Cursor<&[u8]>, cursor_start: u64, num: u8, size: u8) -> Result<String>
{
let buf = crate::decoders::tdf_field_read_string(cursor, cursor_start, num, size)?;

match String::from_utf8(buf) {
Ok(val) => Ok(format!("\"{}\"", val.trim_matches(char::from(0)))),
Err(..) => Ok(String::from("\"\""))
}
}

fn tdf_field_read_vla_to_str(cursor: &mut Cursor<&[u8]>, cursor_start: u64, size: u8) -> Result<String>
{
let buf = crate::decoders::tdf_field_read_vla(cursor, cursor_start, size)?;

Ok(format!("{}", hex::encode(buf)))
}

pub fn tdf_read_into_str(tdf_id: &u16, size: u8, cursor: &mut Cursor<&[u8]>) -> Result<String>
{
let cursor_start = cursor.position();

let res = match tdf_id {
{% for tdf_id, info in definitions.items() %}
{{ tdf_id }} =>
Ok(format!(
"{{ info['rust_fmt'] }}",
{% for conv in info['rust_convs'] %}
{{ conv[1] }},
{% endfor %}
)),
{% endfor %}
_ => {
let mut buf = vec![0; size as usize];
cursor.read_exact(&mut buf)?;
Ok(format!("{}", hex::encode(buf)))
}
};
let cursor_end = cursor.position();
let cursor_read = cursor_end - cursor_start;

if (size as u64) < cursor_read {
// Hande read overflow (more data read than specified)
return Result::Err(Error::new(
ErrorKind::InvalidData,
"Read overflow, corrupt data/metadata",
));
}

let underflow = size as u64 - cursor_read;

// Handle read underflow (more data specified than expected)
if underflow > 0 {
crate::decoders::tdf_field_read_string(cursor, cursor_start, 0, underflow as u8)?;
}
res
}
4 changes: 2 additions & 2 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ impl TdfOutput for TdfCsvWriter {
let mut writer = std::io::BufWriter::new(std::fs::File::create(path.clone())?);

// Write header into file
let heading = tdf::decoders::tdf_fields(&tdf_id).join(",");
let heading = tdf::decoders_csv::tdf_fields(&tdf_id).join(",");
writer.write_all(format!("time,{}\n", heading).as_bytes())?;

// Touch the count variable in case the decoding fails
Expand All @@ -98,7 +98,7 @@ impl TdfOutput for TdfCsvWriter {
};

// Construct CSV line
let reading = tdf::decoders::tdf_read_into_str(&tdf_id, size, cursor)?;
let reading = tdf::decoders_csv::tdf_read_into_str(&tdf_id, size, cursor)?;
let time = match tdf_idx {
Some(idx) => {
// Use the index directly if provided
Expand Down
Loading
Loading