Skip to content

Commit 4b0e79b

Browse files
committed
add EqArchiverReader experiment
1 parent 56ba69d commit 4b0e79b

File tree

1 file changed

+36
-0
lines changed
  • crates/libeq_archive/src

1 file changed

+36
-0
lines changed

crates/libeq_archive/src/lib.rs

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,43 @@ pub use parser::{Archive, Block, Directory, Footer, Header, IndexEntry};
3232

3333
const UNCOMPRESSED_BLOCK_SIZE: usize = 8192;
3434

35+
/// Provides read-only access to a S3D archive, decompressing data as it is requested
36+
#[derive(Debug)]
37+
38+
pub struct EqArchiveReader {
39+
pub filenames: Vec<String>,
40+
archive: Archive,
41+
}
42+
43+
impl EqArchiveReader {
44+
pub fn new<R: Read>(mut reader: R) -> Result<EqArchiveReader, Error> {
45+
let mut buffer = Vec::new();
46+
reader.read_to_end(&mut buffer)?;
47+
let mut archive = Archive::parse(&buffer[..])?.1;
48+
archive.index_entries.sort_by_key(|e| e.data_offset);
49+
let filenames = archive.filenames();
50+
Ok(EqArchiveReader { archive, filenames })
51+
}
52+
53+
pub fn get(&self, filename: &str) -> Result<Vec<u8>, Error> {
54+
let position = self
55+
.filenames
56+
.iter()
57+
.position(|f| f.eq_ignore_ascii_case(filename))
58+
.ok_or(Error::FileNotFound(filename.to_string()))?;
59+
let data = self
60+
.archive
61+
.index_entries
62+
.get(position)
63+
.map(|entry| entry.decompress(&self.archive.blocks))
64+
.ok_or(Error::FileNotFound(filename.to_string()))?;
65+
Ok(data)
66+
}
67+
}
68+
69+
/// Provides full read and write methods for Everquest S3D archives
3570
#[derive(Default, Debug)]
71+
3672
pub struct EqArchive {
3773
files: Vec<(String, Vec<u8>)>,
3874
}

0 commit comments

Comments
 (0)