use std::fmt;
pub const SEED_LEN: usize = 16;
pub const TABLE_SIZE: usize = 1048573; pub const MAX_TABLE_SIZE: usize = 1_073_741_827; pub const HASH_BASE: u64 = 263;
pub const HASH_MOD: u64 = (1 << 61) - 1; pub const DELTA_MAGIC: &[u8; 4] = b"DLT\x03";
pub const DELTA_MAGIC_LARGE: &[u8; 4] = b"DLT\x04";
pub const DELTA_FLAG_INPLACE: u8 = 0x01;
pub const DELTA_CMD_END: u8 = 0;
pub const DELTA_CMD_COPY: u8 = 1;
pub const DELTA_CMD_ADD: u8 = 2;
pub const DELTA_CMD_BIGCOPY: u8 = 3;
pub const DELTA_CMD_BIGADD: u8 = 4;
pub const DELTA_CMD_MOVE: u8 = 5;
pub const DELTA_CMD_BIGMOVE: u8 = 6;
pub const DELTA_CRC_SIZE: usize = 8;
pub const DELTA_U32_SIZE: usize = 4;
pub const DELTA_U64_SIZE: usize = 8;
pub const DELTA_HEADER_SIZE: usize = 25; pub const DELTA_HEADER_SIZE_LARGE: usize = 29; pub const DELTA_COPY_PAYLOAD: usize = 12; pub const DELTA_ADD_HEADER: usize = 8; pub const DELTA_BIGCOPY_PAYLOAD: usize = 24; pub const DELTA_BIGADD_HEADER: usize = 16; pub const DELTA_BUF_CAP: usize = 256;
#[derive(Clone, Debug, PartialEq, Eq)]
pub enum Command {
Copy { offset: usize, length: usize },
Add { data: Vec<u8> },
}
impl fmt::Display for Command {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Command::Copy { offset, length } => write!(f, "COPY(off={}, len={})", offset, length),
Command::Add { data } => {
if data.len() <= 20 {
write!(f, "ADD({:?})", data)
} else {
write!(f, "ADD(len={})", data.len())
}
}
}
}
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub enum PlacedCommand {
Copy { src: usize, dst: usize, length: usize },
Add { dst: usize, data: Vec<u8> },
Move { src: usize, dst: usize, length: usize },
}
impl fmt::Display for PlacedCommand {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
PlacedCommand::Copy { src, dst, length } => {
write!(f, "COPY(src={}, dst={}, len={})", src, dst, length)
}
PlacedCommand::Add { dst, data } => {
if data.len() <= 20 {
write!(f, "ADD(dst={}, {:?})", dst, data)
} else {
write!(f, "ADD(dst={}, len={})", dst, data.len())
}
}
PlacedCommand::Move { src, dst, length } => {
write!(f, "MOVE(src={}, dst={}, len={})", src, dst, length)
}
}
}
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum Algorithm {
Greedy,
Onepass,
Correcting,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum CyclePolicy {
Localmin,
Constant,
}
#[derive(Clone, Debug)]
pub struct DiffOptions {
pub p: usize,
pub q: usize,
pub buf_cap: usize,
pub verbose: bool,
pub use_splay: bool,
pub max_table: usize,
}
impl Default for DiffOptions {
fn default() -> Self {
Self {
p: SEED_LEN,
q: TABLE_SIZE,
buf_cap: DELTA_BUF_CAP,
verbose: false,
use_splay: false,
max_table: MAX_TABLE_SIZE,
}
}
}
#[derive(Debug)]
pub enum DeltaError {
InvalidFormat(String),
UnexpectedEof,
IoError(std::io::Error),
}
impl fmt::Display for DeltaError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
DeltaError::InvalidFormat(msg) => write!(f, "invalid delta format: {}", msg),
DeltaError::UnexpectedEof => write!(f, "unexpected end of delta data"),
DeltaError::IoError(e) => write!(f, "I/O error: {}", e),
}
}
}
impl std::error::Error for DeltaError {}
impl From<std::io::Error> for DeltaError {
fn from(e: std::io::Error) -> Self {
DeltaError::IoError(e)
}
}
#[derive(Debug)]
pub struct DeltaSummary {
pub num_commands: usize,
pub num_copies: usize,
pub num_adds: usize,
pub copy_bytes: usize,
pub add_bytes: usize,
pub total_output_bytes: usize,
}
pub fn delta_summary(commands: &[Command]) -> DeltaSummary {
let mut num_copies = 0;
let mut num_adds = 0;
let mut copy_bytes = 0;
let mut add_bytes = 0;
for cmd in commands {
match cmd {
Command::Copy { length, .. } => {
num_copies += 1;
copy_bytes += length;
}
Command::Add { data } => {
num_adds += 1;
add_bytes += data.len();
}
}
}
DeltaSummary {
num_commands: commands.len(),
num_copies,
num_adds,
copy_bytes,
add_bytes,
total_output_bytes: copy_bytes + add_bytes,
}
}
pub fn placed_summary(commands: &[PlacedCommand]) -> DeltaSummary {
let mut num_copies = 0;
let mut num_adds = 0;
let mut copy_bytes = 0;
let mut add_bytes = 0;
for cmd in commands {
match cmd {
PlacedCommand::Copy { length, .. } => {
num_copies += 1;
copy_bytes += length;
}
PlacedCommand::Add { data, .. } => {
num_adds += 1;
add_bytes += data.len();
}
PlacedCommand::Move { length, .. } => {
num_copies += 1;
copy_bytes += length;
}
}
}
DeltaSummary {
num_commands: commands.len(),
num_copies,
num_adds,
copy_bytes,
add_bytes,
total_output_bytes: copy_bytes + add_bytes,
}
}