Skip to content

Commit

Permalink
Reimplement saving and reporting
Browse files Browse the repository at this point in the history
  • Loading branch information
szeweq committed Jul 12, 2024
1 parent f9e1d3b commit 3a7a31d
Show file tree
Hide file tree
Showing 2 changed files with 90 additions and 74 deletions.
69 changes: 38 additions & 31 deletions lib-core/src/entry/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -92,42 +92,49 @@ pub trait EntrySaver {
mut ps: impl FnMut(ProgressState) -> crate::Result_<()>,
) -> crate::Result_<()> where Self: Sized {
let mut cv = Vec::new();
let mut n = 0;
for NamedEntry(name, et) in rx {
match et {
EntryType::Directory => {
self.save(&name, SavingEntry::Directory)?;
for (n, ne) in rx.into_iter().enumerate() {
ps(ProgressState::Push(n, ne.0.clone()))?;
if let Some(se) = process_entry(&mut cv, &ne, ev, cfgmap) {
self.save(&ne.0, se)?;
}
}
ps(ProgressState::Finish)
}
}

/// Saves an entry with the [`EntrySaver`].
pub fn process_entry<'a>(
cbuf: &'a mut Vec<u8>,
NamedEntry(name, et): &'a NamedEntry,
ev: &mut ErrorCollector,
cfgmap: &cfg::ConfigMap,
) -> Option<SavingEntry<'a>> {
let se = match et {
EntryType::Directory => SavingEntry::Directory,
EntryType::File(buf, fop) => {
match fop {
FileOp::Ignore(e) => {
ev.collect(name.clone(), e.clone().into());
return None;
}
EntryType::File(buf, fop) => {
ps(ProgressState::Push(n, name.clone()))?;
n += 1;
match fop {
FileOp::Ignore(e) => {
ev.collect(name.clone(), e.into());
FileOp::Minify(m) => {
let buf: &[u8] = match m.minify(cfgmap, buf, cbuf) {
Ok(()) => cbuf,
Err(e) => {
ev.collect(name.clone(), e);
buf
}
FileOp::Minify(m) => {
let buf: &[u8] = match m.minify(cfgmap, &buf, &mut cv) {
Ok(()) => &cv,
Err(e) => {
ev.collect(name.clone(), e);
&buf
}
};
self.save(&name, SavingEntry::File(buf, m.compress_min()))?;
cv.clear();
}
FileOp::Recompress(x) => {
self.save(&name, SavingEntry::File(&buf, x as u16))?;
}
FileOp::Pass => {
self.save(&name, SavingEntry::File(&buf, 24))?;
}
}
};
SavingEntry::File(buf, m.compress_min())
}
FileOp::Recompress(x) => SavingEntry::File(buf, *x as u16),
FileOp::Pass => SavingEntry::File(buf, 24)
}
}
ps(ProgressState::Finish)
}
};
Some(se)
//saver.save(&name, se)?;
//Ok(())
}

/// An entry with its name and type.
Expand Down
95 changes: 52 additions & 43 deletions src/bin/mc-repack/main.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
use std::{fs, path::Path, sync::Arc};
use clap::Parser;
use cli_args::{Cmd, FilesArgs, JarsArgs, RepackOpts};
use crossbeam_channel::Sender;
use crossbeam_channel::{Receiver, Sender};
use indicatif::{ProgressBar, ProgressStyle, MultiProgress};

use mc_repack_core::{cfg, entry::{self, read_entry, EntryReader, EntrySaver}, errors::ErrorCollector, fop::TypeBlacklist, ProgressState};
use mc_repack_core::{cfg, entry::{self, process_entry, read_entry, EntryReader, EntrySaver, NamedEntry, ReadEntryIter}, errors::ErrorCollector, fop::TypeBlacklist, ProgressState};

mod cli_args;
mod config;
Expand Down Expand Up @@ -92,8 +92,8 @@ fn process_jars(base: &Path, fit: FilesIter, jargs: &JarsArgs, opts: &mut Repack
db.create(np)?;
}
match optimize_with(
entry::ZipEntryReader::new_mem(fs::read(&fp)?)?,
entry::ZipEntrySaver::custom_compress(
&mut entry::ZipEntryReader::new_mem(fs::read(&fp)?)?,
&mut entry::ZipEntrySaver::custom_compress(
fs::File::create(&nfp)?,
jargs.keep_dirs,
clvl
Expand All @@ -102,17 +102,7 @@ fn process_jars(base: &Path, fit: FilesIter, jargs: &JarsArgs, opts: &mut Repack
) {
Ok(()) => {
if let Some(ref mut report) = opts.report {
match (fs::metadata(&fp), fs::metadata(&nfp)) {
(Ok(fm), Ok(nm)) => {
report.push(&relname, fm.len(), nm.len());
}
(Err(e), Ok(_)) | (Ok(_), Err(e)) => {
println!("Cannot report {}: {}", relname, e);
}
(Err(e1), Err(e2)) => {
println!("Cannot report {}: {}, {}", relname, e1, e2);
}
}
report_sizes(report, &relname, &fp, &nfp);
}
},
Err(e) => {
Expand All @@ -136,8 +126,8 @@ fn process_files(base: &Path, fit: FilesIter, fargs: &FilesArgs, opts: &mut Repa
let pb2 = file_progress_bar();
let ps = thread_progress_bar(pb2);
optimize_with(
entry::FSEntryReader::custom(base.into(), fit),
entry::FSEntrySaver::new(fargs.out.clone().into_boxed_path()),
&mut entry::FSEntryReader::custom(base.into(), fit),
&mut entry::FSEntrySaver::new(fargs.out.clone().into_boxed_path()),
cfgmap, &ps, ec, blacklist.clone()
)?;
drop(ps);
Expand All @@ -154,22 +144,26 @@ fn files_report(report: &mut report::Report, path: &Path, out: &Path) -> Result_
let relname = relp.to_string_lossy();
if matches!(ftype, Some(false)) {
let nfp = out.join(&relp);
match (fs::metadata(&fp), fs::metadata(&nfp)) {
(Ok(fm), Ok(nm)) => {
report.push(&relname, fm.len(), nm.len());
}
(Err(e), Ok(_)) | (Ok(_), Err(e)) => {
println!("Cannot report {}: {}", relname, e);
}
(Err(e1), Err(e2)) => {
println!("Cannot report {}: {}, {}", relname, e1, e2);
}
}
report_sizes(report, &relname, &fp, &nfp);
}
}
Ok(())
}

fn report_sizes(report: &mut report::Report, relname: &str, fp: &Path, nfp: &Path) {
match (fs::metadata(fp), fs::metadata(nfp)) {
(Ok(fm), Ok(nm)) => {
report.push(relname, fm.len(), nm.len());
}
(Err(e), Ok(_)) | (Ok(_), Err(e)) => {
println!("Cannot report {}: {}", relname, e);
}
(Err(e1), Err(e2)) => {
println!("Cannot report {}: {}, {}", relname, e1, e2);
}
}
}

fn thread_progress_bar(pb: ProgressBar) -> Sender<ProgressState> {
let (ps, pr) = crossbeam_channel::unbounded();
rayon::spawn(move || {
Expand Down Expand Up @@ -200,8 +194,8 @@ fn print_entry_errors(ec: &ErrorCollector) {
}

pub fn optimize_with<R: EntryReader + Send + 'static, S: EntrySaver + Send + 'static>(
reader: R,
saver: S,
reader: &mut R,
saver: &mut S,
cfgmap: &cfg::ConfigMap,
ps: &Sender<ProgressState>,
errors: &mut ErrorCollector,
Expand All @@ -215,20 +209,13 @@ pub fn optimize_with<R: EntryReader + Send + 'static, S: EntrySaver + Send + 'st
let r1 = &mut r1;
let r2 = &mut r2;
s.spawn_fifo(move |_| {
let mut reader = reader;
for re in reader.read_iter() {
let r = match read_entry::<R>(re, &blacklist) {
Ok(Some(ne)) => wrap_send(&tx, ne),
Ok(None) => Ok(()),
Err(e) => Err(e),
};
if let Err(e) = r {
*r1 = Err(e);
break;
}
}
//let mut reader = reader;
*r1 = reading(reader.read_iter(), tx, blacklist)
});
s.spawn_fifo(move |_| {
//let mut saver = saver;
*r2 = saving(saver, rx, ps, errors, cfgmap)
});
s.spawn_fifo(move |_| *r2 = saver.save_entries(rx, errors, cfgmap, |p| wrap_send(ps, p)));
});
match (r1, r2) {
(Ok(_), Ok(_)) => Ok(()),
Expand All @@ -237,6 +224,28 @@ pub fn optimize_with<R: EntryReader + Send + 'static, S: EntrySaver + Send + 'st
}
}

fn reading<R: EntryReader>(iter: ReadEntryIter<R>, tx: Sender<NamedEntry>, blacklist: Arc<TypeBlacklist>) -> Result_<()> {
for re in iter {
if let Some(ne) = read_entry::<R>(re, &blacklist)? {
wrap_send(&tx, ne)?;
};
}
Ok(())
}
fn saving<S: EntrySaver>(saver: &mut S, rx: Receiver<NamedEntry>, ps: &Sender<ProgressState>, errors: &mut ErrorCollector, cfgmap: &cfg::ConfigMap) -> Result_<()> {
let mut cv = Vec::new();
for (n, ne) in rx.into_iter().enumerate() {
wrap_send(ps, ProgressState::Push(n, ne.0.clone()))?;
if let Some(se) = process_entry(&mut cv, &ne, errors, cfgmap) {
saver.save(&ne.0, se)?;
if !cv.is_empty() {
cv.clear();
}
}
}
wrap_send(ps, ProgressState::Finish)
}

fn wrap_send<T>(s: &Sender<T>, t: T) -> Result_<()> {
s.send(t).map_err(|_| anyhow::anyhow!("channel closed early"))
}
Expand Down

0 comments on commit 3a7a31d

Please sign in to comment.