Skip to content

Commit 01c8538

Browse files
authored
Crinex (#318)
* Upgrade program/runby * TextDiff: compression now validated * Working on RNX2CRX --------- Signed-off-by: Guillaume W. Bres <[email protected]>
1 parent 91660c4 commit 01c8538

File tree

10 files changed

+101
-75
lines changed

10 files changed

+101
-75
lines changed

src/binex/rnx2bin/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,7 @@ impl<'a> RNX2BIN<'a> {
143143
let mut geo = MonumentGeoRecord::default();
144144
geo.epoch = self.t0;
145145
geo.meta = MonumentGeoMetadata::RNX2BIN;
146-
geo = geo.with_software_name(&format!("geo-rust v{}", env!("CARGO_PKG_VERSION")));
146+
geo = geo.with_software_name(&format!("rtk-rs/rinex v{}", env!("CARGO_PKG_VERSION")));
147147
geo
148148
}
149149
}

src/hatanaka/compressor.rs

Lines changed: 36 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -78,18 +78,33 @@ impl<const M: usize> CompressorExpert<M> {
7878
.sorted()
7979
.collect::<Vec<_>>();
8080

81-
self.epoch_buf = format!(
82-
"{:04} {:02} {:02} {:02} {:02} {:02}.{:07} {}{:3} ",
83-
y,
84-
m,
85-
d,
86-
hh,
87-
mm,
88-
ss,
89-
ns / 100,
90-
k.flag,
91-
svnn.len(),
92-
);
81+
if self.v3 {
82+
self.epoch_buf.push_str(&format!(
83+
"> {:04} {:02} {:02} {:02} {:02} {:02}.{:07} {}{:3} ",
84+
y,
85+
m,
86+
d,
87+
hh,
88+
mm,
89+
ss,
90+
ns / 100,
91+
k.flag,
92+
svnn.len(),
93+
));
94+
} else {
95+
self.epoch_buf.push_str(&format!(
96+
"&{:04} {:02} {:02} {:02} {:02} {:02}.{:07} {}{:3} ",
97+
y,
98+
m,
99+
d,
100+
hh,
101+
mm,
102+
ss,
103+
ns / 100,
104+
k.flag,
105+
svnn.len(),
106+
));
107+
}
93108

94109
// Append each SV to epoch description
95110
for sv in svnn.iter() {
@@ -99,13 +114,9 @@ impl<const M: usize> CompressorExpert<M> {
99114
// Epoch compression
100115
if self.epoch_compression {
101116
let compressed = self.epoch_diff.compress(&self.epoch_buf);
102-
writeln!(w, " {}", compressed)?;
117+
writeln!(w, "{}", compressed)?;
103118
} else {
104-
if self.v3 {
105-
writeln!(w, "> {}", self.epoch_buf)?;
106-
} else {
107-
writeln!(w, "&{}", self.epoch_buf)?;
108-
}
119+
writeln!(w, "{}", self.epoch_buf)?;
109120
}
110121

111122
if let Some(clk) = v.clock {
@@ -153,10 +164,14 @@ impl<const M: usize> CompressorExpert<M> {
153164

154165
if let Some(lli) = signal.lli {
155166
self.flags_buf.push_str(&format!("{}", lli.bits() as u8));
167+
} else {
168+
self.flags_buf.push_str(" ");
156169
}
157170

158171
if let Some(snr) = signal.snr {
159172
self.flags_buf.push_str(&format!("{}", snr as u8));
173+
} else {
174+
self.flags_buf.push_str(" ");
160175
}
161176
} else {
162177
// BLANK is a single ' '
@@ -170,11 +185,11 @@ impl<const M: usize> CompressorExpert<M> {
170185
let compressed = flags_kernel.compress(&self.flags_buf);
171186
writeln!(w, "{}", compressed)?;
172187
} else {
173-
let kernel = TextDiff::new(&self.flags_buf);
188+
let mut kernel = TextDiff::new("");
189+
let compressed = kernel.compress(&self.flags_buf);
190+
writeln!(w, "{}", compressed)?;
174191
self.flags_diff.insert(*sv, kernel);
175-
writeln!(w, "{}", self.flags_buf)?;
176192
}
177-
178193
self.flags_buf.clear();
179194
}
180195
self.epoch_compression = true;

src/hatanaka/crinex.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,7 @@ impl Default for CRINEX {
164164
fn default() -> Self {
165165
Self {
166166
version: Version { major: 3, minor: 0 },
167-
prog: format!("rust-rinex-{}", env!("CARGO_PKG_VERSION")),
167+
prog: format!("rtk-rs/rinex v{}", env!("CARGO_PKG_VERSION")),
168168
date: epoch_now_utc(),
169169
}
170170
}

src/hatanaka/textdiff.rs

Lines changed: 48 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -69,59 +69,65 @@ impl TextDiff {
6969
/// Returns compressed text.
7070
pub fn compress(&mut self, data: &str) -> &str {
7171
let len = data.len();
72-
let buf_len = self.buffer.len();
73-
let history_len = self.buffer.len();
72+
let mut buf_len = self.buffer.len();
73+
let min_len = std::cmp::min(len, buf_len);
7474

75-
// expand with new content
76-
if len > buf_len {
77-
self.buffer.push_str(&data[buf_len..]);
78-
self.compressed.push_str(&data[buf_len..].replace(' ', "&")); // copy & replace whitespaces
75+
if buf_len > len {
76+
// special case: shrink history
77+
self.buffer = self.buffer[..len].to_string();
78+
buf_len = len; // update size
7979
}
8080

81-
// study possible shared content
82-
let mut new = data.bytes();
83-
let mut history = self.buffer[..history_len].bytes();
81+
self.compressed = self.buffer.to_string();
8482

8583
unsafe {
84+
let mut bytes = data.as_bytes().iter();
85+
let mut buffered = self.buffer.as_bytes().iter();
8686
let mut compressed = self.compressed.as_bytes_mut().iter_mut();
8787

88-
// run through bytes for which we have history
89-
// and either keep or compress
90-
while let Some(new) = new.next() {
91-
let compressed = compressed.next().unwrap();
92-
93-
if let Some(history) = history.next() {
94-
if history == new {
95-
*compressed = b' ';
88+
while let Some(buffered) = buffered.next() {
89+
let byte = bytes.next().unwrap();
90+
let mut compressed = compressed.next().unwrap();
91+
if byte == buffered {
92+
*compressed = b' ';
93+
} else {
94+
if *byte == b' ' {
95+
*compressed = b'&';
9696
} else {
97-
if new == b' ' {
98-
*compressed = b'&';
99-
} else {
100-
*compressed = new;
101-
}
97+
*compressed = *byte;
10298
}
10399
}
104100
}
101+
}
105102

106-
// supports shorter inputs than internal buffer:
107-
// possible '&' residues need to be whitened
108-
// this gives maximum flexibility when dealing with actual files
109-
while let Some(compressed) = compressed.next() {
110-
*compressed = b' ';
111-
}
103+
// update internal memory
104+
self.buffer = data.to_string();
112105

113-
self.buffer = data.to_string();
114-
&self.compressed
106+
// possible new string termination
107+
if len > buf_len {
108+
self.compressed.push_str(&data[buf_len..]);
109+
110+
unsafe {
111+
let mut compressed = self.compressed.as_bytes_mut().iter_mut().skip(buf_len);
112+
while let Some(byte) = compressed.next() {
113+
if *byte == b' ' {
114+
*byte = b'&';
115+
}
116+
}
117+
}
115118
}
119+
120+
&self.compressed
116121
}
117122
}
118123

119124
#[cfg(test)]
120125
mod test {
121126
use super::*;
122127
#[test]
123-
fn test_decompression() {
124-
let mut diff = TextDiff::new("ABCDEFG 12 000 33 XXACQmpLf");
128+
fn textdiff_decompression() {
129+
const INIT: &str = "ABCDEFG 12 000 33 XXACQmpLf";
130+
let mut diff = TextDiff::new(INIT);
125131

126132
let compressed: Vec<&str> = vec![
127133
" 3 1 44 xxACq F",
@@ -134,6 +140,7 @@ mod test {
134140
"& ",
135141
" ",
136142
];
143+
137144
let expected: Vec<&str> = vec![
138145
"ABCDEFG 13 001 44 xxACqmpLF",
139146
"ABCDEFG 43 001 44 xxACqmpLF",
@@ -148,6 +155,7 @@ mod test {
148155

149156
for i in 0..compressed.len() {
150157
let decompressed = diff.decompress(compressed[i]);
158+
151159
assert_eq!(
152160
decompressed,
153161
expected[i],
@@ -186,21 +194,23 @@ mod test {
186194
}
187195

188196
#[test]
189-
#[ignore]
190-
fn test_compression() {
197+
fn textdiff_compression() {
191198
let mut diff = TextDiff::new("0");
199+
192200
assert_eq!(diff.compress("0"), " ");
193201
assert_eq!(diff.compress("4"), "4");
194202
assert_eq!(diff.compress("4"), " ");
203+
assert_eq!(diff.compress("44"), " 4");
195204
assert_eq!(diff.compress("4 "), " &");
205+
assert_eq!(diff.compress("4 "), " ");
196206
assert_eq!(diff.compress("4 "), " &");
197-
assert_eq!(diff.compress("0"), "0 ");
198-
assert_eq!(diff.compress("0"), " ");
199-
assert_eq!(diff.compress(" "), "& ");
207+
assert_eq!(diff.compress("0"), "0");
208+
assert_eq!(diff.compress("0"), " ");
209+
assert_eq!(diff.compress(" "), "&&&");
200210

201211
diff.force_init("Default 1234");
202212
assert_eq!(diff.compress("DEfault 1234"), " E ");
203213
assert_eq!(diff.compress("DEfault 1234"), " ");
204-
assert_eq!(diff.compress(" "), " &");
214+
assert_eq!(diff.compress(" "), "&&&&&&& &&&&&");
205215
}
206216
}

src/header/decim.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ impl Decimate for Header {
1313
}
1414
fn decimate_mut(&mut self, _: &DecimationFilter) {
1515
self.program = Some(format!(
16-
"geo-rust v{}",
16+
"rs-rinex v{}",
1717
Self::format_pkg_version(env!("CARGO_PKG_VERSION"),)
1818
));
1919

src/header/mod.rs

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,7 @@ impl Default for Header {
153153
rinex_type: Type::ObservationData,
154154
constellation: Some(Constellation::Mixed),
155155
program: Some(format!(
156-
"geo-rust v{}",
156+
"rs-rinex v{}",
157157
Self::format_pkg_version(env!("CARGO_PKG_VERSION"))
158158
)),
159159
obs: Some(Default::default()),
@@ -261,7 +261,7 @@ impl Header {
261261

262262
let (y, m, d, hh, mm, ss, _) = timestamp.to_gregorian_utc();
263263
format!(
264-
"geo-rust v{} {:>width$} {}{:02}{:02} {:02}{:02}{:02} {:x}",
264+
"rs-rinex v{} {:>width$} {}{:02}{:02} {:02}{:02}{:02} {:x}",
265265
formatted_version,
266266
"FILE MERGE",
267267
y,
@@ -402,37 +402,37 @@ mod test {
402402
(
403403
"1.0.0",
404404
"1.0.0",
405-
"geo-rust v1.0.0 FILE MERGE 20000101 000000 UTC",
405+
"rs-rinex v1.0.0 FILE MERGE 20000101 000000 UTC",
406406
),
407407
(
408408
"10.0.0",
409409
"10.0.0",
410-
"geo-rust v10.0.0 FILE MERGE 20000101 000000 UTC",
410+
"rs-rinex v10.0.0 FILE MERGE 20000101 000000 UTC",
411411
),
412412
(
413413
"0.17.0",
414414
"0.17.0",
415-
"geo-rust v0.17.0 FILE MERGE 20000101 000000 UTC",
415+
"rs-rinex v0.17.0 FILE MERGE 20000101 000000 UTC",
416416
),
417417
(
418418
"0.17.1",
419419
"0.17.1",
420-
"geo-rust v0.17.1 FILE MERGE 20000101 000000 UTC",
420+
"rs-rinex v0.17.1 FILE MERGE 20000101 000000 UTC",
421421
),
422422
(
423423
"0.17.1-alpha",
424424
"0.17.1a",
425-
"geo-rust v0.17.1a FILE MERGE 20000101 000000 UTC",
425+
"rs-rinex v0.17.1a FILE MERGE 20000101 000000 UTC",
426426
),
427427
(
428428
"0.17.1-rc",
429429
"0.17.1rc",
430-
"geo-rust v0.17.1rc FILE MERGE 20000101 000000 UTC",
430+
"rs-rinex v0.17.1rc FILE MERGE 20000101 000000 UTC",
431431
),
432432
(
433433
"0.17.1-rc-1",
434434
"0.17.1rc1",
435-
"geo-rust v0.17.1rc1 FILE MERGE 20000101 000000 UTC",
435+
"rs-rinex v0.17.1rc1 FILE MERGE 20000101 000000 UTC",
436436
),
437437
] {
438438
assert_eq!(Header::format_pkg_version(pkg_version), formatted);

src/lib.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -406,7 +406,7 @@ impl Rinex {
406406
};
407407
crinex.date = epoch::now();
408408
crinex.prog = format!(
409-
"geo-rust v{}",
409+
"rs-rinex v{}",
410410
Header::format_pkg_version(env!("CARGO_PKG_VERSION"))
411411
);
412412
self.header = self.header.with_crinex(crinex);
@@ -437,7 +437,7 @@ impl Rinex {
437437
});
438438

439439
self.header.program = Some(format!(
440-
"geo-rust v{}",
440+
"rs-rinex v{}",
441441
Header::format_pkg_version(env!("CARGO_PKG_VERSION"))
442442
));
443443
}

src/processing/split/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ impl Split for Rinex {
8383

8484
fn split_mut(&mut self, t: Epoch) -> Self {
8585
self.header.program = Some(format!(
86-
"geo-rust v{}",
86+
"rs-rust v{}",
8787
Header::format_pkg_version(env!("CARGO_PKG_VERSION"),)
8888
));
8989

src/qc/merge/header.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -181,7 +181,7 @@ impl Merge for Header {
181181
let now = Epoch::now().map_err(|_| MergeError::Other)?;
182182

183183
self.program = Some(format!(
184-
"geo-rust v{}",
184+
"rs-rinex v{}",
185185
Self::format_pkg_version(env!("CARGO_PKG_VERSION"))
186186
));
187187

src/record/formatting.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ impl Record {
2727
// following the Hatanaka Compression algorithm.
2828
if header.crinex.is_some() {
2929
let mut compressor = Compressor::default();
30+
compressor.v3 = version_major > 2;
3031
compressor.format(w, &rec, header)?;
3132
} else {
3233
for (k, v) in rec.iter() {

0 commit comments

Comments
 (0)