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
//! A pure-Rust reader for CHM (Compiled HTML Help) archives.
//!
//! [`ChmFile`] opens a `.chm` file, parses its ITSF/ITSP header and PMGL/PMGI directory,
//! and lets you look up entries by path, enumerate them, and read their (possibly
//! LZX-compressed) contents.
//!
//! ```no_run
//! use libchm::{ChmFile, EntrySel};
//!
//! # fn main() -> libchm::Result<()> {
//! let mut chm = ChmFile::open("docs.chm")?;
//! for entry in chm.entries(EntrySel::ALL)? {
//! println!("{}", entry.path);
//! }
//! let bytes = chm.read_path("/index.html")?;
//! println!("index size: {}", bytes.len());
//! # Ok(())
//! # }
//! ```
//!
//! # Paths
//!
//! Entry paths are absolute within the archive and matched case-insensitively, so
//! `/Index.html` and `/index.html` name the same entry. Directory entries end with `/`.
//!
//! # Selecting entries
//!
//! [`EntrySel`] filters enumeration by namespace category (`NORMAL`, `SPECIAL`, `META`)
//! and by kind (`FILES`, `DIRS`). An entry matches only if the selector names both its
//! category and its kind, so use [`EntrySel::ALL`] for everything, or combine flags:
//!
//! ```no_run
//! # use libchm::{ChmFile, EntrySel};
//! # fn main() -> libchm::Result<()> {
//! # let mut chm = ChmFile::open("docs.chm")?;
//! // Ordinary content files, skipping directories and CHM-internal metadata.
//! let pages = chm.entries(EntrySel::NORMAL | EntrySel::FILES)?;
//! # Ok(())
//! # }
//! ```
//!
//! # Robustness
//!
//! Archives are untrusted input. Every header field that feeds an allocation, an index,
//! or a divisor is validated before use, and malformed files are reported as a
//! [`ChmError`] rather than causing a panic.
pub use ChmFile;
pub use ;
pub use ;