sit-rs

Crates.iosit-rs
lib.rssit-rs
version0.2.0
created_at2026-01-25 12:30:39.372692+00
updated_at2026-01-25 19:22:08.105974+00
descriptionRust-native extraction for StuffIt Expander archive files
homepage
repositoryhttps://codeberg.org/cyco/sit-rs
max_upload_size
id2068609
size254,086
(cyco)

documentation

README

sit

Rust-native extraction for StuffIt Expander archive files.

Overview

For simple file verification use [verify] or [verify_path].

For more advanced use-cases you would typically open an [Archive], either from a file or an [std::io::Read]er, and then iterate through archive's entries by calling [Archive::iter].

Each entry provides some meta data, like its [Entry::name], or [Entry::uncompressed_size]. You can access the uncompressed data transparently by passing the entry into the archive's Archive::open method and specifying which fork you want to access.

The iterator is designed to avoid seeking (especially seeking backwards), so it's advisable to always read the resource fork first and the data fork second whenever you are interested in both forks,.

Use [Archive::into_inner] methods to get your original reader back.

The following demonstrates how to extract the data fork of a specific entry in the archive:

use std::io::{Read as _};
use sit::{Archive, Fork};

/// Open archive from the file system
let mut archive = Archive::open_path("test/StuffIt 1.10 Moby Dick.sit")
                          .expect("Could not open archive");

// Find an entry in the archive
let mut title = archive.iter()
                       .find(|e| e.is_file() && e.name() == "00b Title.txt")
                       .expect("Entry not found in archive");

// Allocate space for extracted data
let mut contents = vec![0u8; title.uncompressed_size(Fork::Data)];

// Open a reader where the compressed data fork for the entry is located
archive.open_fork(&title, Fork::Data)
       .expect("Could not open entry")
        // Request verification of crc checksums
       .verifying()
        // Extract data
       .read_exact(&mut contents)
       .unwrap();

let contents = String::from_utf8_lossy(&contents);
assert!(contents.contains("MOBY-DICK"));

Verification

The StuffIt file format employs multiple CRC checksums to ensure the integrity of the archive header, entry headers and uncompressed data streams.

Verification can be triggered by calling [Archive::verify] (all checksums) and [Archive::verify_entry] (entry related checksums) at the cost of potentially iterating through all entries, uncompressing the whole archive and then seeking back to the start.

Alternatively verification can be requested using [archive::EntryIterator::verifying], which will create a new iterator that verifies header checksums as they are discovered and [EntryReader::verifying] which will update the CRC checksum as bytes are uncompressed.

When using [EntryReader::verifying] it is important to make sure that all data is read from the reader as the checksum can only be verified when the last byte has been seen. You can use [VerifyingEntryReader::slurp] to read the stream to the end and ensure the checksum is verified in case you're not interested in the remaining bytes. Calling the method on a reader that has already finished will return the validation result again without doing additional work.

Low-level access

Structures

The [structs] module provides definitions for the data structures used in StuffIt archives. These structs can be read from any reader using [binrw].

Note that the layout of binary data was change somewhat substantially with version 5 of SutffIt, so the module is split into two submodules [structs::v1] (for pre-5 archives) and [structs::v5] for archive files that were created with StuffIt 5.

A common interface to both versions is provided in [structs::ArchiveHeader], [structs::Entry], [structs::Directory] and [structs::File].

Algorithms

Decompression algorithms are implemented in the [algos] module, usually in the form of a struct with an [std::io::Read] implementation that provides transparent access to the uncompressed data.

While those reader also implement [std::io::Seek], these implementations are usually stubbed and only provide reliable [std::io::Seek::stream_len] and [std::io::Seek::stream_position] methods. Seeking forward might also be supported if you're lucky.

Limitations

The crate currently does not verify checksums contained in file or directory meta data. Only file contents and the archive header are verified.

Commit count: 7

cargo fmt