public GatheringExtractor(Stream stream, Definitions.FileType sig, Predicate <RelativePath> shouldExtract, Func <RelativePath, IStreamFactory, ValueTask <T> > mapfn) { _shouldExtract = shouldExtract; _mapFn = mapfn; _results = new Dictionary <RelativePath, T>(); _stream = stream; _sig = sig; }
public static async Task <ArchiveFile> Open(Stream archiveStream, Definitions.FileType format) { var self = new ArchiveFile(); self.InitializeAndValidateLibrary(); self._archive = self._sevenZipHandle.CreateInArchive(Formats.FileTypeGuidMapping[format]); if (!FileExtractor2.FavorPerfOverRAM) { self.SetCompressionProperties(new Dictionary <string, string>() { { "mt", "off" } }); } self._archiveStream = new InStreamWrapper(archiveStream); return(self); }
private static async Task <Dictionary <RelativePath, T> > GatheringExtractWith7Zip <T>(Stream stream, Definitions.FileType sig, Predicate <RelativePath> shouldExtract, Func <RelativePath, IStreamFactory, ValueTask <T> > mapfn) { return(await new GatheringExtractor <T>(stream, sig, shouldExtract, mapfn).Extract()); }
private static async Task <Dictionary <RelativePath, T> > GatheringExtractWithBSA <T>(IStreamFactory sFn, Definitions.FileType sig, Predicate <RelativePath> shouldExtract, Func <RelativePath, IStreamFactory, ValueTask <T> > mapfn) { var archive = await BSADispatch.OpenRead(sFn, sig); var results = new Dictionary <RelativePath, T>(); foreach (var entry in archive.Files) { if (!shouldExtract(entry.Path)) { continue; } var result = await mapfn(entry.Path, await entry.GetStreamFactory()); results.Add(entry.Path, result); } return(results); }
private static async Task <Dictionary <RelativePath, T> > GatheringExtractWith7Zip <T>(WorkQueue queue, IStreamFactory sf, Definitions.FileType sig, Predicate <RelativePath> shouldExtract, Func <RelativePath, IExtractedFile, ValueTask <T> > mapfn, AbsolutePath tempPath, HashSet <RelativePath> onlyFiles) { TempFile tmpFile = null; var dest = tempPath.Combine(Guid.NewGuid().ToString()); dest.CreateDirectory(); TempFile spoolFile = null; AbsolutePath source; try { if (sf.Name is AbsolutePath abs) { source = abs; } else { spoolFile = new TempFile(tempPath.Combine(Guid.NewGuid().ToString()) .WithExtension(source.Extension)); await using var s = await sf.GetStream(); await spoolFile.Path.WriteAllAsync(s); source = spoolFile.Path; } Utils.Log(new GenericInfo($"Extracting {(string)source.FileName}", $"The contents of {(string)source.FileName} are being extracted to {(string)source.FileName} using 7zip.exe")); var process = new ProcessHelper { Path = @"Extractors\7z.exe".RelativeTo(AbsolutePath.EntryPoint), }; if (onlyFiles != null) { //It's stupid that we have to do this, but 7zip's file pattern matching isn't very fuzzy IEnumerable <string> AllVariants(string input) { yield return($"\"{input}\""); yield return($"\"\\{input}\""); } tmpFile = new TempFile(); await tmpFile.Path.WriteAllLinesAsync(onlyFiles.SelectMany(f => AllVariants((string)f)).ToArray()); process.Arguments = new object[] { "x", "-bsp1", "-y", $"-o\"{dest}\"", source, $"@\"{tmpFile.Path}\"", "-mmt=off" }; } else { process.Arguments = new object[] { "x", "-bsp1", "-y", $"-o\"{dest}\"", source, "-mmt=off" }; } var result = process.Output.Where(d => d.Type == ProcessHelper.StreamType.Output) .ForEachAsync(p => { var(_, line) = p; if (line == null) { return; } if (line.Length <= 4 || line[3] != '%') { return; } int.TryParse(line.Substring(0, 3), out var percentInt); Utils.Status($"Extracting {(string)source.FileName} - {line.Trim()}", Percent.FactoryPutInRange(percentInt / 100d)); }); var exitCode = await process.Start(); if (exitCode != 0) { Utils.ErrorThrow(new _7zipReturnError(exitCode, source, dest, "")); } else { Utils.Status($"Extracting {source.FileName} - done", Percent.One, alsoLog: true); } var results = await dest.EnumerateFiles() .PMap(queue, async f => { var path = f.RelativeTo(dest); if (!shouldExtract(path)) { return(((RelativePath, T)) default);