11use std:: {
22 collections:: HashMap ,
3- io:: { Cursor , Write } ,
3+ io:: { Cursor , Read , Write } ,
4+ ops:: DerefMut ,
5+ sync:: { Arc , Mutex } ,
46} ;
57
68use binrw:: { binrw, BinRead , BinWrite } ;
79use common:: { SeekRead , SeekWrite } ;
10+ use mini_fs:: File ;
811
9- use crate :: memory_file:: MemoryFile ;
12+ use crate :: { memory_file:: MemoryFile , streaming_file :: StreamingFile } ;
1013
1114pub struct YpkArchive {
12- reader : Box < dyn SeekRead > ,
15+ reader : Arc < Mutex < dyn SeekRead + Send + Sync > > ,
1316 pub entries : Vec < YpkEntry > ,
1417 entries_hash : HashMap < u64 , Vec < usize > > ,
1518}
1619
1720impl YpkArchive {
18- pub fn load ( mut reader : Box < dyn SeekRead > ) -> anyhow:: Result < Self > {
19- let header = YpkHeader :: read ( & mut reader) ?;
21+ pub fn load ( file : Arc < Mutex < dyn SeekRead + Send + Sync > > ) -> anyhow:: Result < Self > {
22+ let mut reader = file. lock ( ) . unwrap ( ) ;
23+ let header = YpkHeader :: read ( & mut reader. deref_mut ( ) ) ?;
2024
2125 reader. seek ( std:: io:: SeekFrom :: Start ( header. entry_offset ) ) ?;
2226 let mut entries = Vec :: with_capacity ( header. entry_count as usize ) ;
2327 for _ in 0 ..header. entry_count {
24- entries. push ( YpkEntry :: read ( & mut reader) ?) ;
28+ entries. push ( YpkEntry :: read ( & mut reader. deref_mut ( ) ) ?) ;
2529 }
2630
2731 let mut entries_hash = HashMap :: new ( ) ;
@@ -32,31 +36,44 @@ impl YpkArchive {
3236 . push ( i) ;
3337 }
3438
39+ drop ( reader) ;
40+
3541 Ok ( Self {
36- reader,
42+ reader : file ,
3743 entries,
3844 entries_hash,
3945 } )
4046 }
4147
42- pub fn open ( & mut self , name : & str ) -> std:: io:: Result < MemoryFile > {
43- let ( offset, actual_size) = {
48+ pub fn open ( & mut self , name : & str ) -> std:: io:: Result < File > {
49+ let ( offset, actual_size, is_compressed ) = {
4450 let entry = self . get_entry ( name) . ok_or_else ( || {
4551 std:: io:: Error :: new (
4652 std:: io:: ErrorKind :: NotFound ,
4753 format ! ( "Entry {:?} not found" , name) ,
4854 )
4955 } ) ?;
5056
51- ( entry. offset , entry. actual_size )
57+ ( entry. offset , entry. actual_size , entry . is_compressed == 1 )
5258 } ;
5359
54- self . reader . seek ( std:: io:: SeekFrom :: Start ( offset) ) ?;
60+ /*let mut reader = self.reader.lock().unwrap();
61+ reader.seek(std::io::SeekFrom::Start(offset))?;
5562 let mut buf = vec![0; actual_size as usize];
56- self . reader . read_exact ( & mut buf) ?;
57-
58- let buf = zstd:: stream:: decode_all :: < & [ u8 ] > ( buf. as_ref ( ) ) ;
59- Ok ( MemoryFile :: new ( Cursor :: new ( buf. unwrap ( ) ) ) )
63+ reader.read_exact(&mut buf)?;*/
64+
65+ let mut streaming =
66+ StreamingFile :: new ( self . reader . clone ( ) , offset, offset + actual_size as u64 ) ;
67+
68+ if is_compressed {
69+ let buf = zstd:: stream:: decode_all ( & mut streaming) ?;
70+ return Ok ( MemoryFile :: new ( Cursor :: new ( buf) ) . into ( ) ) ;
71+ } else {
72+ /*let mut buf = Vec::new();
73+ streaming.read_to_end(&mut buf)?;
74+ return Ok(MemoryFile::new(Cursor::new(buf)).into());*/
75+ return Ok ( streaming. into ( ) ) ;
76+ }
6077 }
6178
6279 fn get_entry ( & self , name : & str ) -> Option < & YpkEntry > {
@@ -102,6 +119,7 @@ pub struct YpkEntry {
102119 name : Vec < u8 > ,
103120
104121 offset : u64 ,
122+ is_compressed : u32 ,
105123 original_size : u32 ,
106124 actual_size : u32 ,
107125}
@@ -129,17 +147,22 @@ impl YpkWriter {
129147 let offset = self . writer . stream_position ( ) ?;
130148 let original_size = data. len ( ) as u32 ;
131149
150+ let ( is_compressed, data) = if name. ends_with ( ".bik" ) {
151+ ( false , data. to_vec ( ) )
152+ } else {
153+ ( true , zstd:: stream:: encode_all ( data, 0 ) ?)
154+ } ;
155+
132156 let name = normorlize_path ( name) ;
133157 let name_for_hash = name. to_lowercase ( ) ;
134158 let name = name. as_bytes ( ) ;
135159
136- let data = zstd:: stream:: encode_all ( data, 0 ) ?;
137-
138160 self . entries . push ( YpkEntry {
139161 hash : xxhash_rust:: xxh3:: xxh3_64 ( name_for_hash. as_bytes ( ) ) ,
140162 name_len : name. len ( ) as u32 ,
141163 name : name. to_vec ( ) ,
142164 offset,
165+ is_compressed : is_compressed as u32 ,
143166 original_size,
144167 actual_size : data. len ( ) as u32 ,
145168 } ) ;
0 commit comments