Fully Working CCSDS parsing
+ updated ccsds config to make it work, as I expect it to at leastpull/1/head
parent
e822d9ff13
commit
f8ba81e2ca
|
@ -3,34 +3,40 @@
|
||||||
# Ref: https://public.ccsds.org/Pubs/133x0b2e1.pdfa
|
# Ref: https://public.ccsds.org/Pubs/133x0b2e1.pdfa
|
||||||
#
|
#
|
||||||
# Example Packet:
|
# Example Packet:
|
||||||
# [0xe0, 0xa1, 0xc0, 0x00, 0x05, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05]
|
# [0xe0, 0xa1, 0xc0, 0x00, 0x00, 0x05, 0x01, 0x02, 0x03, 0x04, 0x05]
|
||||||
|
|
||||||
[[formats]]
|
[[formats]]
|
||||||
name = "ccsds"
|
name = "ccsds"
|
||||||
bit_flip = true
|
bit_flip = false
|
||||||
|
|
||||||
[[formats.fields]]
|
[[formats.fields]]
|
||||||
name = "Version Number"
|
name = "Version Number"
|
||||||
|
bit_flip = true
|
||||||
field_type = {type = "UInt", bit_width = 3, endianness = "BigEndian"}
|
field_type = {type = "UInt", bit_width = 3, endianness = "BigEndian"}
|
||||||
|
|
||||||
[[formats.fields]]
|
[[formats.fields]]
|
||||||
name = "Packet Type"
|
name = "Packet Type"
|
||||||
|
bit_flip = true
|
||||||
field_type = {type = "UInt", bit_width = 1, endianness = "BigEndian"}
|
field_type = {type = "UInt", bit_width = 1, endianness = "BigEndian"}
|
||||||
|
|
||||||
[[formats.fields]]
|
[[formats.fields]]
|
||||||
name = "Secondary Header Flag"
|
name = "Secondary Header Flag"
|
||||||
|
bit_flip = true
|
||||||
field_type = {type = "UInt", bit_width = 1, endianness = "BigEndian"}
|
field_type = {type = "UInt", bit_width = 1, endianness = "BigEndian"}
|
||||||
|
|
||||||
[[formats.fields]]
|
[[formats.fields]]
|
||||||
name = "APID"
|
name = "APID"
|
||||||
|
bit_flip = true
|
||||||
field_type = {type = "UInt", bit_width = 11, endianness = "BigEndian"}
|
field_type = {type = "UInt", bit_width = 11, endianness = "BigEndian"}
|
||||||
|
|
||||||
[[formats.fields]]
|
[[formats.fields]]
|
||||||
name = "Sequency Flags"
|
name = "Sequence Flags"
|
||||||
|
bit_flip = true
|
||||||
field_type = {type = "UInt", bit_width = 2, endianness = "BigEndian"}
|
field_type = {type = "UInt", bit_width = 2, endianness = "BigEndian"}
|
||||||
|
|
||||||
[[formats.fields]]
|
[[formats.fields]]
|
||||||
name = "Packet Sequence Count"
|
name = "Packet Sequence Count"
|
||||||
|
bit_flip = true
|
||||||
field_type = {type = "UInt", bit_width = 14, endianness = "BigEndian"}
|
field_type = {type = "UInt", bit_width = 14, endianness = "BigEndian"}
|
||||||
|
|
||||||
[[formats.fields]]
|
[[formats.fields]]
|
||||||
|
@ -40,5 +46,4 @@ field_type = {type = "UInt", bit_width = 16, endianness = "BigEndian"}
|
||||||
[[formats.fields]]
|
[[formats.fields]]
|
||||||
name = "Data"
|
name = "Data"
|
||||||
# Allow payloads up to the max size that can be specfied in "Data Length"
|
# Allow payloads up to the max size that can be specfied in "Data Length"
|
||||||
field_type = {type = "Bytes", max_len = 65535}
|
field_type = {type = "Bytes", max_len = 65535, endianness = "BigEndian"}
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use num_bigint::BigUint;
|
use crate::formatter::format::LastByte;
|
||||||
use std::fmt::{Display, Formatter};
|
use std::fmt::{Display, Formatter};
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
|
@ -31,10 +31,23 @@ pub const fn bit_mask(mask: u8) -> u8 {
|
||||||
#[derive(Default, Clone, Debug)]
|
#[derive(Default, Clone, Debug)]
|
||||||
pub struct ByteStream {
|
pub struct ByteStream {
|
||||||
data: Vec<u8>,
|
data: Vec<u8>,
|
||||||
|
reverse_bits: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ByteStream {
|
impl ByteStream {
|
||||||
pub fn get_bytes(&self, bit_ndx: usize, bit_count: usize) -> Result<Vec<u8>, ByteStreamError> {
|
pub fn set_reverse_bits(&mut self, reverse_bits: bool) {
|
||||||
|
self.reverse_bits = reverse_bits;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_reverse_bits(&self) -> bool {
|
||||||
|
self.reverse_bits
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_bytes<T: LastByte>(
|
||||||
|
&self,
|
||||||
|
bit_ndx: usize,
|
||||||
|
bit_count: usize,
|
||||||
|
) -> Result<Vec<u8>, ByteStreamError> {
|
||||||
let byte_ndx = bit_ndx / 8;
|
let byte_ndx = bit_ndx / 8;
|
||||||
let bits_before = (bit_ndx % 8) as u8;
|
let bits_before = (bit_ndx % 8) as u8;
|
||||||
let bits_in_last_byte = ((bit_ndx + bit_count - bits_before as usize) % 8) as u8;
|
let bits_in_last_byte = ((bit_ndx + bit_count - bits_before as usize) % 8) as u8;
|
||||||
|
@ -51,11 +64,17 @@ impl ByteStream {
|
||||||
return Err(ByteStreamError::OutOfRange);
|
return Err(ByteStreamError::OutOfRange);
|
||||||
}
|
}
|
||||||
|
|
||||||
let byte_stream = self.data[byte_ndx..byte_ndx + bytes_needed].to_vec();
|
let mut byte_stream = self.data[byte_ndx..byte_ndx + bytes_needed].to_vec();
|
||||||
|
|
||||||
let number = BigUint::from_bytes_le(&byte_stream) >> bits_before;
|
if self.reverse_bits {
|
||||||
|
for byte in &mut byte_stream {
|
||||||
|
*byte = byte.reverse_bits();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
let mut byte_stream = number.to_bytes_le();
|
let number = T::big_uint(&byte_stream) >> bits_before;
|
||||||
|
|
||||||
|
let mut byte_stream = T::big_u_int_to_bytes(number);
|
||||||
|
|
||||||
if bytes_needed > byte_count && bytes_needed == byte_stream.len() {
|
if bytes_needed > byte_count && bytes_needed == byte_stream.len() {
|
||||||
byte_stream.pop();
|
byte_stream.pop();
|
||||||
|
@ -81,20 +100,26 @@ impl From<&[u8]> for ByteStream {
|
||||||
|
|
||||||
impl From<Vec<u8>> for ByteStream {
|
impl From<Vec<u8>> for ByteStream {
|
||||||
fn from(vec: Vec<u8>) -> Self {
|
fn from(vec: Vec<u8>) -> Self {
|
||||||
ByteStream { data: vec }
|
ByteStream {
|
||||||
|
data: vec,
|
||||||
|
reverse_bits: false,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::ByteStream;
|
use super::ByteStream;
|
||||||
|
use byteorder::BigEndian;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_get_bytes_no_shift() {
|
fn test_get_bytes_no_shift() {
|
||||||
let bytes: Vec<u8> = vec![0xff, 0x00, 0x55];
|
let bytes: Vec<u8> = vec![0xff, 0x00, 0x55];
|
||||||
let bit_stream = ByteStream::from(bytes.clone());
|
let bit_stream = ByteStream::from(bytes.clone());
|
||||||
|
|
||||||
let new_bytes = bit_stream.get_bytes(0, bytes.len() * 8).unwrap();
|
let new_bytes = bit_stream
|
||||||
|
.get_bytes::<BigEndian>(0, bytes.len() * 8)
|
||||||
|
.unwrap();
|
||||||
assert_eq!(bytes, new_bytes);
|
assert_eq!(bytes, new_bytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -103,7 +128,7 @@ mod tests {
|
||||||
let bytes: Vec<u8> = vec![0x5f, 0x00, 0x55];
|
let bytes: Vec<u8> = vec![0x5f, 0x00, 0x55];
|
||||||
let bit_stream = ByteStream::from(bytes.clone());
|
let bit_stream = ByteStream::from(bytes.clone());
|
||||||
|
|
||||||
let new_bytes = bit_stream.get_bytes(4, 4).unwrap();
|
let new_bytes = bit_stream.get_bytes::<BigEndian>(4, 4).unwrap();
|
||||||
assert_eq!(vec![0x05], new_bytes);
|
assert_eq!(vec![0x05], new_bytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -112,7 +137,7 @@ mod tests {
|
||||||
let bytes: Vec<u8> = vec![0xff, 0x55];
|
let bytes: Vec<u8> = vec![0xff, 0x55];
|
||||||
let bit_stream = ByteStream::from(bytes.clone());
|
let bit_stream = ByteStream::from(bytes.clone());
|
||||||
|
|
||||||
let new_bytes = bit_stream.get_bytes(4, 8).unwrap();
|
let new_bytes = bit_stream.get_bytes::<BigEndian>(4, 8).unwrap();
|
||||||
assert_eq!(vec![0x5f], new_bytes);
|
assert_eq!(vec![0x5f], new_bytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -121,7 +146,7 @@ mod tests {
|
||||||
let bytes: Vec<u8> = vec![0xff, 0x55];
|
let bytes: Vec<u8> = vec![0xff, 0x55];
|
||||||
let bit_stream = ByteStream::from(bytes.clone());
|
let bit_stream = ByteStream::from(bytes.clone());
|
||||||
|
|
||||||
let new_bytes = bit_stream.get_bytes(7, 2).unwrap();
|
let new_bytes = bit_stream.get_bytes::<BigEndian>(7, 2).unwrap();
|
||||||
assert_eq!(vec![0x03], new_bytes);
|
assert_eq!(vec![0x03], new_bytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -130,7 +155,7 @@ mod tests {
|
||||||
let bytes: Vec<u8> = vec![0xff, 0x55];
|
let bytes: Vec<u8> = vec![0xff, 0x55];
|
||||||
let bit_stream = ByteStream::from(bytes.clone());
|
let bit_stream = ByteStream::from(bytes.clone());
|
||||||
|
|
||||||
let new_bytes = bit_stream.get_bytes(8, 8).unwrap();
|
let new_bytes = bit_stream.get_bytes::<BigEndian>(8, 8).unwrap();
|
||||||
assert_eq!(vec![0x55], new_bytes);
|
assert_eq!(vec![0x55], new_bytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -139,7 +164,7 @@ mod tests {
|
||||||
let bytes: Vec<u8> = vec![0x55];
|
let bytes: Vec<u8> = vec![0x55];
|
||||||
let bit_stream = ByteStream::from(bytes.clone());
|
let bit_stream = ByteStream::from(bytes.clone());
|
||||||
|
|
||||||
let new_bytes = bit_stream.get_bytes(0, 3).unwrap();
|
let new_bytes = bit_stream.get_bytes::<BigEndian>(0, 3).unwrap();
|
||||||
assert_eq!(vec![0x05], new_bytes);
|
assert_eq!(vec![0x05], new_bytes);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,6 +13,10 @@ pub trait LastByte: ByteOrder {
|
||||||
fn big_int(buf: &[u8]) -> BigInt;
|
fn big_int(buf: &[u8]) -> BigInt;
|
||||||
|
|
||||||
fn big_uint(buf: &[u8]) -> BigUint;
|
fn big_uint(buf: &[u8]) -> BigUint;
|
||||||
|
|
||||||
|
fn big_u_int_to_bytes(big_int: BigUint) -> Vec<u8>;
|
||||||
|
|
||||||
|
fn big_int_to_bytes(big_int: BigInt) -> Vec<u8>;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl LastByte for BigEndian {
|
impl LastByte for BigEndian {
|
||||||
|
@ -27,6 +31,14 @@ impl LastByte for BigEndian {
|
||||||
fn big_uint(buf: &[u8]) -> BigUint {
|
fn big_uint(buf: &[u8]) -> BigUint {
|
||||||
BigUint::from_bytes_be(buf)
|
BigUint::from_bytes_be(buf)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn big_u_int_to_bytes(big_int: BigUint) -> Vec<u8> {
|
||||||
|
big_int.to_bytes_be()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn big_int_to_bytes(big_int: BigInt) -> Vec<u8> {
|
||||||
|
big_int.to_signed_bytes_be()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl LastByte for LittleEndian {
|
impl LastByte for LittleEndian {
|
||||||
|
@ -41,6 +53,14 @@ impl LastByte for LittleEndian {
|
||||||
fn big_uint(buf: &[u8]) -> BigUint {
|
fn big_uint(buf: &[u8]) -> BigUint {
|
||||||
BigUint::from_bytes_le(buf)
|
BigUint::from_bytes_le(buf)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn big_u_int_to_bytes(big_int: BigUint) -> Vec<u8> {
|
||||||
|
big_int.to_bytes_le()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn big_int_to_bytes(big_int: BigInt) -> Vec<u8> {
|
||||||
|
big_int.to_signed_bytes_le()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
|
@ -79,25 +99,31 @@ pub enum FieldType {
|
||||||
/// Unsigned Int
|
/// Unsigned Int
|
||||||
UInt {
|
UInt {
|
||||||
bit_width: usize,
|
bit_width: usize,
|
||||||
endianness: BigEndianness,
|
endianness: Endianness,
|
||||||
},
|
},
|
||||||
/// Unsigned Int
|
/// Unsigned Int
|
||||||
Int {
|
Int {
|
||||||
bit_width: usize,
|
bit_width: usize,
|
||||||
endianness: BigEndianness,
|
endianness: Endianness,
|
||||||
},
|
},
|
||||||
/// Single Precession Float
|
/// Single Precession Float
|
||||||
Float { endianness: BigEndianness },
|
Float { endianness: Endianness },
|
||||||
/// Double Precession Float
|
/// Double Precession Float
|
||||||
Double { endianness: BigEndianness },
|
Double { endianness: Endianness },
|
||||||
/// Null Terminated String Field
|
/// Null Terminated String Field
|
||||||
String { max_len: usize },
|
String {
|
||||||
|
max_len: usize,
|
||||||
|
endianness: Endianness,
|
||||||
|
},
|
||||||
/// Fixed Byte Length Field
|
/// Fixed Byte Length Field
|
||||||
Bytes { max_len: usize },
|
Bytes {
|
||||||
|
max_len: usize,
|
||||||
|
endianness: Endianness,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Deserialize, Clone, PartialOrd, PartialEq, Copy)]
|
#[derive(Debug, Deserialize, Clone, PartialOrd, PartialEq, Copy)]
|
||||||
pub enum BigEndianness {
|
pub enum Endianness {
|
||||||
LittleEndian,
|
LittleEndian,
|
||||||
BigEndian,
|
BigEndian,
|
||||||
}
|
}
|
||||||
|
@ -108,8 +134,8 @@ pub struct Field {
|
||||||
pub name: String,
|
pub name: String,
|
||||||
/// Field Type
|
/// Field Type
|
||||||
pub field_type: FieldType,
|
pub field_type: FieldType,
|
||||||
/// Flip Bit Border
|
/// Flip Bit Order
|
||||||
pub flip_bit_order: Option<bool>,
|
pub bit_flip: Option<bool>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Field {
|
impl Field {
|
||||||
|
@ -118,7 +144,7 @@ impl Field {
|
||||||
bit_ndx: usize,
|
bit_ndx: usize,
|
||||||
bit_width: usize,
|
bit_width: usize,
|
||||||
) -> Result<(String, usize), FormatError> {
|
) -> Result<(String, usize), FormatError> {
|
||||||
let mut bytes = byte_stream.get_bytes(bit_ndx, bit_width)?;
|
let mut bytes = byte_stream.get_bytes::<T>(bit_ndx, bit_width)?;
|
||||||
|
|
||||||
if let Some(last_byte) = T::last_byte(&mut bytes) {
|
if let Some(last_byte) = T::last_byte(&mut bytes) {
|
||||||
let last_bit = ((bit_width - 1) % 8) as u8;
|
let last_bit = ((bit_width - 1) % 8) as u8;
|
||||||
|
@ -142,7 +168,7 @@ impl Field {
|
||||||
bit_ndx: usize,
|
bit_ndx: usize,
|
||||||
bit_width: usize,
|
bit_width: usize,
|
||||||
) -> Result<(String, usize), FormatError> {
|
) -> Result<(String, usize), FormatError> {
|
||||||
let bytes = byte_stream.get_bytes(bit_ndx, bit_width)?;
|
let bytes = byte_stream.get_bytes::<T>(bit_ndx, bit_width)?;
|
||||||
|
|
||||||
let big_int = T::big_uint(&bytes);
|
let big_int = T::big_uint(&bytes);
|
||||||
Ok((big_int.to_string(), bit_width))
|
Ok((big_int.to_string(), bit_width))
|
||||||
|
@ -152,7 +178,7 @@ impl Field {
|
||||||
byte_stream: &ByteStream,
|
byte_stream: &ByteStream,
|
||||||
bit_ndx: usize,
|
bit_ndx: usize,
|
||||||
) -> Result<(String, usize), FormatError> {
|
) -> Result<(String, usize), FormatError> {
|
||||||
let bytes = byte_stream.get_bytes(bit_ndx, 32)?;
|
let bytes = byte_stream.get_bytes::<T>(bit_ndx, 32)?;
|
||||||
let mut cursor = Cursor::new(bytes);
|
let mut cursor = Cursor::new(bytes);
|
||||||
|
|
||||||
Ok((cursor.read_f32::<T>().unwrap().to_string(), 4))
|
Ok((cursor.read_f32::<T>().unwrap().to_string(), 4))
|
||||||
|
@ -162,13 +188,13 @@ impl Field {
|
||||||
byte_stream: &ByteStream,
|
byte_stream: &ByteStream,
|
||||||
bit_ndx: usize,
|
bit_ndx: usize,
|
||||||
) -> Result<(String, usize), FormatError> {
|
) -> Result<(String, usize), FormatError> {
|
||||||
let bytes = byte_stream.get_bytes(bit_ndx, 64)?;
|
let bytes = byte_stream.get_bytes::<T>(bit_ndx, 64)?;
|
||||||
let mut cursor = Cursor::new(bytes);
|
let mut cursor = Cursor::new(bytes);
|
||||||
|
|
||||||
Ok((cursor.read_f64::<T>().unwrap().to_string(), 4))
|
Ok((cursor.read_f64::<T>().unwrap().to_string(), 4))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn format_string(
|
fn format_string<T: LastByte>(
|
||||||
byte_stream: &ByteStream,
|
byte_stream: &ByteStream,
|
||||||
mut bit_ndx: usize,
|
mut bit_ndx: usize,
|
||||||
max_byte_len: usize,
|
max_byte_len: usize,
|
||||||
|
@ -176,7 +202,7 @@ impl Field {
|
||||||
let mut string_bytes = Vec::new();
|
let mut string_bytes = Vec::new();
|
||||||
|
|
||||||
for _ in 0..max_byte_len {
|
for _ in 0..max_byte_len {
|
||||||
let byte = byte_stream.get_bytes(bit_ndx, 8)?[0];
|
let byte = byte_stream.get_bytes::<T>(bit_ndx, 8)?[0];
|
||||||
|
|
||||||
if byte == 0 {
|
if byte == 0 {
|
||||||
break;
|
break;
|
||||||
|
@ -190,7 +216,7 @@ impl Field {
|
||||||
Ok((String::from_utf8(string_bytes)?, byte_count))
|
Ok((String::from_utf8(string_bytes)?, byte_count))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn format_bytes(
|
fn format_bytes<T: LastByte>(
|
||||||
byte_stream: &ByteStream,
|
byte_stream: &ByteStream,
|
||||||
bit_ndx: usize,
|
bit_ndx: usize,
|
||||||
max_byte_len: usize,
|
max_byte_len: usize,
|
||||||
|
@ -203,25 +229,31 @@ impl Field {
|
||||||
data_remaining * 8
|
data_remaining * 8
|
||||||
};
|
};
|
||||||
|
|
||||||
let data = byte_stream.get_bytes(bit_ndx, width)?;
|
let data = byte_stream.get_bytes::<T>(bit_ndx, width)?;
|
||||||
|
|
||||||
Ok((print_bytes_as_array(&data), width))
|
Ok((print_bytes_as_array(&data), width))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn format_data(
|
fn format_data(
|
||||||
&self,
|
&self,
|
||||||
byte_stream: &ByteStream,
|
byte_stream: &mut ByteStream,
|
||||||
bit_ndx: usize,
|
bit_ndx: usize,
|
||||||
) -> Result<(String, usize), FormatError> {
|
) -> Result<(String, usize), FormatError> {
|
||||||
match self.field_type {
|
let global_bit_flip = byte_stream.get_reverse_bits();
|
||||||
|
|
||||||
|
if let Some(bit_flip) = self.bit_flip {
|
||||||
|
byte_stream.set_reverse_bits(bit_flip);
|
||||||
|
}
|
||||||
|
|
||||||
|
let fmt = match self.field_type {
|
||||||
FieldType::UInt {
|
FieldType::UInt {
|
||||||
bit_width,
|
bit_width,
|
||||||
endianness,
|
endianness,
|
||||||
} => match endianness {
|
} => match endianness {
|
||||||
BigEndianness::LittleEndian => {
|
Endianness::LittleEndian => {
|
||||||
Self::format_uint::<LittleEndian>(byte_stream, bit_ndx, bit_width)
|
Self::format_uint::<LittleEndian>(byte_stream, bit_ndx, bit_width)
|
||||||
}
|
}
|
||||||
BigEndianness::BigEndian => {
|
Endianness::BigEndian => {
|
||||||
Self::format_uint::<BigEndian>(byte_stream, bit_ndx, bit_width)
|
Self::format_uint::<BigEndian>(byte_stream, bit_ndx, bit_width)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -229,28 +261,52 @@ impl Field {
|
||||||
bit_width,
|
bit_width,
|
||||||
endianness,
|
endianness,
|
||||||
} => match endianness {
|
} => match endianness {
|
||||||
BigEndianness::LittleEndian => {
|
Endianness::LittleEndian => {
|
||||||
Self::format_int::<LittleEndian>(byte_stream, bit_ndx, bit_width)
|
Self::format_int::<LittleEndian>(byte_stream, bit_ndx, bit_width)
|
||||||
}
|
}
|
||||||
BigEndianness::BigEndian => {
|
Endianness::BigEndian => {
|
||||||
Self::format_int::<BigEndian>(byte_stream, bit_ndx, bit_width)
|
Self::format_int::<BigEndian>(byte_stream, bit_ndx, bit_width)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
FieldType::Float { endianness } => match endianness {
|
FieldType::Float { endianness } => match endianness {
|
||||||
BigEndianness::LittleEndian => {
|
Endianness::LittleEndian => {
|
||||||
Self::format_float::<LittleEndian>(byte_stream, bit_ndx)
|
Self::format_float::<LittleEndian>(byte_stream, bit_ndx)
|
||||||
}
|
}
|
||||||
BigEndianness::BigEndian => Self::format_float::<BigEndian>(byte_stream, bit_ndx),
|
Endianness::BigEndian => Self::format_float::<BigEndian>(byte_stream, bit_ndx),
|
||||||
},
|
},
|
||||||
FieldType::Double { endianness } => match endianness {
|
FieldType::Double { endianness } => match endianness {
|
||||||
BigEndianness::LittleEndian => {
|
Endianness::LittleEndian => {
|
||||||
Self::format_double::<LittleEndian>(byte_stream, bit_ndx)
|
Self::format_double::<LittleEndian>(byte_stream, bit_ndx)
|
||||||
}
|
}
|
||||||
BigEndianness::BigEndian => Self::format_double::<BigEndian>(byte_stream, bit_ndx),
|
Endianness::BigEndian => Self::format_double::<BigEndian>(byte_stream, bit_ndx),
|
||||||
},
|
},
|
||||||
FieldType::String { max_len } => Self::format_string(byte_stream, bit_ndx, max_len),
|
FieldType::String {
|
||||||
FieldType::Bytes { max_len } => Self::format_bytes(byte_stream, bit_ndx, max_len),
|
max_len,
|
||||||
}
|
endianness,
|
||||||
|
} => match endianness {
|
||||||
|
Endianness::LittleEndian => {
|
||||||
|
Self::format_string::<LittleEndian>(byte_stream, bit_ndx, max_len)
|
||||||
|
}
|
||||||
|
Endianness::BigEndian => {
|
||||||
|
Self::format_string::<LittleEndian>(byte_stream, bit_ndx, max_len)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
FieldType::Bytes {
|
||||||
|
max_len,
|
||||||
|
endianness,
|
||||||
|
} => match endianness {
|
||||||
|
Endianness::LittleEndian => {
|
||||||
|
Self::format_bytes::<LittleEndian>(byte_stream, bit_ndx, max_len)
|
||||||
|
}
|
||||||
|
Endianness::BigEndian => {
|
||||||
|
Self::format_bytes::<LittleEndian>(byte_stream, bit_ndx, max_len)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}?;
|
||||||
|
|
||||||
|
byte_stream.set_reverse_bits(global_bit_flip);
|
||||||
|
|
||||||
|
Ok(fmt)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -267,11 +323,13 @@ pub struct Format {
|
||||||
impl Format {
|
impl Format {
|
||||||
pub fn format_data(&self, data: &[u8]) -> Result<String, FormatError> {
|
pub fn format_data(&self, data: &[u8]) -> Result<String, FormatError> {
|
||||||
let mut format_str = String::new();
|
let mut format_str = String::new();
|
||||||
let byte_stream = ByteStream::from(data);
|
let mut byte_stream = ByteStream::from(data);
|
||||||
let mut bit_ndx: usize = 0;
|
let mut bit_ndx: usize = 0;
|
||||||
|
|
||||||
|
byte_stream.set_reverse_bits(self.bit_flip);
|
||||||
|
|
||||||
for field in &self.fields {
|
for field in &self.fields {
|
||||||
match field.format_data(&byte_stream, bit_ndx) {
|
match field.format_data(&mut byte_stream, bit_ndx) {
|
||||||
Ok((data_str, bit_width)) => {
|
Ok((data_str, bit_width)) => {
|
||||||
bit_ndx += bit_width;
|
bit_ndx += bit_width;
|
||||||
writeln!(format_str, "{}: {}", field.name, data_str).unwrap();
|
writeln!(format_str, "{}: {}", field.name, data_str).unwrap();
|
||||||
|
@ -290,17 +348,17 @@ impl Format {
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use crate::byte_stream::ByteStream;
|
use crate::byte_stream::ByteStream;
|
||||||
use crate::formatter::format::{BigEndianness, Field, FieldType};
|
use crate::formatter::format::{Endianness, Field, FieldType};
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_format_int_4_bits() {
|
fn test_format_int_4_bits() {
|
||||||
let field = Field {
|
let field = Field {
|
||||||
field_type: FieldType::Int {
|
field_type: FieldType::Int {
|
||||||
bit_width: 4,
|
bit_width: 4,
|
||||||
endianness: BigEndianness::LittleEndian,
|
endianness: Endianness::LittleEndian,
|
||||||
},
|
},
|
||||||
name: "test".to_string(),
|
name: "test".to_string(),
|
||||||
flip_bit_order: None,
|
bit_flip: None,
|
||||||
};
|
};
|
||||||
|
|
||||||
for i in 0i8..7i8 {
|
for i in 0i8..7i8 {
|
||||||
|
@ -322,10 +380,10 @@ mod tests {
|
||||||
let field = Field {
|
let field = Field {
|
||||||
field_type: FieldType::Int {
|
field_type: FieldType::Int {
|
||||||
bit_width: 5,
|
bit_width: 5,
|
||||||
endianness: BigEndianness::LittleEndian,
|
endianness: Endianness::LittleEndian,
|
||||||
},
|
},
|
||||||
name: "test".to_string(),
|
name: "test".to_string(),
|
||||||
flip_bit_order: None,
|
bit_flip: None,
|
||||||
};
|
};
|
||||||
let byte_steam = ByteStream::from(vec![0x1B]);
|
let byte_steam = ByteStream::from(vec![0x1B]);
|
||||||
let (output, _) = field.format_data(&byte_steam, 0).unwrap();
|
let (output, _) = field.format_data(&byte_steam, 0).unwrap();
|
||||||
|
@ -338,10 +396,10 @@ mod tests {
|
||||||
let field = Field {
|
let field = Field {
|
||||||
field_type: FieldType::Int {
|
field_type: FieldType::Int {
|
||||||
bit_width: 16,
|
bit_width: 16,
|
||||||
endianness: BigEndianness::LittleEndian,
|
endianness: Endianness::LittleEndian,
|
||||||
},
|
},
|
||||||
name: "test".to_string(),
|
name: "test".to_string(),
|
||||||
flip_bit_order: None,
|
bit_flip: None,
|
||||||
};
|
};
|
||||||
|
|
||||||
let byte_steam = ByteStream::from(vec![0xFC, 0xA5]);
|
let byte_steam = ByteStream::from(vec![0xFC, 0xA5]);
|
||||||
|
@ -355,10 +413,10 @@ mod tests {
|
||||||
let field = Field {
|
let field = Field {
|
||||||
field_type: FieldType::Int {
|
field_type: FieldType::Int {
|
||||||
bit_width: 16,
|
bit_width: 16,
|
||||||
endianness: BigEndianness::LittleEndian,
|
endianness: Endianness::LittleEndian,
|
||||||
},
|
},
|
||||||
name: "test".to_string(),
|
name: "test".to_string(),
|
||||||
flip_bit_order: None,
|
bit_flip: None,
|
||||||
};
|
};
|
||||||
|
|
||||||
let byte_steam = ByteStream::from(vec![0xC0, 0x5F, 0x0A]);
|
let byte_steam = ByteStream::from(vec![0xC0, 0x5F, 0x0A]);
|
||||||
|
@ -371,10 +429,10 @@ mod tests {
|
||||||
fn test_format_float() {
|
fn test_format_float() {
|
||||||
let field = Field {
|
let field = Field {
|
||||||
field_type: FieldType::Float {
|
field_type: FieldType::Float {
|
||||||
endianness: BigEndianness::LittleEndian,
|
endianness: Endianness::LittleEndian,
|
||||||
},
|
},
|
||||||
name: "test".to_string(),
|
name: "test".to_string(),
|
||||||
flip_bit_order: None,
|
bit_flip: None,
|
||||||
};
|
};
|
||||||
|
|
||||||
let byte_steam = ByteStream::from(b"\x52\x58\xd2\xc3".to_vec());
|
let byte_steam = ByteStream::from(b"\x52\x58\xd2\xc3".to_vec());
|
||||||
|
@ -387,10 +445,10 @@ mod tests {
|
||||||
fn test_format_double() {
|
fn test_format_double() {
|
||||||
let field = Field {
|
let field = Field {
|
||||||
field_type: FieldType::Double {
|
field_type: FieldType::Double {
|
||||||
endianness: BigEndianness::LittleEndian,
|
endianness: Endianness::LittleEndian,
|
||||||
},
|
},
|
||||||
name: "test".to_string(),
|
name: "test".to_string(),
|
||||||
flip_bit_order: None,
|
bit_flip: None,
|
||||||
};
|
};
|
||||||
|
|
||||||
let byte_steam = ByteStream::from(b"\xD7\xA3\x70\x3D\x0A\x4B\x7A\xC0".to_vec());
|
let byte_steam = ByteStream::from(b"\xD7\xA3\x70\x3D\x0A\x4B\x7A\xC0".to_vec());
|
||||||
|
@ -403,10 +461,10 @@ mod tests {
|
||||||
fn test_format_float_err() {
|
fn test_format_float_err() {
|
||||||
let field = Field {
|
let field = Field {
|
||||||
field_type: FieldType::Double {
|
field_type: FieldType::Double {
|
||||||
endianness: BigEndianness::LittleEndian,
|
endianness: Endianness::LittleEndian,
|
||||||
},
|
},
|
||||||
name: "test".to_string(),
|
name: "test".to_string(),
|
||||||
flip_bit_order: None,
|
bit_flip: None,
|
||||||
};
|
};
|
||||||
|
|
||||||
let byte_steam = ByteStream::from(b"\x3D\x70\xA3\xD7".to_vec());
|
let byte_steam = ByteStream::from(b"\x3D\x70\xA3\xD7".to_vec());
|
||||||
|
@ -419,7 +477,7 @@ mod tests {
|
||||||
let field = Field {
|
let field = Field {
|
||||||
field_type: FieldType::String { max_len: 16 },
|
field_type: FieldType::String { max_len: 16 },
|
||||||
name: "test".to_string(),
|
name: "test".to_string(),
|
||||||
flip_bit_order: None,
|
bit_flip: None,
|
||||||
};
|
};
|
||||||
|
|
||||||
let byte_steam = ByteStream::from(b"Hello World!\0".to_vec());
|
let byte_steam = ByteStream::from(b"Hello World!\0".to_vec());
|
||||||
|
@ -434,7 +492,7 @@ mod tests {
|
||||||
let field = Field {
|
let field = Field {
|
||||||
field_type: FieldType::Bytes { max_len: 2 },
|
field_type: FieldType::Bytes { max_len: 2 },
|
||||||
name: "test".to_string(),
|
name: "test".to_string(),
|
||||||
flip_bit_order: None,
|
bit_flip: None,
|
||||||
};
|
};
|
||||||
|
|
||||||
let byte_steam = ByteStream::from(vec![0xDE, 0xAD, 0xBE, 0xEF]);
|
let byte_steam = ByteStream::from(vec![0xDE, 0xAD, 0xBE, 0xEF]);
|
||||||
|
@ -449,7 +507,7 @@ mod tests {
|
||||||
let field = Field {
|
let field = Field {
|
||||||
field_type: FieldType::Bytes { max_len: 64 },
|
field_type: FieldType::Bytes { max_len: 64 },
|
||||||
name: "test".to_string(),
|
name: "test".to_string(),
|
||||||
flip_bit_order: None,
|
bit_flip: None,
|
||||||
};
|
};
|
||||||
|
|
||||||
let byte_steam = ByteStream::from(vec![0xDE, 0xAD]);
|
let byte_steam = ByteStream::from(vec![0xDE, 0xAD]);
|
||||||
|
@ -464,10 +522,10 @@ mod tests {
|
||||||
let field = Field {
|
let field = Field {
|
||||||
field_type: FieldType::UInt {
|
field_type: FieldType::UInt {
|
||||||
bit_width: 11,
|
bit_width: 11,
|
||||||
endianness: BigEndianness::LittleEndian,
|
endianness: Endianness::LittleEndian,
|
||||||
},
|
},
|
||||||
name: "test".to_string(),
|
name: "test".to_string(),
|
||||||
flip_bit_order: None,
|
bit_flip: None,
|
||||||
};
|
};
|
||||||
|
|
||||||
let byte_steam = ByteStream::from(vec![
|
let byte_steam = ByteStream::from(vec![
|
||||||
|
|
Loading…
Reference in New Issue