Skip to content

Commit

Permalink
Send errors in EntryType
Browse files Browse the repository at this point in the history
  • Loading branch information
szeweq committed May 13, 2024
1 parent a0e7a8f commit cfc1731
Show file tree
Hide file tree
Showing 5 changed files with 55 additions and 16 deletions.
4 changes: 2 additions & 2 deletions lib-core/src/entry/fs.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use std::{path::Path, fs};
use std::{fs, path::Path};
use crossbeam_channel::Sender;
use crate::{optimizer::EntryType, fop::FileOp};
use crate::{fop::FileOp, optimizer::EntryType};
use super::{EntryReader, EntrySaver, EntrySaverSpec};

/// An entry reader implementation for a file system. It reads a file tree from a provided directory.
Expand Down
11 changes: 9 additions & 2 deletions lib-core/src/entry/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,9 @@ impl<T: EntrySaverSpec> EntrySaver<T> {
let mut n = 0;
for et in rx {
match et {
EntryType::Error(name, e) => {
ev.collect(name, e);
}
EntryType::Count(u) => {
wrap_send(ps, ProgressState::Start(u))?;
}
Expand All @@ -66,11 +69,15 @@ impl<T: EntrySaverSpec> EntrySaver<T> {
&buf
}
};
self.0.save_file(&fname, buf, m.compress_min())?;
if let Err(e) = self.0.save_file(&fname, buf, m.compress_min()) {
ev.collect(fname.clone(), Box::new(e));
}
cv.clear();
}
FileOp::Recompress(x) => {
self.0.save_file(&fname, &buf, x as u16)?;
if let Err(e) = self.0.save_file(&fname, &buf, x as u16) {
ev.collect(fname.clone(), Box::new(e));
}
}
}
}
Expand Down
32 changes: 25 additions & 7 deletions lib-core/src/entry/zip.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
use std::{io::{Read, Seek, BufReader, Write, BufWriter}, sync::Arc};
use std::{io::{BufReader, BufWriter, Read, Seek, Write}, sync::Arc};
use crossbeam_channel::Sender;
use flate2::bufread::DeflateEncoder;
use zip::{ZipArchive, ZipWriter, write::FileOptions, CompressionMethod};

use crate::{optimizer::EntryType, fop::FileOp};
use crate::{fop::FileOp, optimizer::EntryType};
use super::{EntryReader, EntrySaverSpec, EntrySaver};

