Example #1
0
 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;
 }
Example #2
0
        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);
        }
Example #3
0
 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());
 }
Example #4
0
        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);
        }
Example #5
0
        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);