diff --git a/SabreTools.DatTools/Rebuilder.cs b/SabreTools.DatTools/Rebuilder.cs index cc61a328..64df84b0 100644 --- a/SabreTools.DatTools/Rebuilder.cs +++ b/SabreTools.DatTools/Rebuilder.cs @@ -470,7 +470,7 @@ namespace SabreTools.DatTools outputFormat = OutputFormat.ParentFolder; // Get the output archive, if possible - Folder? outputArchive = GetPreconfiguredFolder(datFile, date, outputFormat); + IFolder? outputArchive = GetPreconfiguredFolder(datFile, date, outputFormat); // Now rebuild to the output file outputArchive!.Write(fileStream, outDir, (item as Rom)!.ConvertToBaseFile()); @@ -516,7 +516,7 @@ namespace SabreTools.DatTools datItem.SetName($"{datItem.GetName()}_{crc}"); // Get the output archive, if possible - Folder? outputArchive = GetPreconfiguredFolder(datFile, date, outputFormat); + IFolder? outputArchive = GetPreconfiguredFolder(datFile, date, outputFormat); // Now rebuild to the output file bool eitherSuccess = false; @@ -822,9 +822,9 @@ namespace SabreTools.DatTools /// True if the date from the DAT should be used if available, false otherwise /// Output format that files should be written to /// Folder configured with proper flags - private static Folder? GetPreconfiguredFolder(DatFile datFile, bool date, OutputFormat outputFormat) + private static IFolder? GetPreconfiguredFolder(DatFile datFile, bool date, OutputFormat outputFormat) { - Folder? outputArchive = FileTypeTool.CreateFolderType(outputFormat); + IFolder? outputArchive = FileTypeTool.CreateFolderType(outputFormat); if (outputArchive is BaseArchive baseArchive && date) baseArchive.SetRealDates(date); diff --git a/SabreTools.FileTypes/BaseArchive.cs b/SabreTools.FileTypes/BaseArchive.cs index b9460731..9203b3f1 100644 --- a/SabreTools.FileTypes/BaseArchive.cs +++ b/SabreTools.FileTypes/BaseArchive.cs @@ -1,12 +1,24 @@ using System.Collections.Generic; using System.IO; +using SabreTools.Hashing; +using SabreTools.IO.Logging; namespace SabreTools.FileTypes { - public abstract class BaseArchive : Folder + public abstract class BaseArchive : BaseFile, IFolder { #region Protected instance variables + /// + /// Hashes that are available for children + /// + protected HashType[] _hashTypes = [HashType.CRC32, HashType.MD5, HashType.SHA1]; + + /// + /// Set of children file objects + /// + protected List? _children; + /// /// Determines if real dates are written /// @@ -17,6 +29,11 @@ namespace SabreTools.FileTypes /// protected const int _bufferSize = 4096 * 128; + /// + /// Logging object + /// + protected Logger _logger; + #endregion #region Construtors @@ -24,36 +41,54 @@ namespace SabreTools.FileTypes /// /// Create a new Archive with no base file /// - public BaseArchive() : base(writeToParent: false) { } + public BaseArchive() + { + _logger = new Logger(this); + } /// /// Create a new BaseArchive from the given file /// /// Name of the file to use - public BaseArchive(string filename) : base(filename, writeToParent: false) { } + public BaseArchive(string filename) : base(filename) + { + _logger = new Logger(this); + } #endregion #region Extraction /// - public override abstract bool CopyAll(string outDir); + public abstract bool CopyAll(string outDir); /// - public override abstract string? CopyToFile(string entryName, string outDir); + public abstract string? CopyToFile(string entryName, string outDir); /// - public override abstract (Stream?, string?) GetEntryStream(string entryName); + public abstract (Stream?, string?) GetEntryStream(string entryName); #endregion #region Information - /// - public override abstract List? GetChildren(); + /// + /// Set the hash type that can be included in children + /// + public void SetHashType(HashType hashType) + => SetHashTypes([hashType]); + + /// + /// Set the hash types that can be included in children + /// + public void SetHashTypes(HashType[] hashTypes) + => _hashTypes = hashTypes; /// - public override abstract List GetEmptyFolders(); + public abstract List? GetChildren(); + + /// + public abstract List GetEmptyFolders(); /// /// Check whether the input file is a standardized format @@ -73,13 +108,13 @@ namespace SabreTools.FileTypes } /// - public override abstract bool Write(string inputFile, string outDir, BaseFile? baseFile); + public abstract bool Write(string inputFile, string outDir, BaseFile? baseFile); /// - public override abstract bool Write(Stream? inputStream, string outDir, BaseFile? baseFile); + public abstract bool Write(Stream? inputStream, string outDir, BaseFile? baseFile); /// - public override abstract bool Write(List inputFiles, string outDir, List? baseFiles); + public abstract bool Write(List inputFiles, string outDir, List? baseFiles); #endregion } diff --git a/SabreTools.FileTypes/FileTypeTool.cs b/SabreTools.FileTypes/FileTypeTool.cs index d85b7bd4..fc2ce707 100644 --- a/SabreTools.FileTypes/FileTypeTool.cs +++ b/SabreTools.FileTypes/FileTypeTool.cs @@ -173,11 +173,11 @@ namespace SabreTools.FileTypes } /// - /// Create an Folder object of the specified type, if possible + /// Create an IFolder object of the specified type, if possible /// /// OutputFormat representing the archive to create - /// Archive object representing the inputs - public static Folder? CreateFolderType(OutputFormat outputFormat) + /// IFolder object representing the inputs + public static IFolder? CreateFolderType(OutputFormat outputFormat) { return outputFormat switch { diff --git a/SabreTools.FileTypes/Folder.cs b/SabreTools.FileTypes/Folder.cs index 85090fb2..24a60fdf 100644 --- a/SabreTools.FileTypes/Folder.cs +++ b/SabreTools.FileTypes/Folder.cs @@ -12,7 +12,7 @@ namespace SabreTools.FileTypes /// /// Represents a folder for reading and writing /// - public class Folder : BaseFile + public class Folder : BaseFile, IFolder { #region Protected instance variables @@ -31,11 +31,6 @@ namespace SabreTools.FileTypes /// protected Logger _logger; - /// - /// Static logger for static methods - /// - protected static Logger _staticLogger = new(); - /// /// Flag specific to Folder to omit Machine name from output path /// @@ -70,12 +65,8 @@ namespace SabreTools.FileTypes #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 virtual bool CopyAll(string outDir) + /// + public bool CopyAll(string outDir) { // If we have an invalid filename if (Filename == null) @@ -138,13 +129,8 @@ namespace SabreTools.FileTypes } } - /// - /// Attempt to extract a file from an archive - /// - /// Name of the entry to be extracted - /// Output directory for archive extraction - /// Name of the extracted file, null on error - public virtual string? CopyToFile(string entryName, string outDir) + /// + public string? CopyToFile(string entryName, string outDir) { string? realentry = null; @@ -181,12 +167,8 @@ namespace SabreTools.FileTypes return realentry; } - /// - /// Attempt to extract a stream from an archive - /// - /// Name of the entry to be extracted - /// Stream representing the entry, null on error - public virtual (Stream?, string?) GetEntryStream(string entryName) + /// + public (Stream?, string?) GetEntryStream(string entryName) { // If we have an invalid filename if (Filename == null) @@ -236,11 +218,8 @@ namespace SabreTools.FileTypes public void SetHashTypes(HashType[] hashTypes) => _hashTypes = hashTypes; - /// - /// Generate a list of immediate children from the current folder - /// - /// List of BaseFile objects representing the found data - public virtual List? GetChildren() + /// + public List? GetChildren() { // If we have an invalid filename if (Filename == null) @@ -274,12 +253,8 @@ namespace SabreTools.FileTypes return _children; } - /// - /// Generate a list of empty folders in an archive - /// - /// Input file to get data from - /// List of empty folders in the folder - public virtual List? GetEmptyFolders() + /// + public List? GetEmptyFolders() { return Filename.ListEmpty(); } @@ -288,29 +263,15 @@ namespace SabreTools.FileTypes #region Writing - /// - /// Write an input file to an output folder - /// - /// Input filename to be moved - /// Output directory to build to - /// BaseFile representing the new information - /// True if the write was a success, false otherwise - /// This works for now, but it can be sped up by using Ionic.Zip or another zlib wrapper that allows for header values built-in. See edc's code. - public virtual bool Write(string inputFile, string outDir, BaseFile? baseFile) + /// + public bool Write(string inputFile, string outDir, BaseFile? baseFile) { FileStream fs = File.OpenRead(inputFile); return Write(fs, outDir, baseFile); } - /// - /// Write an input stream to an output folder - /// - /// Input stream to be moved - /// Output directory to build to - /// BaseFile representing the new information - /// True if the write was a success, false otherwise - /// This works for now, but it can be sped up by using Ionic.Zip or another zlib wrapper that allows for header values built-in. See edc's code. - public virtual bool Write(Stream? inputStream, string outDir, BaseFile? baseFile) + /// + public bool Write(Stream? inputStream, string outDir, BaseFile? baseFile) { // If either input is null or empty, return if (inputStream == null || baseFile == null || baseFile.Filename == null) @@ -388,14 +349,8 @@ namespace SabreTools.FileTypes } } - /// - /// Write a set of input files to an output folder (assuming the same output archive name) - /// - /// Input files to be moved - /// Output directory to build to - /// BaseFiles representing the new information - /// True if the inputs were written properly, false otherwise - public virtual bool Write(List inputFiles, string outDir, List? baseFiles) + /// + public bool Write(List inputFiles, string outDir, List? baseFiles) { throw new NotImplementedException(); } diff --git a/SabreTools.FileTypes/IFolder.cs b/SabreTools.FileTypes/IFolder.cs new file mode 100644 index 00000000..b3348bc7 --- /dev/null +++ b/SabreTools.FileTypes/IFolder.cs @@ -0,0 +1,85 @@ +using System.Collections.Generic; +using System.IO; + +namespace SabreTools.FileTypes +{ + /// + /// Represents an item that can contain children + /// + public interface IFolder + { + #region Extraction + + /// + /// Attempt to extract a file as an archive + /// + /// Output directory for archive extraction + /// True if the extraction was a success, false otherwise + bool CopyAll(string outDir); + + /// + /// Attempt to extract a file from an archive + /// + /// Name of the entry to be extracted + /// Output directory for archive extraction + /// Name of the extracted file, null on error + string? CopyToFile(string entryName, string outDir); + + /// + /// Attempt to extract a stream from an archive + /// + /// Name of the entry to be extracted + /// Stream representing the entry, null on error + (Stream?, string?) GetEntryStream(string entryName); + + #endregion + + #region Information + + /// + /// Generate a list of immediate children from the current folder + /// + /// List of BaseFile objects representing the found data + List? GetChildren(); + + /// + /// Generate a list of empty folders in an archive + /// + /// Input file to get data from + /// List of empty folders in the folder + List? GetEmptyFolders(); + + #endregion + + #region Writing + + /// + /// Write an input file to an output folder + /// + /// Input filename to be moved + /// Output directory to build to + /// BaseFile representing the new information + /// True if the write was a success, false otherwise + bool Write(string inputFile, string outDir, BaseFile? baseFile); + + /// + /// Write an input stream to an output folder + /// + /// Input stream to be moved + /// Output directory to build to + /// BaseFile representing the new information + /// True if the write was a success, false otherwise + bool Write(Stream? inputStream, string outDir, BaseFile? baseFile); + + /// + /// Write a set of input files to an output folder (assuming the same output archive name) + /// + /// Input files to be moved + /// Output directory to build to + /// BaseFiles representing the new information + /// True if the inputs were written properly, false otherwise + bool Write(List inputFiles, string outDir, List? baseFiles); + + #endregion + } +} \ No newline at end of file