Skip to content

Commit 9547b02

Browse files
authored
File CRC: tolerate crc errors (#52)
Signed-off-by: Guillaume W. Bres <[email protected]>
1 parent 06625cf commit 9547b02

File tree

3 files changed

+57
-10
lines changed

3 files changed

+57
-10
lines changed

Cargo.toml

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "cggtts"
3-
version = "4.3.1"
3+
version = "4.4.0"
44
license = "MPL-2.0"
55
authors = ["Guillaume W. Bres <[email protected]>"]
66
description = "CGGTTS data parsing and synthesis"
@@ -24,6 +24,11 @@ default = [] # no features by default
2424
# Unlock common view period definitions and scheduling
2525
scheduler = []
2626

27+
# Activate logs
28+
logs = [
29+
"dep:log",
30+
]
31+
2732
# Satellite tracker and fit method
2833
tracker = [
2934
"dep:polyfit-rs",

src/header/parsing.rs

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,9 @@ use std::{
1111
str::FromStr,
1212
};
1313

14+
#[cfg(feature = "logs")]
15+
use log::error;
16+
1417
fn parse_header_version(s: &str) -> Result<Version, ParsingError> {
1518
const MARKER: &str = "CGGTTS GENERIC DATA FORMAT VERSION = ";
1619
const SIZE: usize = MARKER.len();
@@ -58,7 +61,13 @@ fn parse_hardware(s: &str) -> Result<Hardware, ParsingError> {
5861

5962
impl Header {
6063
/// Parse [Header] from any [Read]able input.
61-
pub fn parse<R: Read>(reader: &mut BufReader<R>) -> Result<Self, ParsingError> {
64+
/// ## Inputs
65+
/// - reader: mutable [BufReader] implementation
66+
/// - tolerate_crc_error: allow the CRC to differ and still proceed
67+
pub fn parse<R: Read>(
68+
reader: &mut BufReader<R>,
69+
tolerate_crc_error: bool,
70+
) -> Result<Self, ParsingError> {
6271
const CKSUM_PATTERN: &str = "CKSUM = ";
6372
const CKSUM_LEN: usize = CKSUM_PATTERN.len();
6473

@@ -295,7 +304,15 @@ impl Header {
295304
};
296305

297306
if value != crc {
298-
return Err(ParsingError::ChecksumValue);
307+
#[cfg(feature = "logs")]
308+
error!(
309+
"invalid file crc: got 0x{:02X} but expecting 0x{:02X}",
310+
value, crc
311+
);
312+
313+
if !tolerate_crc_error {
314+
return Err(ParsingError::ChecksumValue);
315+
}
299316
}
300317

301318
// CKSUM initiates the end of header section

src/lib.rs

Lines changed: 32 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -325,6 +325,7 @@ impl CGGTTS {
325325
}
326326

327327
/// Parse [CGGTTS] from a local file.
328+
/// This will fail on CRC mismatches.
328329
/// Advanced CGGTTS files generated from modern GNSS
329330
/// receivers may describe the ionospheric delay compensation:
330331
/// ```
@@ -342,19 +343,30 @@ impl CGGTTS {
342343
///```
343344
pub fn from_file<P: AsRef<Path>>(path: P) -> Result<Self, ParsingError> {
344345
let fd = File::open(path).unwrap_or_else(|e| panic!("File open error: {}", e));
346+
let mut reader = BufReader::new(fd);
347+
Self::parse(&mut reader, false)
348+
}
345349

350+
/// Parse [CGGTTS] from a local file, but tolerates CRC errors (check your logs).
351+
/// See [Self::from_file] for more information.
352+
pub fn from_file_infaillible_crc<P: AsRef<Path>>(path: P) -> Result<Self, ParsingError> {
353+
let fd = File::open(path).unwrap_or_else(|e| panic!("File open error: {}", e));
346354
let mut reader = BufReader::new(fd);
347-
Self::parse(&mut reader)
355+
Self::parse(&mut reader, true)
348356
}
349357

350358
/// Parse a new [CGGTTS] from any [Read]able interface.
351359
/// This will fail on:
352-
/// - Any critical standard violation
353-
/// - If file revision is not 2E (latest)
354-
/// - If following [Track]s do not contain the same [Constellation]
355-
pub fn parse<R: Read>(reader: &mut BufReader<R>) -> Result<Self, ParsingError> {
360+
/// - any critical standard violation
361+
/// - CRC mismatched (if not tolerated)
362+
/// - file revision is not 2E (latest)
363+
/// - [Track]s do not contain the same [Constellation]
364+
pub fn parse<R: Read>(
365+
reader: &mut BufReader<R>,
366+
tolerate_crc_error: bool,
367+
) -> Result<Self, ParsingError> {
356368
// Parse header section
357-
let header = Header::parse(reader)?;
369+
let header = Header::parse(reader, tolerate_crc_error)?;
358370

359371
// Parse tracks:
360372
// consumes all remaning lines and attempt parsing on each new line.
@@ -390,6 +402,7 @@ impl CGGTTS {
390402
}
391403

392404
/// Parse [CGGTTS] from gzip compressed local path.
405+
/// CRC errors will not be tolerated.
393406
#[cfg(feature = "flate2")]
394407
#[cfg_attr(docsrs, doc(cfg(feature = "flate2")))]
395408
pub fn from_gzip_file<P: AsRef<Path>>(path: P) -> Result<Self, ParsingError> {
@@ -398,7 +411,19 @@ impl CGGTTS {
398411
let reader = GzDecoder::new(fd);
399412

400413
let mut reader = BufReader::new(reader);
401-
Self::parse(&mut reader)
414+
Self::parse(&mut reader, false)
415+
}
416+
417+
/// Parse [CGGTTS] from gzip compressed local path, but tolerates CRC errors.
418+
#[cfg(feature = "flate2")]
419+
#[cfg_attr(docsrs, doc(cfg(feature = "flate2")))]
420+
pub fn from_gzip_file_infaillible_crc<P: AsRef<Path>>(path: P) -> Result<Self, ParsingError> {
421+
let fd = File::open(path).unwrap_or_else(|e| panic!("File open error: {}", e));
422+
423+
let reader = GzDecoder::new(fd);
424+
425+
let mut reader = BufReader::new(reader);
426+
Self::parse(&mut reader, true)
402427
}
403428

404429
/// Format [CGGTTS] following standard specifications.

0 commit comments

Comments
 (0)