lotus_lib/cache_pair/
cache_pair_reader.rs1use std::fs::File;
2use std::io::{Read, Seek, SeekFrom};
3use std::path::PathBuf;
4
5use anyhow::Result;
6
7use crate::cache_pair::cache_pair::CachePair;
8use crate::compression::post_ensmallening::decompress_post_ensmallening;
9use crate::compression::pre_ensmallening::decompress_pre_ensmallening;
10use crate::toc::{FileNode, Node, Toc};
11
12pub struct CachePairReader {
14 is_post_ensmallening: bool,
15 toc_path: PathBuf,
16 cache_path: PathBuf,
17 toc: Toc,
18}
19
20impl CachePair for CachePairReader {
21 fn new(toc_path: PathBuf, cache_path: PathBuf, is_post_ensmallening: bool) -> Self {
22 let toc = Toc::new(toc_path.clone());
23 Self {
24 is_post_ensmallening,
25 toc_path,
26 cache_path,
27 toc,
28 }
29 }
30
31 fn is_post_ensmallening(&self) -> bool {
32 self.is_post_ensmallening
33 }
34
35 fn toc_path(&self) -> PathBuf {
36 self.toc_path.clone()
37 }
38
39 fn cache_path(&self) -> PathBuf {
40 self.cache_path.clone()
41 }
42
43 fn read_toc(&mut self) -> Result<()> {
44 self.toc.read_toc()
45 }
46
47 fn unread_toc(&mut self) {
48 self.toc.unread_toc()
49 }
50}
51
52impl CachePairReader {
53 pub fn get_directory_node<T: Into<PathBuf>>(&self, path: T) -> Option<Node> {
55 self.toc.get_directory_node(path.into())
56 }
57
58 pub fn get_file_node<T: Into<PathBuf>>(&self, path: T) -> Option<Node> {
60 self.toc.get_file_node(path.into())
61 }
62
63 pub fn directories(&self) -> &Vec<Node> {
65 self.toc.directories()
66 }
67
68 pub fn files(&self) -> &Vec<Node> {
70 self.toc.files()
71 }
72
73 pub fn get_data(&self, file_node: Node) -> Result<Vec<u8>> {
75 let mut cache_reader = File::open(self.cache_path.clone()).unwrap();
76 cache_reader
77 .seek(SeekFrom::Start(file_node.cache_offset() as u64))
78 .unwrap();
79
80 let mut data = vec![0; file_node.comp_len() as usize];
81 cache_reader.read_exact(&mut data).unwrap();
82 Ok(data)
83 }
84
85 pub fn decompress_data(&self, file_node: Node) -> Result<Vec<u8>> {
89 if file_node.comp_len() == file_node.len() {
90 return self.get_data(file_node);
91 }
92
93 let mut cache_reader = File::open(self.cache_path.clone()).unwrap();
94 cache_reader.seek(SeekFrom::Start(file_node.cache_offset() as u64))?;
95
96 if self.is_post_ensmallening {
97 return decompress_post_ensmallening(
98 file_node.comp_len() as usize,
99 file_node.len() as usize,
100 &mut cache_reader,
101 );
102 } else {
103 return decompress_pre_ensmallening(
104 file_node.comp_len() as usize,
105 file_node.len() as usize,
106 &mut cache_reader,
107 );
108 }
109 }
110}