Skip to content

Commit

Permalink
Merge pull request #7 from nyurik/lint-ideas
Browse files Browse the repository at this point in the history
  • Loading branch information
kornelski authored Apr 2, 2024
2 parents 9fffac6 + 2d8d70f commit 77d9bf7
Show file tree
Hide file tree
Showing 8 changed files with 74 additions and 61 deletions.
2 changes: 1 addition & 1 deletion .editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,4 @@ root = true
[*]
indent_style = space
insert_final_newline = true
trim_trailing_whitespace = true
trim_trailing_whitespace = true
12 changes: 7 additions & 5 deletions .github/workflows/rust.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,10 @@ jobs:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v2
- name: Build
run: cargo build --verbose
- name: Run tests
run: cargo test --verbose
- uses: actions/checkout@v2
- name: Build
run: RUSTFLAGS='-D warnings' cargo build --verbose
- name: Run tests
run: cargo test --verbose
- name: Clippy
run: cargo clippy -- -D warnings
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,4 @@
target/

.DS_Store
Cargo.lock
Cargo.lock
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,5 @@ keywords = ["bspatch", "patch", "diff", "delta", "binary"]
license = "BSD-2-Clause"
homepage = "https://lib.rs/bsdiff"
repository = "https://github.com/space-wizards/bsdiff-rs"
edition = "2018"
edition = "2021"
include = ["src/*.rs", "LICENSE", "README.md", "Cargo.toml"]
61 changes: 44 additions & 17 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,30 +1,57 @@
# bsdiff-rs

