aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Schadt <kingdread@gmx.de>2023-01-14 20:05:38 +0100
committerDaniel Schadt <kingdread@gmx.de>2023-01-14 20:05:38 +0100
commitba171bad33767ad52e0900760358bac3df69f896 (patch)
treee82d81ae4cf0ebf12116367a68b870ee5c29a713
parent767b239776c23d9aa31c5d0b594ba200c430a8bb (diff)
downloadhittekaart-ba171bad33767ad52e0900760358bac3df69f896.tar.gz
hittekaart-ba171bad33767ad52e0900760358bac3df69f896.tar.bz2
hittekaart-ba171bad33767ad52e0900760358bac3df69f896.zip
add support for reading brotli and gzip files
-rw-r--r--Cargo.lock38
-rw-r--r--Cargo.toml2
-rw-r--r--src/gpx.rs42
-rw-r--r--src/main.rs8
4 files changed, 85 insertions, 5 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 337cfc7..b995bd3 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -24,6 +24,21 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe"
[[package]]
+name = "alloc-no-stdlib"
+version = "2.0.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cc7bb162ec39d46ab1ca8c77bf72e890535becd1751bb45f64c597edb4c8c6b3"
+
+[[package]]
+name = "alloc-stdlib"
+version = "0.2.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "94fb8275041c72129eb51b7d0322c29b8387a0386127718b096429201a5d6ece"
+dependencies = [
+ "alloc-no-stdlib",
+]
+
+[[package]]
name = "anes"
version = "0.1.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -83,6 +98,27 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
[[package]]
+name = "brotli"
+version = "3.3.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a1a0b1dbcc8ae29329621f8d4f0d835787c1c38bb1401979b49d13b0b305ff68"
+dependencies = [
+ "alloc-no-stdlib",
+ "alloc-stdlib",
+ "brotli-decompressor",
+]
+
+[[package]]
+name = "brotli-decompressor"
+version = "2.3.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "59ad2d4653bf5ca36ae797b1f4bb4dbddb60ce49ca4aed8a2ce4829f60425b80"
+dependencies = [
+ "alloc-no-stdlib",
+ "alloc-stdlib",
+]
+
+[[package]]
name = "bumpalo"
version = "3.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -564,10 +600,12 @@ dependencies = [
name = "hittekaart"
version = "0.1.0"
dependencies = [
+ "brotli",
"clap 4.1.0",
"color-eyre",
"colorgrad",
"criterion",
+ "flate2",
"fnv",
"image",
"imageproc",
diff --git a/Cargo.toml b/Cargo.toml
index cf67d91..f50423e 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -11,9 +11,11 @@ name = "hittebench"
harness = false
[dependencies]
+brotli = "3.3.4"
clap = { version = "4.1.0", features = ["derive"] }
color-eyre = "0.6.2"
colorgrad = "0.6.2"
+flate2 = "1.0.25"
fnv = "1.0.7"
image = "0.24.5"
imageproc = "0.23.0"
diff --git a/src/gpx.rs b/src/gpx.rs
index 337a2a9..9dd7725 100644
--- a/src/gpx.rs
+++ b/src/gpx.rs
@@ -3,9 +3,16 @@
//! We *could* use the [gpx](https://github.com/georust/gpx) crate, but we don't care about much
//! other than the coordinates of the tracks. By implementing the little functionality ourselves,
//! we can use a fast XML parser ([roxmltree](https://github.com/RazrFalcon/roxmltree)).
-use std::{f64::consts::PI, fs, path::Path};
+use std::{
+ f64::consts::PI,
+ ffi::OsStr,
+ fs::{self, File},
+ io::{BufReader, Read},
+ path::Path,
+};
use color_eyre::eyre::{eyre, Result};
+use flate2::bufread::GzDecoder;
use roxmltree::{Document, Node, NodeType};
#[derive(Debug, Copy, Clone, PartialEq)]
@@ -67,12 +74,41 @@ pub fn extract_from_str(input: &str) -> Result<Vec<Coordinates>> {
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
pub enum Compression {
None,
+ Gzip,
+ Brotli,
+}
+
+impl Compression {
+ pub fn suggest_from_path<P: AsRef<Path>>(path: P) -> Option<Compression> {
+ let Some(ext) = path.as_ref().extension() else { return None };
+ if OsStr::new("br") == ext {
+ Some(Compression::Brotli)
+ } else if [OsStr::new("gz"), OsStr::new("gzip")].contains(&ext) {
+ Some(Compression::Gzip)
+ } else if OsStr::new("gpx") == ext {
+ Some(Compression::None)
+ } else {
+ None
+ }
+ }
}
pub fn extract_from_file<P: AsRef<Path>>(
path: P,
- _compression: Compression,
+ compression: Compression,
) -> Result<Vec<Coordinates>> {
- let content = fs::read_to_string(path)?;
+ let content = match compression {
+ Compression::None => fs::read_to_string(path)?,
+ Compression::Gzip => {
+ let mut result = String::new();
+ GzDecoder::new(BufReader::new(File::open(path)?)).read_to_string(&mut result)?;
+ result
+ }
+ Compression::Brotli => {
+ let mut result = Vec::new();
+ brotli::BrotliDecompress(&mut BufReader::new(File::open(path)?), &mut result)?;
+ String::from_utf8(result)?
+ }
+ };
extract_from_str(&content)
}
diff --git a/src/main.rs b/src/main.rs
index f4a7aa7..e2dacb7 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -5,7 +5,7 @@ use std::{
};
use clap::Parser;
-use color_eyre::eyre::{bail, Context, Result};
+use color_eyre::eyre::{bail, eyre, Context, Result};
use indicatif::{MultiProgress, ProgressBar, ProgressDrawTarget, ProgressStyle};
use is_terminal::IsTerminal;
use rayon::ThreadPoolBuilder;
@@ -14,6 +14,8 @@ mod gpx;
mod layer;
mod renderer;
+use gpx::Compression;
+
#[derive(Parser, Debug, Clone)]
#[command(author, version, about)]
struct Args {
@@ -70,7 +72,9 @@ fn main() -> Result<()> {
let mut tracks = Vec::new();
for file in &args.files {
- let data = gpx::extract_from_file(file, gpx::Compression::None).unwrap();
+ let compression = Compression::suggest_from_path(file)
+ .ok_or_else(|| eyre!("Could not determine format for {file:?}"))?;
+ let data = gpx::extract_from_file(file, compression)?;
tracks.push(data);
bar.inc(1);
}