Skip to main content

gix_chunk/
lib.rs

1//! Low-level access to reading and writing chunk file based formats.
2//!
3//! See the [git documentation](https://github.com/git/git/blob/seen/Documentation/technical/chunk-format.txt) for details.
4//!
5//! ## Examples
6//!
7//! ```
8//! # fn main() -> Result<(), Box<dyn std::error::Error>> {
9//! use std::io::Write;
10//!
11//! let mut index = gix_chunk::file::Index::for_writing();
12//! index.plan_chunk(*b"OIDF", 4);
13//! index.plan_chunk(*b"DATA", 3);
14//!
15//! let mut out = index.into_write(Vec::new(), 0)?;
16//! while let Some(kind) = out.next_chunk() {
17//!     match kind {
18//!         [b'O', b'I', b'D', b'F'] => out.write_all(b"abcd")?,
19//!         [b'D', b'A', b'T', b'A'] => out.write_all(b"xyz")?,
20//!         _ => unreachable!("planned chunks are known"),
21//!     }
22//! }
23//!
24//! let data = out.into_inner();
25//! let decoded = gix_chunk::file::Index::from_bytes(&data, 0, 2)?;
26//! assert_eq!(decoded.data_by_id(&data, *b"OIDF")?, b"abcd");
27//! assert_eq!(decoded.data_by_id(&data, *b"DATA")?, b"xyz");
28//! # Ok(()) }
29//! ```
30#![deny(missing_docs, rust_2018_idioms, unsafe_code)]
31
32/// An identifier to describe the kind of chunk, unique within a chunk file, typically in ASCII
33pub type Id = [u8; 4];
34
35/// A special value denoting the end of the chunk file table of contents.
36pub const SENTINEL: Id = [0u8; 4];
37
38///
39pub mod range {
40    use std::ops::Range;
41
42    use crate::file;
43
44    /// Turn a u64 Range into a usize range safely, to make chunk ranges useful in memory mapped files.
45    pub fn into_usize(Range { start, end }: Range<file::Offset>) -> Option<Range<usize>> {
46        let start = start.try_into().ok()?;
47        let end = end.try_into().ok()?;
48        Some(Range { start, end })
49    }
50
51    /// Similar to [`into_usize()`], but panics assuming that the memory map couldn't be created if offsets
52    /// stored are too high.
53    ///
54    /// This is only true for correctly formed files, as it's entirely possible to provide out of bounds offsets
55    /// which are checked for separately - we wouldn't be here if that was the case.
56    pub fn into_usize_or_panic(range: Range<file::Offset>) -> Range<usize> {
57        into_usize(range).expect("memory maps can't be created if files are too large")
58    }
59}
60
61///
62pub mod file;