Skip to content

Commit

Permalink
Merge branch 'main' of https:/E85Addict/cmpr
Browse files Browse the repository at this point in the history
  • Loading branch information
E85Addict committed Apr 16, 2023
2 parents 1f049eb + 27bff86 commit 88d7ef0
Show file tree
Hide file tree
Showing 5 changed files with 48 additions and 42 deletions.
3 changes: 2 additions & 1 deletion .cargo/config.toml
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
[build]
target = "x86_64-unknown-linux-gnu"
target = "aarch64-linux-android"
rustflags = ["-Ctarget-feature=+neon"]

[unstable]
build-std = ["std", "panic_abort"]
Expand Down
9 changes: 5 additions & 4 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,11 @@ jobs:
- uses: actions/checkout@v3
- name: Setup NDK
run: |
wget -nv https://dl.google.com/android/repository/android-ndk-r25b-linux.zip
unzip -qo android-ndk-r25b-linux.zip
chmod -R 777 ./android-ndk-r25b
export NDK_HOME="$(pwd)/android-ndk-r25b"
N="android-ndk-r25c"
wget -nv https://dl.google.com/android/repository/${N}-linux.zip
unzip -qo ${N}-linux.zip
chmod -R 777 ./${N}
export NDK_HOME="$(pwd)/${N}"
cargo install cargo-ndk
mkdir -p output
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
/target
/test
test*
Cargo.lock
3 changes: 3 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@ edition = "2021"
[dependencies]
libc = "0.2"

[profile.dev]
panic = "abort"

[profile.release]
lto = true
panic = "abort"
Expand Down
74 changes: 37 additions & 37 deletions src/main.rs
Original file line number Diff line number Diff line change
@@ -1,66 +1,66 @@
#![no_main]
#![feature(slice_as_chunks)]
#![feature(let_chains)]

use cmpr::{cprintln, Mmap, RawArgs};
use std::{fs::File, os::unix::prelude::AsRawFd, path::Path};

mod cmperror {
use std::io;
pub enum Error {
FileReadErr(io::Error),
MmapErr,
}

impl From<io::Error> for Error {
fn from(e: io::Error) -> Self {
Self::FileReadErr(e)
}
}
}
#![feature(array_chunks, portable_simd, let_chains)]

#[no_mangle]
pub extern "C" fn main(argc: i32, argv: *const *const u8) -> i32 {
let mut args = RawArgs::new(argc, argv);
let _ = args.next().unwrap();
if args.len() < 2 {
if let Some(arg) = args.next() && arg == "--version" {
cprintln!("cmpr by j-hc (github.com/j-hc)\nLicense GPL-3.0");
} else {
cprintln!("Usage: cmpr <file_path> <file_path>");
}
return 1;
cprintln!(
"Usage: cmpr <file_path> <file_path>\ncmpr by j-hc (github.com/j-hc)\nLicense GPL-3.0"
);
}

match run(args.next().unwrap(), args.next().unwrap()) {
Ok(true) => 0,
Err(e) => {
match e {
cmperror::Error::FileReadErr(_) => cprintln!("ERROR: File read failed"),
cmperror::Error::MmapErr => cprintln!("ERROR: Memory mapping failed"),
RunErr::IO => cprintln!("ERROR: could not read file"),
RunErr::MMap => cprintln!("ERROR: could not mmap file"),
}
1
}
_ => 1,
}
}

fn run(f1_path: impl AsRef<Path>, f2_path: impl AsRef<Path>) -> Result<bool, cmperror::Error> {
const CHUNK_SIZE: usize = 4096;
enum RunErr {
IO,
MMap,
}

let f1 = File::open(f1_path)?;
let f1_size = f1.metadata()?.len();
impl From<io::Error> for RunErr {
fn from(_: io::Error) -> Self {
Self::IO
}
}

let f2 = File::open(f2_path)?;
fn run(p1: &str, p2: &str) -> Result<bool, RunErr> {
let f1 = File::open(p1)?;
let f1_size = f1.metadata()?.len();
let f2 = File::open(p2)?;
let f2_size = f2.metadata()?.len();
if f1_size != f2_size {
return Ok(false);
}
let Some(fm1) = Mmap::new(f1.as_raw_fd(), f1_size as _) else { return Err(RunErr::MMap) };
let Some(fm2) = Mmap::new(f2.as_raw_fd(), f2_size as _) else { return Err(RunErr::MMap) };

let mmap1 = Mmap::new(f1.as_raw_fd(), f1_size as _).ok_or(cmperror::Error::MmapErr)?;
let mmap2 = Mmap::new(f2.as_raw_fd(), f2_size as _).ok_or(cmperror::Error::MmapErr)?;
Ok(compare(&fm1, &fm2))
}

fn compare(fm1: &[u8], fm2: &[u8]) -> bool {
const CHUNK_SIZE: usize = 16;
let mut fm1 = fm1.array_chunks::<CHUNK_SIZE>();
let mut fm2 = fm2.array_chunks::<CHUNK_SIZE>();

let (chunks1, r1) = mmap1.as_chunks::<CHUNK_SIZE>();
let (chunks2, r2) = mmap2.as_chunks::<CHUNK_SIZE>();
Ok(chunks1.iter().zip(chunks2.iter()).all(|(b1, b2)| b1 == b2) && r1 == r2)
iter::zip(fm1.by_ref(), fm2.by_ref())
.all(|(m1, m2)| u8x16::from_slice(m1) == u8x16::from_slice(m2))
&& iter::zip(fm1.remainder(), fm2.remainder()).all(|(m1, m2)| m1 == m2)
}

use cmpr::{cprintln, Mmap, RawArgs};
use std::fs::File;
use std::os::fd::AsRawFd;
use std::simd::u8x16;
use std::{io, iter};

0 comments on commit 88d7ef0

Please sign in to comment.