casc_storage/archive/
mod.rs1mod archive_reader;
4mod archive_writer;
5
6pub use archive_reader::ArchiveReader;
7pub use archive_writer::ArchiveWriter;
8
9use crate::error::Result;
10use crate::types::ArchiveLocation;
11use std::borrow::Cow;
12use std::path::{Path, PathBuf};
13
14pub struct Archive {
16 pub id: u16,
18 pub path: PathBuf,
20 pub size: u64,
22 reader: Option<ArchiveReader>,
24}
25
26impl Archive {
27 pub fn new(id: u16, path: PathBuf) -> Result<Self> {
29 let size = if path.exists() {
30 std::fs::metadata(&path)?.len()
31 } else {
32 0
33 };
34
35 Ok(Self {
36 id,
37 path,
38 size,
39 reader: None,
40 })
41 }
42
43 pub fn open(&mut self) -> Result<&mut ArchiveReader> {
45 if self.reader.is_none() {
46 self.reader = Some(ArchiveReader::open(&self.path)?);
47 }
48 Ok(self.reader.as_mut().unwrap())
49 }
50
51 pub fn read_at_cow(&self, location: &ArchiveLocation) -> Result<Cow<'_, [u8]>> {
53 if let Some(ref reader) = self.reader {
54 reader.read_at_cow(location.offset, location.size as usize)
55 } else {
56 let mut reader = ArchiveReader::open(&self.path)?;
58 let data = reader.read_at(location.offset, location.size as usize)?;
59 Ok(Cow::Owned(data))
60 }
61 }
62
63 pub fn read_at(&mut self, location: &ArchiveLocation) -> Result<Vec<u8>> {
65 let reader = self.open()?;
66 reader.read_at(location.offset, location.size as usize)
67 }
68
69 pub fn contains(&self, location: &ArchiveLocation) -> bool {
71 location.archive_id == self.id && location.offset + location.size as u64 <= self.size
72 }
73
74 pub fn filename(&self) -> String {
76 format!("data.{:03}", self.id)
77 }
78
79 pub fn path(&self) -> &Path {
81 &self.path
82 }
83}