#archive #bindings #file #ffi #gamedev #directory #read

zarchive

Simple Rust bindings to Exzap's ZArchive library

3 unstable releases

0.2.0 Mar 2, 2023
0.1.1 Jul 5, 2022
0.1.0 Jun 30, 2022

#340 in Compression

Download history 36/week @ 2024-02-25 1/week @ 2024-03-03 10/week @ 2024-03-10 1/week @ 2024-03-17 4/week @ 2024-03-24 51/week @ 2024-03-31

66 downloads per month

Custom license

74KB
1.5K SLoC

C++ 696 SLoC // 0.1% comments Rust 622 SLoC C 151 SLoC // 0.3% comments

crates.io api license build

Simple Rust bindings to ZArchive.

Overview

ZArchive is yet another file archive format. Think of zip, tar, 7z, etc. but with the requirement of allowing random-access reads and supporting compression.

Features / Specifications

  • Supports random-access reads within stored files
  • Uses zstd compression (64KiB blocks)
  • Scales reasonably well up to multiple terabytes with millions of files
  • The theoretical size limit per-file is 2^48-1 (256 Terabyte)
  • The encoding for paths within the archive is Windows-1252 (case-insensitive)
  • Contains a SHA256 hash of the whole archive for integrity checks
  • Endian-independent. The format always uses big-endian internally
  • Stateless file and directory iterator handles which don't require memory allocation (not entirely true of the Rust bindings)

Rust Bindings

The zarchive crate provides Rust bindings to the C++ library. The API is intentionally limited. While most of the reader API is implemented, only a basic archive packing function is exposed for writing, due to complex safety considerations. The Rust bindings add some slight overhead to the reader's directory iteration API, but hopefully with a sufficient benefit of convenience.

Example - Pack and extract an archive

use zarchive::{pack, extract};
pack("/path/to/stuff/to/pack", "/path/to/archive.zar")?;
extract("/path/to/archive.zar", "/path/to/extract")?;

Limitations

  • Not designed for adding, removing or modifying files after the archive has been created

No-seek creation

When creating new archives only byte append operations are used. No file seeking is necessary. This makes it possible to create archives on storage which is write-once. It also simplifies streaming ZArchive creation over network.

UTF8 paths

UTF8 for file and folder paths is theoretically supported as paths are just binary blobs. But the case-insensitive comparison only applies to latin letters (a-z). The Rust bindings use the primitive &str type, which means that all paths passed through this API are UTF8.

Wii U specifics

Originally this format was created to store Wii U games dumps. These use the file extension .wua (Wii U Archive) but are otherwise regular ZArchive files. To allow multiple Wii U titles to be stored inside a single archive, each title must be placed in a subfolder following the naming scheme: 16-digit titleId followed by _v and then the version as decimal. For example: 0005000e10102000_v32

License

The zarchive crate is licensed under the GPL 3+. The original ZArchive library is licensed under MIT No Attribution, with the exception of sha_256.c and sha_256.h which are public domain, see: https://github.com/amosnier/sha-2.

Dependencies

~4MB
~82K SLoC