xrw/lib.rs
1/*!
2A library for structural I/O across binary formats.
3
4`xrw` treats any binary format whose data is organized into discrete, bounded units as a
5container. These units, whether called chunks, atoms, boxes, elements, pages, or frames,
6share a common shape: an identifying marker, a size, and a payload. The size may be stored
7explicitly in the block header, fixed by the format specification, or derivable from header
8fields. Regardless, `xrw` represents every unit as a [`Block`].
9
10# Approach
11
12Each container family is described by a [`Descriptor`], which stores byte order, identifier
13width, size field width, and alignment boundaries. All reading and writing behaviour is derived
14from this descriptor, making it straightforward to support new formats without changes to the
15core traversal logic.
16
17When given a stream, `xrw` reads the magic bytes to identify the container [`Family`] and,
18where the format specifies it, its [`Kind`]. From there, the container header is parsed and
19the stream is traversed block by block, recording each block's identifier, offset, payload
20offset, and size into a [`Structure`]. Payloads are not read or copied.
21
22The resulting [`Structure`] can be queried and manipulated freely. Reordering, removing, or
23swapping blocks operates only on the in-memory block index. Regardless of how large the file is,
24the cost of manipulation is negligible since no payload data is involved. Since every [`Block`]
25retains its absolute offset into the original stream, the block index acts as a complete description
26of what the output file should look like. To apply changes, [`Structure::write_from`] reads each
27payload directly from its stored offset and writes it to a new file in the current block order,
28handling size fields, padding, and alignment automatically.
29
30Currently supported container families include RIFF, IFF, RF64, BW64, and Sony Wave64.
31Support for QuickTime/ISOBMFF, PNG, JPEG, EBML/Matroska, FLAC, Ogg, TIFF/IFD, ASF, MXF,
32and more is planned.
33
34# Overview
35
36[`Structure`] is the primary struct, representing the parsed result of a binary file. It
37exposes the complete block index alongside the detected family, descriptor, and any
38family-specific metadata such as [`DataSize64`] for RF64 and BW64 files.
39```rust
40let mut reader = Reader::open("audio.wav")?;
41let structure = Structure::read(&mut reader, &ReadOptions::default())?;
42
43if let Some(fmt) = structure.find(Marker::FourCC(*b"fmt ")) {
44 let payload = structure.read_payload(&mut reader, fmt)?;
45}
46```
47
48Supported operations include reading and writing containers, block manipulation, finding and
49querying, padding and alignment, and container conversion. See [`Structure`] for the complete
50list.
51# Related
52
53- [`quickparse`](https://github.com/) — minimal essential chunk extraction for audio formats.
54- [`coreav`](https://github.com/) — comprehensive metadata reading and manipulation for audio and video formats.
55- [`xver`](https://github.com/) — specification compliance checking for audio and video formats.
56*/
57
58pub mod block;
59pub mod descriptor;
60pub mod family;
61pub mod kind;
62pub mod marker;
63pub mod reader;
64pub mod structure;
65
66pub use block::Block;
67pub use descriptor::Descriptor;
68pub use family::Family;
69pub use kind::Kind;
70pub use marker::Marker;
71pub use reader::Reader;
72pub use structure::Structure;
73
74use thiserror::Error;
75
76#[derive(Debug, Clone, Copy, PartialEq, Eq)]
77pub enum Byteorder {
78 Big,
79 Little,
80}
81
82#[derive(Debug, Error)]
83pub enum Error {
84 #[error("io error: {0}")]
85 Io(#[from] std::io::Error),
86
87 #[error("unknown container")]
88 UnknownContainer,
89
90 #[error("unexpected end of stream")]
91 UnexpectedEof,
92}
93
94pub type Result<T> = std::result::Result<T, Error>;