/// <summary> /// Extract the Stream given. /// </summary> /// <param name="filename">The filename to use for the stream.</param> /// <param name="stream">The Stream to extract from</param> /// <param name="opts">The Extractor Options to use.</param> /// <returns></returns> public IEnumerable <FileEntry> Extract(string filename, Stream stream, ExtractorOptions?opts = null) { var options = opts ?? new ExtractorOptions(); var governor = new ResourceGovernor(options); governor.ResetResourceGovernor(stream); FileEntry?fileEntry = null; try { fileEntry = new FileEntry(Path.GetFileName(filename), stream); governor.ResetResourceGovernor(stream); } catch (Exception ex) { Logger.Debug(ex, "Failed to extract file {0}", filename); } if (fileEntry != null) { foreach (var result in Extract(fileEntry, opts, governor)) { governor.GovernorStopwatch.Stop(); yield return(result); governor.GovernorStopwatch.Start(); } } governor.GovernorStopwatch.Stop(); }
/// <summary> /// Extract from a FileEntry. /// </summary> /// <param name="fileEntry">The FileEntry containing the Conteant stream to parse.</param> /// <param name="opts">The ExtractorOptions to use</param> /// <param name="governor">The Resource governor to use (or null to create a new one).</param> /// <returns>The FileEntries found.</returns> public IEnumerable <FileEntry> Extract(FileEntry fileEntry, ExtractorOptions?opts = null, ResourceGovernor?governor = null) { var options = opts ?? new ExtractorOptions(); var Governor = governor; if (Governor == null) { Governor = new ResourceGovernor(options); Governor.ResetResourceGovernor(fileEntry.Content); } Logger.Trace("ExtractFile({0})", fileEntry.FullPath); Governor.CurrentOperationProcessedBytesLeft -= fileEntry.Content.Length; Governor.CheckResourceGovernor(); IEnumerable <FileEntry> result = Array.Empty <FileEntry>(); var useRaw = false; try { var type = MiniMagic.DetectFileType(fileEntry); if (type == ArchiveFileType.UNKNOWN || !Extractors.ContainsKey(type)) { useRaw = true; result = new[] { fileEntry }; } else { result = Extractors[type].Extract(fileEntry, options, Governor); } } catch (Exception ex) { Logger.Debug(ex, "Error extracting {0}: {1}", fileEntry.FullPath, ex.Message); useRaw = true; result = new[] { fileEntry }; } // After we are done with an archive subtract its bytes. Contents have been counted now separately if (!useRaw) { Governor.CurrentOperationProcessedBytesLeft += fileEntry.Content.Length; } return(result); }