Cleared up issue with parsing ints
+ Endianness was all out of whack + Everything is currently handled as little endian, easy to add a config for endianness later + num-bigint comes in clutch, it now handles the shifting of bitspull/1/head
parent
6daf3a55f2
commit
bb6f331c75
|
@ -3,7 +3,7 @@
|
||||||
# Ref: https://public.ccsds.org/Pubs/133x0b2e1.pdfa
|
# Ref: https://public.ccsds.org/Pubs/133x0b2e1.pdfa
|
||||||
#
|
#
|
||||||
# Example Packet:
|
# Example Packet:
|
||||||
# [0x08, 0x55, 0xc0, 0x00, 0x00, 0x05, 0x01, 0x02, 0x03, 0x04, 0x05]
|
# [0xe0, 0xa1, 0xc0, 0x00, 0x05, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05]
|
||||||
|
|
||||||
[[formats]]
|
[[formats]]
|
||||||
name = "ccsds"
|
name = "ccsds"
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
use std::fmt::{Display, Formatter};
|
use std::fmt::{Display, Formatter};
|
||||||
|
use num_bigint::BigUint;
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub enum ByteStreamError {
|
pub enum ByteStreamError {
|
||||||
|
@ -32,13 +33,14 @@ pub struct ByteStream {
|
||||||
data: Vec<u8>,
|
data: Vec<u8>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
impl ByteStream {
|
impl ByteStream {
|
||||||
pub fn get_bytes(&self, bit_ndx: usize, bit_count: usize) -> Result<Vec<u8>, ByteStreamError> {
|
pub fn get_bytes(&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;
|
||||||
let byte_count = if bit_count >= 8 { bit_count / 8 } else { 1 };
|
let byte_count = ((bit_count as f32) / (8.0)).ceil() as usize;
|
||||||
let bytes_needed = if bits_before != 0 {
|
let bytes_needed = if (bits_before as usize + bit_count) % 8 != 0 && !(bits_before as usize + bit_count < 8){
|
||||||
byte_count + 1
|
byte_count + 1
|
||||||
} else {
|
} else {
|
||||||
byte_count
|
byte_count
|
||||||
|
@ -48,21 +50,13 @@ impl ByteStream {
|
||||||
return Err(ByteStreamError::OutOfRange);
|
return Err(ByteStreamError::OutOfRange);
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut byte_stream = self.data[byte_ndx..byte_ndx + bytes_needed].to_vec();
|
let byte_stream = self.data[byte_ndx..byte_ndx + bytes_needed].to_vec();
|
||||||
|
|
||||||
if bits_before != 0 {
|
let number = BigUint::from_bytes_le(&byte_stream) >> bits_before;
|
||||||
let mut carry: u8 = 0;
|
|
||||||
for _ in 0..bits_before {
|
|
||||||
for k in (0..bytes_needed).rev() {
|
|
||||||
let next: u8 = (byte_stream[k] & 0x01) << 7;
|
|
||||||
byte_stream[k] = (byte_stream[k] >> 1) | carry;
|
|
||||||
|
|
||||||
carry = next;
|
let mut byte_stream = number.to_bytes_le();
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if bytes_needed > byte_count {
|
if bytes_needed > byte_count && bytes_needed == byte_stream.len() {
|
||||||
byte_stream.pop();
|
byte_stream.pop();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -105,11 +99,11 @@ mod tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_get_bytes_with_shift_in_byte() {
|
fn test_get_bytes_with_shift_in_byte() {
|
||||||
let bytes: Vec<u8> = vec![0xff, 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(4, 4).unwrap();
|
||||||
assert_eq!(vec![0x0f], new_bytes);
|
assert_eq!(vec![0x05], new_bytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|
|
@ -3,7 +3,7 @@ use serde::Deserialize;
|
||||||
use std::fmt::{Write, Display, Formatter};
|
use std::fmt::{Write, Display, Formatter};
|
||||||
use num_bigint::{BigUint, BigInt};
|
use num_bigint::{BigUint, BigInt};
|
||||||
use std::io::Cursor;
|
use std::io::Cursor;
|
||||||
use byteorder::{BigEndian, ReadBytesExt};
|
use byteorder::{LittleEndian, ReadBytesExt};
|
||||||
use std::string::FromUtf8Error;
|
use std::string::FromUtf8Error;
|
||||||
use crate::formatter::printers::print_bytes_as_array;
|
use crate::formatter::printers::print_bytes_as_array;
|
||||||
|
|
||||||
|
@ -75,7 +75,7 @@ impl Field {
|
||||||
*last_byte |= !bit_mask(last_bit + 1)
|
*last_byte |= !bit_mask(last_bit + 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
let big_int = BigInt::from_signed_bytes_be(&bytes);
|
let big_int = BigInt::from_signed_bytes_le(&bytes);
|
||||||
|
|
||||||
Ok((big_int.to_string(), bit_width))
|
Ok((big_int.to_string(), bit_width))
|
||||||
}
|
}
|
||||||
|
@ -87,7 +87,7 @@ impl Field {
|
||||||
fn format_uint(byte_stream: &ByteStream, bit_ndx: usize, bit_width: usize) -> Result<(String, usize), FormatError> {
|
fn format_uint(byte_stream: &ByteStream, bit_ndx: usize, bit_width: usize) -> Result<(String, usize), FormatError> {
|
||||||
let bytes = byte_stream.get_bytes(bit_ndx, bit_width)?;
|
let bytes = byte_stream.get_bytes(bit_ndx, bit_width)?;
|
||||||
|
|
||||||
let big_int = BigUint::from_bytes_be(&bytes);
|
let big_int = BigUint::from_bytes_le(&bytes);
|
||||||
Ok((big_int.to_string(), bit_width))
|
Ok((big_int.to_string(), bit_width))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -95,14 +95,14 @@ impl Field {
|
||||||
let bytes = byte_stream.get_bytes(bit_ndx, 32)?;
|
let bytes = byte_stream.get_bytes(bit_ndx, 32)?;
|
||||||
let mut cursor = Cursor::new(bytes);
|
let mut cursor = Cursor::new(bytes);
|
||||||
|
|
||||||
Ok((cursor.read_f32::<BigEndian>().unwrap().to_string(), 4))
|
Ok((cursor.read_f32::<LittleEndian>().unwrap().to_string(), 4))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn format_double(byte_stream: &ByteStream, bit_ndx: usize) -> Result<(String, usize), FormatError> {
|
fn format_double(byte_stream: &ByteStream, bit_ndx: usize) -> Result<(String, usize), FormatError> {
|
||||||
let bytes = byte_stream.get_bytes(bit_ndx, 64)?;
|
let bytes = byte_stream.get_bytes(bit_ndx, 64)?;
|
||||||
let mut cursor = Cursor::new(bytes);
|
let mut cursor = Cursor::new(bytes);
|
||||||
|
|
||||||
Ok((cursor.read_f64::<BigEndian>().unwrap().to_string(), 4))
|
Ok((cursor.read_f64::<LittleEndian>().unwrap().to_string(), 4))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn format_string(byte_stream: &ByteStream, mut bit_ndx: usize, max_byte_len: usize) -> Result<(String, usize), FormatError> {
|
fn format_string(byte_stream: &ByteStream, mut bit_ndx: usize, max_byte_len: usize) -> Result<(String, usize), FormatError> {
|
||||||
|
@ -218,7 +218,7 @@ mod tests {
|
||||||
let field = Field {field_type: FieldType::Int {bit_width: 16,}, name: "test".to_string()};
|
let field = Field {field_type: FieldType::Int {bit_width: 16,}, name: "test".to_string()};
|
||||||
|
|
||||||
|
|
||||||
let byte_steam = ByteStream::from(vec![0xA5, 0xFC]);
|
let byte_steam = ByteStream::from(vec![0xFC, 0xA5]);
|
||||||
let (output, _) = field.format_data(&byte_steam, 0).unwrap();
|
let (output, _) = field.format_data(&byte_steam, 0).unwrap();
|
||||||
|
|
||||||
assert_eq!(output, "-23044")
|
assert_eq!(output, "-23044")
|
||||||
|
@ -229,7 +229,7 @@ mod tests {
|
||||||
let field = Field {field_type: FieldType::Int {bit_width: 16,}, name: "test".to_string()};
|
let field = Field {field_type: FieldType::Int {bit_width: 16,}, name: "test".to_string()};
|
||||||
|
|
||||||
|
|
||||||
let byte_steam = ByteStream::from(vec![0x50, 0xCA, 0x0F]);
|
let byte_steam = ByteStream::from(vec![0xC0, 0x5F, 0x0A]);
|
||||||
let (output, _) = field.format_data(&byte_steam, 4).unwrap();
|
let (output, _) = field.format_data(&byte_steam, 4).unwrap();
|
||||||
|
|
||||||
assert_eq!(output, "-23044")
|
assert_eq!(output, "-23044")
|
||||||
|
@ -239,7 +239,7 @@ mod tests {
|
||||||
fn test_format_float() {
|
fn test_format_float() {
|
||||||
let field = Field {field_type: FieldType::Float, name: "test".to_string()};
|
let field = Field {field_type: FieldType::Float, name: "test".to_string()};
|
||||||
|
|
||||||
let byte_steam = ByteStream::from(b"\xc3\xd2\x58\x52".to_vec());
|
let byte_steam = ByteStream::from(b"\x52\x58\xd2\xc3".to_vec());
|
||||||
let (output, _) = field.format_data(&byte_steam, 0).unwrap();
|
let (output, _) = field.format_data(&byte_steam, 0).unwrap();
|
||||||
|
|
||||||
assert_eq!(output, "-420.69")
|
assert_eq!(output, "-420.69")
|
||||||
|
@ -249,7 +249,7 @@ mod tests {
|
||||||
fn test_format_double() {
|
fn test_format_double() {
|
||||||
let field = Field {field_type: FieldType::Double, name: "test".to_string()};
|
let field = Field {field_type: FieldType::Double, name: "test".to_string()};
|
||||||
|
|
||||||
let byte_steam = ByteStream::from(b"\xC0\x7A\x4B\x0A\x3D\x70\xA3\xD7".to_vec());
|
let byte_steam = ByteStream::from(b"\xD7\xA3\x70\x3D\x0A\x4B\x7A\xC0".to_vec());
|
||||||
let (output, _) = field.format_data(&byte_steam, 0).unwrap();
|
let (output, _) = field.format_data(&byte_steam, 0).unwrap();
|
||||||
|
|
||||||
assert_eq!(output, "-420.69")
|
assert_eq!(output, "-420.69")
|
||||||
|
@ -296,4 +296,15 @@ mod tests {
|
||||||
|
|
||||||
assert_eq!(output, "[222, 173]")
|
assert_eq!(output, "[222, 173]")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_ccsds_apid_issue() {
|
||||||
|
let field = Field {field_type: FieldType::UInt {bit_width: 11}, name: "test".to_string()};
|
||||||
|
|
||||||
|
let byte_steam = ByteStream::from(vec![0xe0, 0xa1, 0xc0, 0x00, 0x05, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05]);
|
||||||
|
|
||||||
|
let (output, _) = field.format_data(&byte_steam, 5).unwrap();
|
||||||
|
|
||||||
|
assert_eq!(output, "1295")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue