Skip to content

Commit

Permalink
Parse DAF/SPK file record
Browse files Browse the repository at this point in the history
  • Loading branch information
matzipan committed Mar 12, 2023
1 parent 374ad55 commit a5ab074
Show file tree
Hide file tree
Showing 4 changed files with 227 additions and 0 deletions.
1 change: 1 addition & 0 deletions crates/lox_core/src/ephemeris/daf_spk/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
pub mod parser;
224 changes: 224 additions & 0 deletions crates/lox_core/src/ephemeris/daf_spk/parser.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,224 @@
#[derive(Debug, PartialEq)]
pub struct FileRecord {
pub locidw: String,
pub nd: u32,
pub ni: u32,
pub locifn: String,
pub fward: u32,
pub bward: u32,
pub free: u32,
pub locfmt: String,
pub prenul: Vec<u8>,
pub ftpstr: Vec<u8>,
pub pstnul: Vec<u8>,
}

pub fn parse_file_record<'a>(input: &'a [u8]) -> nom::IResult<&[u8], FileRecord> {
// 1. LOCIDW (8 charactersu8, 8 bytes): An identification word (`DAF/xxxx').
// The 'xxxx' substring is a string of four characters or less indicating the
// type of data stored in the DAF file. This is used by the SPICELIB
// subroutines to verify that a particular file is in fact a DAF and not
// merely a direct access file with the same record length. When
// a DAF is openedu8, an error signals if this keyword is not present. [Address
// 0]
let (input, locidw) = nom::bytes::complete::take(8u32)(input)?;

// 2. ND ( 1 integeru8, 4 bytes): The number of double precision components in
// each array summary. [Address 8]
let (input, nd) = nom::number::complete::le_u32(input)?;

// 3. NI ( 1 integeru8, 4 bytes): The number of integer components in each array
// summary. [Address 12]
let (input, ni) = nom::number::complete::le_u32(input)?;

// 4. LOCIFN (60 charactersu8, 60 bytes): The internal name or description of
// the array file. [Address 16]
let (input, locifn) = nom::bytes::complete::take(60u32)(input)?;

// 5. FWARD ( 1 integeru8, 4 bytes): The record number of the initial summary
// record in the file. [Address 76]
let (input, fward) = nom::number::complete::le_u32(input)?;

// 6. BWARD ( 1 integeru8, 4 bytes): The record number of the final summary
// record in the file. [Address 80]
let (input, bward) = nom::number::complete::le_u32(input)?;

// 7. FREE ( 1 integeru8, 4 bytes): The first free address in the file. This is
// the address at which the first element of the next array to be added to
// the file will be stored. [Address 84]
let (input, free) = nom::number::complete::le_u32(input)?;

// 8. LOCFMT ( 8 charactersu8, 8 bytes): The character string that indicates the
// numeric binary format of the DAF. The string has value either "LTL-IEEE"
// or "BIG-IEEE." [Address 88]
let (input, locfmt) = nom::bytes::complete::take(8u32)(input)?;

// 9. PRENUL ( 603 charactersu8, 603 bytes): A block of nulls to pad between the
// last character of LOCFMT and the first character of FTPSTR to keep FTPSTR
// at character 700 (address 699) in a 1024 byte record. [Address 96]
let (input, prenul) = nom::bytes::complete::take(603u32)(input)?;

// 10. FTPSTR ( 28 charactersu8, 28 bytes): The FTP validation string.
// This string is assembled using components returned from the SPICELIB private
// routine ZZFTPSTR. [Address 699]
let (input, ftpstr) = nom::bytes::complete::take(28u32)(input)?;

// 11. PSTNUL ( 297 charactersu8, 297 bytes): A block of nulls to pad from the
// last character of FTPSTR to the end of the file record. Note: this value
// enforces the length of the file record as 1024 bytes. [Address 727]
let (input, pstnul) = nom::bytes::complete::take(297u32)(input)?;

// We know the loc strings are ASCII in the spec, so parsing them as utf-8
// should be safe.
Ok((
input,
FileRecord {
locidw: String::from_utf8_lossy(locidw).trim().to_string(),
nd,
ni,
locifn: String::from_utf8_lossy(locifn).trim().to_string(),
fward,
bward,
free,
locfmt: String::from_utf8_lossy(locfmt).trim().to_string(),
prenul: prenul.to_owned(),
ftpstr: ftpstr.to_owned(),
pstnul: pstnul.to_owned(),
},
))
}

pub fn parse_daf_spk() {
// From https://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/req/daf.html
}

#[test]
fn test_parse_file_record() {
// NASA NAIF spy returns the following values for the file record bytes below
// ==================================================================
// File Architecture : DAF
// Binary File Format : LTL-IEEE
// FTP Validation String : Present and Intact
// Internal File Name : NIO2SPK
// ID Word : DAF/SPK
// ND : 2
// NI : 6
// Forward Record Pointer : 4
// Backward Record Pointer: 4
// First Free Address : 14967465
// ==================================================================
const FILE_RECORD_SEGMENT: [u8; 1024] = [
0x44u8, 0x41u8, 0x46u8, 0x2Fu8, 0x53u8, 0x50u8, 0x4Bu8, 0x20u8, 0x02u8, 0x00u8, 0x00u8,
0x00u8, 0x06u8, 0x00u8, 0x00u8, 0x00u8, 0x4Eu8, 0x49u8, 0x4Fu8, 0x32u8, 0x53u8, 0x50u8,
0x4Bu8, 0x20u8, 0x20u8, 0x20u8, 0x20u8, 0x20u8, 0x20u8, 0x20u8, 0x20u8, 0x20u8, 0x20u8,
0x20u8, 0x20u8, 0x20u8, 0x20u8, 0x20u8, 0x20u8, 0x20u8, 0x20u8, 0x20u8, 0x20u8, 0x20u8,
0x20u8, 0x20u8, 0x20u8, 0x20u8, 0x20u8, 0x20u8, 0x20u8, 0x20u8, 0x20u8, 0x20u8, 0x20u8,
0x20u8, 0x20u8, 0x20u8, 0x20u8, 0x20u8, 0x20u8, 0x20u8, 0x20u8, 0x20u8, 0x20u8, 0x20u8,
0x20u8, 0x20u8, 0x20u8, 0x20u8, 0x20u8, 0x20u8, 0x20u8, 0x20u8, 0x20u8, 0x20u8, 0x04u8,
0x00u8, 0x00u8, 0x00u8, 0x04u8, 0x00u8, 0x00u8, 0x00u8, 0xA9u8, 0x62u8, 0xE4u8, 0x00u8,
0x4Cu8, 0x54u8, 0x4Cu8, 0x2Du8, 0x49u8, 0x45u8, 0x45u8, 0x45u8, 0x00u8, 0x00u8, 0x00u8,
0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8,
0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8,
0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8,
0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8,
0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8,
0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8,
0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8,
0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8,
0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8,
0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8,
0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8,
0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8,
0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8,
0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8,
0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8,
0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8,
0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8,
0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8,
0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8,
0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8,
0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8,
0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8,
0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8,
0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8,
0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8,
0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8,
0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8,
0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8,
0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8,
0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8,
0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8,
0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8,
0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8,
0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8,
0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8,
0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8,
0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8,
0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8,
0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8,
0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8,
0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8,
0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8,
0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8,
0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8,
0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8,
0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8,
0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8,
0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8,
0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8,
0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8,
0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8,
0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8,
0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8,
0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8,
0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x46u8, 0x54u8, 0x50u8, 0x53u8, 0x54u8,
0x52u8, 0x3Au8, 0x0Du8, 0x3Au8, 0x0Au8, 0x3Au8, 0x0Du8, 0x0Au8, 0x3Au8, 0x0Du8, 0x00u8,
0x3Au8, 0x81u8, 0x3Au8, 0x10u8, 0xCEu8, 0x3Au8, 0x45u8, 0x4Eu8, 0x44u8, 0x46u8, 0x54u8,
0x50u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8,
0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8,
0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8,
0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8,
0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8,
0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8,
0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8,
0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8,
0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8,
0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8,
0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8,
0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8,
0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8,
0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8,
0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8,
0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8,
0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8,
0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8,
0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8,
0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8,
0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8,
0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8,
0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8,
0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8,
0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8,
0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8,
0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8,
0x00u8,
];

let (unparsed_string, file_record) =
parse_file_record(&FILE_RECORD_SEGMENT).expect("File record parsing should succeed");

assert_eq!(unparsed_string.len(), 0);

assert_eq!(file_record.locidw, "DAF/SPK");
assert_eq!(file_record.nd, 2);
assert_eq!(file_record.ni, 6);
assert_eq!(file_record.locifn, "NIO2SPK");
assert_eq!(file_record.fward, 4);
assert_eq!(file_record.bward, 4);
assert_eq!(file_record.free, 14967465);
assert_eq!(file_record.locfmt, "LTL-IEEE");
assert_eq!(
file_record.ftpstr,
b"FTPSTR:\r:\n:\r\n:\r\x00:\x81:\x10\xce:ENDFTP"
);
}
1 change: 1 addition & 0 deletions crates/lox_core/src/ephemeris/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
pub mod daf_spk;
1 change: 1 addition & 0 deletions crates/lox_core/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
pub mod bodies;
pub mod communications;
pub mod ephemeris;
pub mod time;

0 comments on commit a5ab074

Please sign in to comment.