/// An entry reader implementation for ZIP archive. It reads its contents from a provided reader (with seeking).
Expand All @@ -16,13 +16,19 @@ impl <R: Read + Seek> ZipEntryReader<R> {
Self { r }
}
}
impl <R: Read + Seek> ZipEntryReader<BufReader<R>> {
/// Creates an entry reader wrapping a specified reader with a [BufReader].
pub fn new_buf(r: R) -> Self {
Self { r: BufReader::new(r) }
}
}
impl <R: Read + Seek> EntryReader for ZipEntryReader<R> {
fn read_entries(
self,
tx: Sender<EntryType>,
use_blacklist: bool
) -> crate::Result_<()> {
let mut za = ZipArchive::new(BufReader::new(self.r))?;
let mut za = ZipArchive::new(self.r)?;
let jfc = za.len();
super::wrap_send(&tx, EntryType::Count(jfc))?;
for i in 0..jfc {
Expand All @@ -34,9 +40,21 @@ impl <R: Read + Seek> EntryReader for ZipEntryReader<R> {
let fop = FileOp::by_name(&fname, use_blacklist);
let mut obuf = Vec::new();
if let FileOp::Ignore(_) = fop {} else {
let mut jf = za.by_index(i)?;
let mut jf = match za.by_index(i) {
Ok(jf) => jf,
Err(e) => {
super::wrap_send(&tx, EntryType::Error(fname, Box::new(e)))?;
continue
}
};
obuf.reserve_exact(jf.size() as usize);
jf.read_to_end(&mut obuf)?;
match jf.read_to_end(&mut obuf) {
Ok(_) => {},
Err(e) => {
super::wrap_send(&tx, EntryType::Error(fname, Box::new(e)))?;
continue
}
}
}
EntryType::File(fname, obuf.into(), fop)
})?;
Expand All @@ -48,7 +66,7 @@ impl <R: Read + Seek> EntryReader for ZipEntryReader<R> {
/// An entry saver implementation for ZIP archive. It writes entries to it using a provided writer.
pub struct ZipEntrySaver<W: Write + Seek> {
w: ZipWriter<BufWriter<W>>,
file_opts: FileOptions<()>
file_opts: FileOptions<'static, ()>
}
impl <W: Write + Seek> ZipEntrySaver<W> {
/// Creates an entry saver with a seekable writer.
Expand All @@ -59,7 +77,7 @@ impl <W: Write + Seek> ZipEntrySaver<W> {
})
}
/// Creates an entry saver with custom file options for ZIP archive and seekable writer.
pub fn custom(w: W, file_opts: FileOptions<()>) -> EntrySaver<Self> {
pub fn custom(w: W, file_opts: FileOptions<'static, ()>) -> EntrySaver<Self> {
EntrySaver(Self {
w: ZipWriter::new(BufWriter::new(w)), file_opts
})
Expand Down
6 changes: 4 additions & 2 deletions lib-core/src/optimizer.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use std::{fs::File, io::{self}, thread, path::Path, sync::Arc};
use std::{fs::File, io, path::Path, sync::Arc, thread};
use crossbeam_channel::{bounded, Sender};

use crate::{fop::FileOp, errors::ErrorCollector, entry::{self, EntryReader, EntrySaver, EntrySaverSpec}};
Expand Down Expand Up @@ -68,7 +68,9 @@ pub enum EntryType {
/// A directory with its path
Directory(Arc<str>),
/// A file with its path, data and file operation
File(Arc<str>, Box<[u8]>, FileOp)
File(Arc<str>, Box<[u8]>, FileOp),
/// An error
Error(Arc<str>, Box<dyn std::error::Error + Send>),
}
impl EntryType {
/// A shorthand function for creating a directory entry
Expand Down
18 changes: 15 additions & 3 deletions src/bin/mc-repack/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use cli_args::RepackOpts;
use crossbeam_channel::Sender;
use indicatif::{ProgressBar, ProgressStyle, MultiProgress};

use mc_repack_core::{optimizer::{ProgressState, optimize_archive}, fop::FileType, errors::{EntryRepackError, ErrorCollector}};
use mc_repack_core::{entry, errors::{EntryRepackError, ErrorCollector}, fop::FileType, optimizer::{optimize_archive, optimize_with, ProgressState}};

mod cli_args;

Expand Down Expand Up @@ -126,8 +126,20 @@ impl ProcessTask for JarDirRepackTask {
let Some(nfp) = new_path(out.as_ref(), &fp) else {
return Err(TaskError::InvalidFileName.into())
};
optimize_archive(fp.into_boxed_path(), nfp.into_boxed_path(), &ps, ec, use_blacklist)
.map_err(|e| wrap_err_with(e, &rde.path()))?;
match optimize_with(
entry::zip::ZipEntryReader::new_buf(fs::File::open(&fp)?),
entry::zip::ZipEntrySaver::new(fs::File::create(&nfp)?),
&ps, ec, use_blacklist
) {
Ok(_) => {},
Err(e) => {
ec.collect("", e.into());
//println!("Cannot repack {}: {}", fp.display(), e);
// if let Err(fe) = fs::remove_file(&nfp) {
// println!("Cannot remove {}: {}", nfp.display(), fe);
// }
}
}
}
}
mp.clear()?;
Expand Down

0 comments on commit cfc1731

Please sign in to comment.