Mercurial > touhou
comparison src/th06/pbg3.rs @ 746:0ebf6467e4ff
examples: Add a menu example.
author | Emmanuel Gil Peyrot <linkmauve@linkmauve.fr> |
---|---|
date | Sat, 18 Jan 2020 19:19:51 +0100 |
parents | 7bde50132735 |
children |
comparison
equal
deleted
inserted
replaced
745:90e907859bae | 746:0ebf6467e4ff |
---|---|
6 //! PBG3 files are merely a bitstream composed of a header, a file | 6 //! PBG3 files are merely a bitstream composed of a header, a file |
7 //! table, and LZSS-compressed files. | 7 //! table, and LZSS-compressed files. |
8 | 8 |
9 use crate::util::bitstream::BitStream; | 9 use crate::util::bitstream::BitStream; |
10 use crate::util::lzss; | 10 use crate::util::lzss; |
11 use std::fs::File; | |
11 use std::io; | 12 use std::io; |
12 use std::collections::hash_map::{self, HashMap}; | 13 use std::collections::hash_map::{self, HashMap}; |
14 use std::path::Path; | |
13 | 15 |
14 /// Helper struct to handle strings and integers in PBG3 bitstreams. | 16 /// Helper struct to handle strings and integers in PBG3 bitstreams. |
15 pub struct PBG3BitStream<R: io::Read + io::Seek> { | 17 pub struct PBG3BitStream<R: io::Read + io::Seek> { |
16 bitstream: BitStream<R>, | 18 bitstream: BitStream<R>, |
17 } | 19 } |
130 pub fn list_files(&self) -> hash_map::Keys<String, Entry> { | 132 pub fn list_files(&self) -> hash_map::Keys<String, Entry> { |
131 self.entries.keys() | 133 self.entries.keys() |
132 } | 134 } |
133 | 135 |
134 /// Read a single file from this PBG3 archive. | 136 /// Read a single file from this PBG3 archive. |
135 pub fn get_file(&mut self, filename: String, check: bool) -> io::Result<Vec<u8>> { | 137 pub fn get_file(&mut self, filename: &str, check: bool) -> io::Result<Vec<u8>> { |
136 // XXX: no unwrap! | 138 // XXX: no unwrap! |
137 let (_unknown_1, _unknown_2, checksum, offset, size) = self.entries.get(&filename).unwrap(); | 139 let (_unknown_1, _unknown_2, checksum, offset, size) = self.entries.get(filename).unwrap(); |
138 self.bitstream.seek(io::SeekFrom::Start(*offset as u64))?; | 140 self.bitstream.seek(io::SeekFrom::Start(*offset as u64))?; |
139 let data = lzss::decompress(&mut self.bitstream.bitstream, *size as usize, 0x2000, 13, 4, 3)?; | 141 let data = lzss::decompress(&mut self.bitstream.bitstream, *size as usize, 0x2000, 13, 4, 3)?; |
140 if check { | 142 if check { |
141 // Verify the checksum. | 143 // Verify the checksum. |
142 let compressed_size = self.bitstream.tell()? as u32 - *offset; | 144 let compressed_size = self.bitstream.tell()? as u32 - *offset; |
150 return Err(io::Error::new(io::ErrorKind::Other, "Corrupted data!")); | 152 return Err(io::Error::new(io::ErrorKind::Other, "Corrupted data!")); |
151 } | 153 } |
152 } | 154 } |
153 Ok(data) | 155 Ok(data) |
154 } | 156 } |
157 } | |
158 | |
159 /// Open a PBG3 archive from its path. | |
160 pub fn from_path_buffered<P: AsRef<Path>>(path: P) -> io::Result<PBG3<io::BufReader<File>>> { | |
161 let file = File::open(path)?; | |
162 let buf_file = io::BufReader::new(file); | |
163 PBG3::from_file(buf_file) | |
155 } | 164 } |
156 | 165 |
157 #[cfg(test)] | 166 #[cfg(test)] |
158 mod tests { | 167 mod tests { |
159 use super::*; | 168 use super::*; |