This repository has no description
1use crate::data;
2
3pub(crate) const N32_SIZE: usize = std::mem::size_of::<u32>();
4
5/// Parses the first 12 bytes of a pack file, returning the pack version as well as the number of objects contained in the pack.
6pub fn decode(data: &[u8; 12]) -> Result<(data::Version, u32), decode::Error> {
7 let mut ofs = 0;
8 if &data[ofs..ofs + b"PACK".len()] != b"PACK" {
9 return Err(decode::Error::Corrupt(
10 "Pack data type not recognized".into(),
11 ));
12 }
13 ofs += N32_SIZE;
14 let kind = match crate::read_u32(&data[ofs..ofs + N32_SIZE]) {
15 2 => data::Version::V2,
16 3 => data::Version::V3,
17 v => return Err(decode::Error::UnsupportedVersion(v)),
18 };
19 ofs += N32_SIZE;
20 let num_objects = crate::read_u32(&data[ofs..ofs + N32_SIZE]);
21
22 Ok((kind, num_objects))
23}
24
25/// Write a pack data header at `version` with `num_objects` and return a buffer.
26pub fn encode(version: data::Version, num_objects: u32) -> [u8; 12] {
27 use crate::data::Version::*;
28 let mut buf = [0u8; 12];
29 buf[..4].copy_from_slice(b"PACK");
30 buf[4..8].copy_from_slice(
31 &match version {
32 V2 => 2u32,
33 V3 => 3,
34 }
35 .to_be_bytes()[..],
36 );
37 buf[8..].copy_from_slice(&num_objects.to_be_bytes()[..]);
38 buf
39}
40
41///
42pub mod decode {
43 /// Returned by [`decode()`][super::decode()].
44 #[derive(thiserror::Error, Debug)]
45 #[allow(missing_docs)]
46 pub enum Error {
47 #[error("Could not open pack file at '{path}'")]
48 Io {
49 source: std::io::Error,
50 path: std::path::PathBuf,
51 },
52 #[error("{0}")]
53 Corrupt(String),
54 #[error("Unsupported pack version: {0}")]
55 UnsupportedVersion(u32),
56 }
57}