Skip to content

Commit

Permalink
Fix endianness check bug
Browse files Browse the repository at this point in the history
  • Loading branch information
kiranshila committed Apr 5, 2024
1 parent a05cd81 commit f2514af
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 16 deletions.
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "sigproc_filterbank"
version = "0.3.1"
version = "0.4.0"
edition = "2021"
rust-version = "1.57.0"
license = "Apache-2.0 OR MIT"
Expand Down
42 changes: 29 additions & 13 deletions src/read.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,16 @@ use crate::errors::FilterbankError;
type ParseResult<'a, T> = IResult<&'a [u8], T, FilterbankError>;
type HeaderResult<'a> = ParseResult<'a, HeaderParameter<'a>>;

/// Figure out the endianness of the file by matching the length field of the `HEADER_START` at the start of the file
fn determine_endianness(input: &[u8]) -> Result<Endianness, nom::Err<FilterbankError>> {
let test_bytes = &input[..4];
match test_bytes {
[12, 0, 0, 0] => Ok(Endianness::Little),
[0, 0, 0, 12] => Ok(Endianness::Big),
_ => Err(nom::Err::Failure(FilterbankError::InvalidHeader)),
}
}

fn header_string(s: &'static str, endian: Endianness) -> impl FnMut(&[u8]) -> ParseResult<&[u8]> {
move |input: &[u8]| length_value(u32(endian), tag(s))(input)
}
Expand Down Expand Up @@ -174,16 +184,10 @@ fn nbits(input: &[u8], endian: Endianness) -> HeaderResult {
}

fn header<'a>(input: &'a [u8]) -> ParseResult<'a, (Endianness, Vec<HeaderParameter<'a>>)> {
// Determine the endianness based on the first match of HEADER_START
let res_big = header_start(input, Endianness::Big);
let res_little = header_start(input, Endianness::Little);
let (remaining, endian) = if let Ok((remaining, _)) = res_big {
(remaining, Endianness::Big)
} else if let Ok((remaining, _)) = res_little {
(remaining, Endianness::Little)
} else {
return Err(res_little.err().unwrap());
};
// Determine the endianness
let endian = determine_endianness(input)?;
// Match the header
let (remaining, _) = header_start(input, endian)?;
// The rest of the owl
let (remaining, (headers, _)) = many_till(
alt((
Expand Down Expand Up @@ -511,7 +515,7 @@ mod tests {
use std::{fs::File, io::Read};

use super::*;
use crate::write::sigproc_string;
use crate::write::{sigproc_string, sigproc_string_endian};

#[test]
fn test_start_end() {
Expand All @@ -524,8 +528,20 @@ mod tests {
}

#[test]
fn test_wrong_endian() {
let hstart = sigproc_string("HEADER_START");
fn test_wrong_endian_big() {
let hstart = sigproc_string_endian("HEADER_START", Endianness::Big);
let a = header_start(&hstart, Endianness::Big);
let b = header_start(&hstart, Endianness::Little);
if a.is_err() {
assert!(b.is_ok())
} else {
assert!(b.is_err())
}
}

#[test]
fn test_wrong_endian_little() {
let hstart = sigproc_string_endian("HEADER_START", Endianness::Little);
let a = header_start(&hstart, Endianness::Big);
let b = header_start(&hstart, Endianness::Little);
if a.is_err() {
Expand Down
29 changes: 27 additions & 2 deletions src/write.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,22 @@
use std::marker::PhantomData;

use nom::number::Endianness;
use ux::{u1, u2, u4};

/// Create an endian-specific sigproc-compatible string
#[allow(unused)]
pub(crate) fn sigproc_string_endian(s: &str, endian: Endianness) -> Vec<u8> {
let len = s.len() as u32;
let mut out = vec![];
match endian {
Endianness::Big => out.extend_from_slice(&len.to_be_bytes()),
Endianness::Little => out.extend_from_slice(&len.to_le_bytes()),
Endianness::Native => out.extend_from_slice(&len.to_ne_bytes()),
}
out.extend_from_slice(s.as_bytes());
out
}

/// Creates a sigproc-compatible string
pub(crate) fn sigproc_string(s: &str) -> Vec<u8> {
let len = s.len() as u32;
Expand Down Expand Up @@ -313,11 +328,21 @@ mod tests {
use super::*;
use crate::read::ReadFilterbank;

// Tested seperately because we don't know the endianness of the test platform

#[test]
fn test_sigproc_string() {
fn test_sigproc_string_little() {
assert_eq!(
b"\x0C\x00\x00\x00HEADER_START".to_vec(),
sigproc_string("HEADER_START")
sigproc_string_endian("HEADER_START", Endianness::Little)
);
}

#[test]
fn test_sigproc_string_big() {
assert_eq!(
b"\x00\x00\x00\x0CHEADER_START".to_vec(),
sigproc_string_endian("HEADER_START", Endianness::Big)
);
}

Expand Down

0 comments on commit f2514af

Please sign in to comment.