1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
//! Building blocks for reading game files: checked byte reading, the hashes game files key their names by, vertex
//! layouts and attribute decoding, an ordered parallel map, sRGB and texture-sampling arithmetic, and (behind the
//! `compress` feature) the compression codecs games store their data in.
//!
//! The readers and decoders work on borrowed bytes and return a value or an error rather than panicking on malformed
//! input; the library modules do no file, environment or process access (the one exception, loading a native Oodle
//! library the caller names, is in `compress::oodle`). Each module states its conventions (byte order, normalization,
//! rounding) in its own documentation, because file formats differ on exactly those points.
//!
//! - [`bytes`]: bounds-checked [`View`](bytes::View) and [`Cursor`](bytes::Cursor) readers. The byte order is stated
//! on every multi-byte read, and a refused read reports the absolute offset it was at.
//! - [`hash`]: CRC-32, Adler-32 (from any start value), Jenkins one-at-a-time (case-folded and exact), MD5 with its
//! block function exposed, and SDBM. Inputs are never normalized.
//! - [`vertex`]: DXGI vertex element formats, layouts with explicit or appended offsets, stream decoding, packed
//! positions and tangents, and triangle-strip and index-buffer helpers.
//! - [`parallel`]: an ordered, panic-safe parallel map over independent items, with the thread count passed in.
//! - `scan` (Unix and Windows): many stored entries of a few large files read in the files' own order, in large
//! (on Windows unbuffered) reads on a stated number of threads, each entry handed to the caller on the thread that
//! read it: the whole-archive pass. The one module that reads files, by the paths its caller names.
//! - [`color`]: the sRGB transfer curve in `f64` and `f32` and its byte forms.
//! - [`sampling`]: texture sampling as GPUs define it: address modes, point, bilinear and trilinear filtering,
//! level of detail, 2D and 3D.
//! - `compress` (feature `compress`): one `Decompressor` / `Compressor` interface over LZ4, deflate, zlib, zstd,
//! LZMA, Brotli, LZO1X, LZO2A and Oodle, and a frame-by-frame LZX decoder. Every decode takes the exact expected
//! output size and refuses anything else.
//! - `sqlite` (feature `sqlite`): the tables of an SQLite 3 file image read whole, a table's columns and every row's
//! typed values, refusing what it does not read (a write-ahead log, a `WITHOUT ROWID` table, a damaged b-tree).
//!
//! # Example
//!
//! Read a small made-up record, then see what a truncated copy of it reports:
//!
//! ```
//! use primase_foundations::bytes::{Cursor, Endian, Field};
//! use primase_foundations::hash::crc32;
//!
//! // "DATA", a little-endian count of 2-byte entries, then the entries
//! let file = [b'D', b'A', b'T', b'A', 2, 0, 0, 0, 0x34, 0x12, 0x78, 0x56];
//!
//! let mut cursor = Cursor::new(&file);
//! assert_eq!(cursor.take(4)?, b"DATA");
//! let count = cursor.count(Endian::Little, 2)?; // refused unless that many entries fit
//! let mut entries = Vec::new();
//! for _ in 0..count {
//! entries.push(cursor.u16(Endian::Little)?);
//! }
//! assert_eq!(entries, [0x1234, 0x5678]);
//! assert_eq!(crc32(b"123456789"), 0xcbf4_3926);
//!
//! // cut short, the read is refused with the field and the offset
//! let mut cut = Cursor::new(&file[..6]);
//! cut.take(4)?;
//! let refusal = cut.count(Endian::Little, 2).field("entry count").unwrap_err();
//! assert_eq!(refusal.to_string(), "entry count at 0x4: 4 bytes run past the end of 6");
//! # Ok::<(), Box<dyn std::error::Error>>(())
//! ```
// A reader of stored bytes never panics, wraps or truncates silently: every index, sum and narrowing is checked and
// reports an error. Unit tests build their fixtures by index and are exempt.
/// This crate's source files as `(name, bytes)`, for a caller that keys a disk cache by the code that computed its
/// values: hashing them retires cached entries when any of them changes. A test keeps the list equal to the `src`
/// folder.
pub const SOURCES: & = &;
// The real-data inputs this crate's unit tests read (tests/inputs/mod.rs).
/// Makes `cargo test` compile and run the README's example.
;