[![Build status](https://github.com/space-wizards/bsdiff-rs/actions/workflows/rust.yml/badge.svg)](https://github.com/space-wizards/bsdiff-rs/actions/workflows/rust.yml)
[![Cargo Link](https://img.shields.io/crates/v/bsdiff.svg)](https://crates.rs/crates/bsdiff)
[![GitHub](https://img.shields.io/badge/github-bsdiff-8da0cb?logo=github)](https://github.com/space-wizards/bsdiff-rs)
[![crates.io version](https://img.shields.io/crates/v/bsdiff.svg)](https://crates.io/crates/bsdiff)
[![docs.rs docs](https://docs.rs/bsdiff/badge.svg)](https://docs.rs/bsdiff)
[![crates.io version](https://img.shields.io/crates/l/bsdiff.svg)](https://github.comspace-wizards/bsdiff-rss/blob/main/LICENSE-APACHE)
[![CI build](https://github.com/space-wizards/bsdiff-rs/actions/workflows/rust.yml/badge.svg)](https://github.com/space-wizards/bsdiff-rs/actions)

Rust port of a [bsdiff library](https://github.com/mendsley/bsdiff). High performance patching. All written in safe Rust.
Bsdiff is a method of diffing files. This crate is a port of a [bsdiff library](https://github.com/mendsley/bsdiff).
High performance patching. All written in safe
Rust.

## Diffing
It is usually a good idea to use bsdiff alongside a compression algorithm like bzip2.

## Usage

```rust
let old = std::fs::read("old")?;
let new = std::fs::read("new")?;
let mut patch = Vec::new();
fn main() {
let one = vec![1, 2, 3, 4, 5];
let two = vec![1, 2, 4, 6];
let mut patch = Vec::new();

bsdiff::diff(&one, &two, &mut patch).unwrap();

bsdiff::diff(&old, &new, &mut patch)?;
// TODO: compress `patch` here
std::fs::write("patch", &patch)?;
let mut patched = Vec::with_capacity(two.len());
bsdiff::patch(&one, &mut patch.as_slice(), &mut patched).unwrap();
assert_eq!(patched, two);
}
```

## Patching
## Diffing Files

```rust
let old = std::fs::read("old")?;
let patch = std::fs::read("patch")?;
// TODO: decompress `patch` here
let mut new = Vec::new();
fn diff_files(file_a: &str, file_b: &str, patch_file: &str) -> std::io::Result<()> {
let old = std::fs::read(file_a)?;
let new = std::fs::read(file_b)?;
let mut patch = Vec::new();

bsdiff::diff(&old, &new, &mut patch)?;
// TODO: compress `patch` here
std::fs::write(patch_file, &patch)
}
```

bsdiff::patch(&old, &mut patch.as_slice(), &mut new)?;
std::fs::write("new", &new)?;
## Patching Files

```rust
fn patch_file(file_a: &str, patch_file: &str, file_b: &str) -> std::io::Result<()> {
let old = std::fs::read(file_a)?;
let patch = std::fs::read(patch_file)?;
// TODO: decompress `patch` here
let mut new = Vec::new();

bsdiff::patch(&old, &mut patch.as_slice(), &mut new)?;
std::fs::write(file_b, &new)
}
```
26 changes: 14 additions & 12 deletions src/diff.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
* POSSIBILITY OF SUCH DAMAGE.
*/

use std::cmp::Ordering;
use std::io;
use std::io::Write;

Expand Down Expand Up @@ -101,15 +102,16 @@ fn split_internal(
let mut k = 0;
let mut i = start;
while i < jj {
let v = V[usz(I[i] + h as isize)];
if v < x {
i += 1;
} else if v == x {
I.swap(i, jj + j);
j += 1;
} else {
I.swap(i, kk + k);
k += 1;
match V[usz(I[i] + h as isize)].cmp(&x) {
Ordering::Less => i += 1,
Ordering::Equal => {
I.swap(i, jj + j);
j += 1;
}
Ordering::Greater => {
I.swap(i, kk + k);
k += 1;
}
}
}
while jj + j < kk {
Expand Down Expand Up @@ -210,14 +212,14 @@ fn matchlen(old: &[u8], new: &[u8]) -> usize {
fn search(I: &[isize], old: &[u8], new: &[u8]) -> (isize, usize) {
if I.len() < 3 {
let x = matchlen(&old[usz(I[0])..], new);
let y = matchlen(&old[usz(I[I.len()-1])..], new);
let y = matchlen(&old[usz(I[I.len() - 1])..], new);
if x > y {
(I[0], x)
} else {
(I[I.len()-1], y)
(I[I.len() - 1], y)
}
} else {
let mid = (I.len()-1) / 2;
let mid = (I.len() - 1) / 2;
let left = &old[usz(I[mid])..];
let right = new;
let len_to_check = left.len().min(right.len());
Expand Down
20 changes: 1 addition & 19 deletions src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,22 +1,4 @@
//! Bsdiff is a method of diffing files.
//! This crate has been ported from C code.
//! The original code and more info can be found [here](https://github.com/mendsley/bsdiff).
//!
//! It is usually a good idea to use bsdiff alongside a compression algorithm like bzip2.
//!
//! # Example
//!
//! ```
//! let one = vec![1, 2, 3, 4, 5];
//! let two = vec![1, 2, 4, 6];
//! let mut patch = Vec::new();
//!
//! bsdiff::diff(&one, &two, &mut patch).unwrap();
//!
//! let mut patched = Vec::with_capacity(two.len());
//! bsdiff::patch(&one, &mut patch.as_slice(), &mut patched).unwrap();
//! assert_eq!(patched, two);
//! ```
#![doc = include_str!("../README.md")]

mod diff;
mod patch;
Expand Down
10 changes: 5 additions & 5 deletions src/patch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,15 +32,15 @@ use std::io;
use std::io::Read;

/// Apply a patch to an "old" file, returning the "new" file.
///
///
/// `old` is the old file, `patch` will be read from with the patch,`new` is the buffer that will be written into.
pub fn patch<T: Read>(old: &[u8], patch: &mut T, new: &mut Vec<u8>) -> io::Result<()> {
let mut oldpos: usize = 0;
loop {
// Read control data
let mut buf = [0; 24];
if read_or_eof(patch, &mut buf)? {
return Ok(())
return Ok(());
}

// only seek can be negative
Expand Down Expand Up @@ -99,7 +99,7 @@ fn read_or_eof<T: Read>(reader: &mut T, buf: &mut [u8; 24]) -> io::Result<bool>
} else {
Err(io::ErrorKind::UnexpectedEof.into())
}
},
}
Ok(n) => {
if n >= tmp.len() {
return Ok(false);
Expand All @@ -116,9 +116,9 @@ fn read_or_eof<T: Read>(reader: &mut T, buf: &mut [u8; 24]) -> io::Result<bool>
#[inline]
fn offtin(buf: [u8; 8]) -> i64 {
let y = i64::from_le_bytes(buf);
if 0 == y & (1<<63) {
if 0 == y & (1 << 63) {
y
} else {
-(y & !(1<<63))
-(y & !(1 << 63))
}
}

0 comments on commit 77d9bf7

Please sign in to comment.