using System.Collections.Generic; using System.IO; using SabreTools.Library.Data; using SabreTools.Library.DatFiles; using SabreTools.Library.DatItems; using SabreTools.Library.Tools; namespace SabreTools.Library.FileTypes { public abstract class BaseArchive : Folder { #region Protected instance variables // Buffer size used by archives protected const int _bufferSize = 4096 * 128; #endregion #region Construtors /// /// Create a new Archive with no base file /// public BaseArchive() { } /// /// Create a new Archive from the given file /// /// Name of the file to use as an archive /// True if hashes for this file should be calculated, false otherwise (default) public BaseArchive(string filename, bool getHashes = false) : base(filename, getHashes) { } /// /// Create an archive object from a filename, if possible /// /// Name of the file to create the archive from /// Archive object representing the inputs public static BaseArchive Create(string input) { BaseArchive archive = null; // First get the archive type FileType? at = input.GetFileType(); // If we got back null, then it's not an archive, so we we return if (at == null) return archive; // Create the archive based on the type Globals.Logger.Verbose($"Found archive of type: {at}"); switch (at) { case FileType.GZipArchive: archive = new GZipArchive(input); break; case FileType.RarArchive: archive = new RarArchive(input); break; case FileType.SevenZipArchive: archive = new SevenZipArchive(input); break; case FileType.TapeArchive: archive = new TapeArchive(input); break; case FileType.ZipArchive: archive = new ZipArchive(input); break; default: // We ignore all other types for now break; } return archive; } /// /// Create an archive object of the specified type, if possible /// /// SharpCompress.Common.ArchiveType representing the archive to create /// Archive object representing the inputs public static BaseArchive Create(FileType archiveType) { switch (archiveType) { case FileType.GZipArchive: return new GZipArchive(); case FileType.RarArchive: return new RarArchive(); case FileType.SevenZipArchive: return new SevenZipArchive(); case FileType.TapeArchive: return new TapeArchive(); case FileType.ZipArchive: return new ZipArchive(); default: return null; } } #endregion #region Extraction /// /// Attempt to extract a file as an archive /// /// Output directory for archive extraction /// True if the extraction was a success, false otherwise public override abstract bool CopyAll(string outDir); /// /// Attempt to extract an entry from an archive /// /// Name of the entry to be extracted /// Output directory for archive extraction /// Name of the extracted file, null on error public override abstract string CopyToFile(string entryName, string outDir); /// /// Attempt to extract a stream from an archive /// /// Name of the entry to be extracted /// Output representing the entry name that was found /// MemoryStream representing the entry, null on error public override abstract (MemoryStream, string) CopyToStream(string entryName); #endregion #region Information /// /// Generate a list of DatItem objects from the header values in an archive /// /// Hash representing the hashes that should be skipped /// True if entry dates should be included, false otherwise (default) /// List of DatItem objects representing the found data /// TODO: All instances of Hash.DeepHashes should be made into 0x0 eventually public override abstract List GetChildren(Hash omitFromScan = Hash.DeepHashes, bool date = false); /// /// Generate a list of empty folders in an archive /// /// Input file to get data from /// List of empty folders in the archive public override abstract List GetEmptyFolders(); /// /// Check whether the input file is a standardized format /// public abstract bool IsTorrent(); #endregion #region Writing /// /// Write an input file to an archive /// /// Input filename to be moved /// Output directory to build to /// DatItem representing the new information /// True if the date from the DAT should be used if available, false otherwise (default) /// True if files should be output in Romba depot folders, false otherwise /// True if the archive was written properly, false otherwise public override abstract bool Write(string inputFile, string outDir, Rom rom, bool date = false, bool romba = false); /// /// Write an input stream to an archive /// /// Input stream to be moved /// Output directory to build to /// DatItem representing the new information /// True if the date from the DAT should be used if available, false otherwise (default) /// True if files should be output in Romba depot folders, false otherwise /// True if the archive was written properly, false otherwise public override abstract bool Write(Stream inputStream, string outDir, Rom rom, bool date = false, bool romba = false); /// /// Write a set of input files to an archive (assuming the same output archive name) /// /// Input files to be moved /// Output directory to build to /// DatItem representing the new information /// True if the date from the DAT should be used if available, false otherwise (default) /// True if files should be output in Romba depot folders, false otherwise /// True if the archive was written properly, false otherwise public override abstract bool Write(List inputFiles, string outDir, List roms, bool date = false, bool romba = false); #endregion } }