diff --git a/RombaSharp/RombaSharp.Helpers.cs b/RombaSharp/RombaSharp.Helpers.cs index 3735ed2b..ca0269af 100644 --- a/RombaSharp/RombaSharp.Helpers.cs +++ b/RombaSharp/RombaSharp.Helpers.cs @@ -41,7 +41,7 @@ namespace RombaSharp if (lowerCaseDats.Contains(input.ToLowerInvariant())) { string fullpath = Path.GetFullPath(datRootDats[lowerCaseDats.IndexOf(input.ToLowerInvariant())]); - string sha1 = ((Rom)Utilities.GetFileInfo(fullpath)).SHA1; + string sha1 = Utilities.ByteArrayToString(Utilities.GetFileInfo(fullpath).SHA1); foundDats.Add(sha1, fullpath); } else diff --git a/SabreTools.Library/DatFiles/DatFile.cs b/SabreTools.Library/DatFiles/DatFile.cs index b5ab1e7e..1ebc9521 100644 --- a/SabreTools.Library/DatFiles/DatFile.cs +++ b/SabreTools.Library/DatFiles/DatFile.cs @@ -3625,13 +3625,13 @@ namespace SabreTools.Library.DatFiles if (Romba) { GZipArchive archive = new GZipArchive(item); - Rom rom = archive.GetTorrentGZFileInfo(); + BaseFile rom = archive.GetTorrentGZFileInfo(); // If the rom is valid, write it out - if (rom != null && rom.Name != null) + if (rom != null && rom.Filename != null) { // Add the list if it doesn't exist already - Add(rom.Size + "-" + rom.CRC, rom); + Add(rom.Size + "-" + rom.CRC, new Rom(rom)); Globals.Logger.User("File added: {0}", Path.GetFileNameWithoutExtension(item) + Environment.NewLine); } else @@ -3655,18 +3655,18 @@ namespace SabreTools.Library.DatFiles } // Create a list for all found items - List extracted = null; + List extracted = null; // If we don't have archives as files, try to scan the file as an archive if (!archivesAsFiles) { // Get the base archive first - BaseArchive archive = Utilities.GetArchive(newItem); + Folder archive = Utilities.GetArchive(newItem); // Now get all extracted items from the archive if (archive != null) { - extracted = archive.GetArchiveFileInfo(omitFromScan: omitFromScan, date: addDate); + extracted = archive.GetChildren(omitFromScan: omitFromScan, date: addDate); } } @@ -3688,8 +3688,9 @@ namespace SabreTools.Library.DatFiles // First take care of the found items Parallel.ForEach(extracted, Globals.ParallelOptions, rom => { + DatItem datItem = (rom.Type == FileType.CHD ? (DatItem)(new Disk(rom)) : (DatItem)(new Rom(rom))); ProcessFileHelper(newItem, - rom, + datItem, basePath, (Path.GetDirectoryName(Path.GetFullPath(item)) + Path.DirectorySeparatorChar).Remove(0, basePath.Length) + Path.GetFileNameWithoutExtension(item)); }); @@ -3700,7 +3701,7 @@ namespace SabreTools.Library.DatFiles List empties = new List(); // Get the base archive first - BaseArchive archive = Utilities.GetArchive(newItem); + Folder archive = Utilities.GetArchive(newItem); // Now get all blank folders from the archive if (archive != null) @@ -3741,7 +3742,16 @@ namespace SabreTools.Library.DatFiles bool addDate, string headerToCheckAgainst, bool chdsAsFiles) { Globals.Logger.Verbose("'{0}' treated like a file", Path.GetFileName(item)); - DatItem datItem = Utilities.GetFileInfo(item, omitFromScan: omitFromScan, date: addDate, header: headerToCheckAgainst, chdsAsFiles: chdsAsFiles); + BaseFile baseFile = Utilities.GetFileInfo(item, omitFromScan: omitFromScan, date: addDate, header: headerToCheckAgainst, chdsAsFiles: chdsAsFiles); + DatItem datItem = null; + if (baseFile.Type == FileType.CHD) + { + datItem = new Disk(baseFile); + } + else if (baseFile.Type == FileType.None) + { + datItem = new Rom(baseFile); + } ProcessFileHelper(item, datItem, basePath, parent); } @@ -4023,7 +4033,7 @@ namespace SabreTools.Library.DatFiles // If we have a path, we want to try to get the rom information GZipArchive archive = new GZipArchive(foundpath); - Rom fileinfo = archive.GetTorrentGZFileInfo(); + BaseFile fileinfo = archive.GetTorrentGZFileInfo(); // If the file information is null, then we continue if (fileinfo == null) @@ -4032,7 +4042,7 @@ namespace SabreTools.Library.DatFiles } // Otherwise, we rebuild that file to all locations that we need to - RebuildIndividualFile(fileinfo, foundpath, outDir, date, inverse, outputFormat, romba, + RebuildIndividualFile(new Rom(fileinfo), foundpath, outDir, date, inverse, outputFormat, romba, updateDat, false /* isZip */, headerToCheckAgainst); } @@ -4220,17 +4230,27 @@ namespace SabreTools.Library.DatFiles if (shouldExternalProcess) { // TODO: All instances of Hash.DeepHashes should be made into 0x0 eventually - DatItem fileinfo = Utilities.GetFileInfo(file, omitFromScan: (quickScan ? Hash.SecureHashes : Hash.DeepHashes), + BaseFile fileinfo = Utilities.GetFileInfo(file, omitFromScan: (quickScan ? Hash.SecureHashes : Hash.DeepHashes), header: headerToCheckAgainst, chdsAsFiles: chdsAsFiles); - usedExternally = RebuildIndividualFile(fileinfo, file, outDir, date, inverse, outputFormat, + DatItem datItem = null; + if (fileinfo.Type == FileType.CHD) + { + datItem = new Disk(fileinfo); + } + else if (fileinfo.Type == FileType.None) + { + datItem = new Rom(fileinfo); + } + + usedExternally = RebuildIndividualFile(datItem, file, outDir, date, inverse, outputFormat, romba, updateDat, null /* isZip */, headerToCheckAgainst); } // If we're supposed to scan the file internally if (shouldInternalProcess) { - // Create an empty list of Roms for archive entries - List entries = null; + // Create an empty list of BaseFile for archive entries + List entries = null; usedInternally = true; // Get the TGZ status for later @@ -4238,29 +4258,40 @@ namespace SabreTools.Library.DatFiles bool isTorrentGzip = tgz.IsTorrent(); // Get the base archive first - BaseArchive archive = Utilities.GetArchive(file); + Folder archive = Utilities.GetArchive(file); // Now get all extracted items from the archive if (archive != null) { // TODO: All instances of Hash.DeepHashes should be made into 0x0 eventually - entries = archive.GetArchiveFileInfo(omitFromScan: (quickScan ? Hash.SecureHashes : Hash.DeepHashes), date: date); + entries = archive.GetChildren(omitFromScan: (quickScan ? Hash.SecureHashes : Hash.DeepHashes), date: date); } // If the entries list is null, we encountered an error and should scan exteranlly if (entries == null && File.Exists(file)) { // TODO: All instances of Hash.DeepHashes should be made into 0x0 eventually - DatItem fileinfo = Utilities.GetFileInfo(file, omitFromScan: (quickScan ? Hash.SecureHashes : Hash.DeepHashes), chdsAsFiles: chdsAsFiles); - usedExternally = RebuildIndividualFile(fileinfo, file, outDir, date, inverse, outputFormat, + BaseFile fileinfo = Utilities.GetFileInfo(file, omitFromScan: (quickScan ? Hash.SecureHashes : Hash.DeepHashes), chdsAsFiles: chdsAsFiles); + DatItem datItem = null; + if (fileinfo.Type == FileType.CHD) + { + datItem = new Disk(fileinfo); + } + else if (fileinfo.Type == FileType.None) + { + datItem = new Rom(fileinfo); + } + + usedExternally = RebuildIndividualFile(datItem, file, outDir, date, inverse, outputFormat, romba, updateDat, null /* isZip */, headerToCheckAgainst); } // Otherwise, loop through the entries and try to match else { - foreach (Rom entry in entries) + foreach (BaseFile entry in entries) { - usedInternally &= RebuildIndividualFile(entry, file, outDir, date, inverse, outputFormat, + DatItem datItem = (entry.Type == FileType.CHD ? (DatItem)(new Disk(entry)) : (DatItem)(new Rom(entry))); + usedInternally &= RebuildIndividualFile(datItem, file, outDir, date, inverse, outputFormat, romba, updateDat, !isTorrentGzip /* isZip */, headerToCheckAgainst); } } @@ -4330,7 +4361,7 @@ namespace SabreTools.Library.DatFiles // If we have a very specifc TGZ->TGZ case, just copy it accordingly GZipArchive tgz = new GZipArchive(file); - Rom rom = tgz.GetTorrentGZFileInfo(); + BaseFile rom = tgz.GetTorrentGZFileInfo(); if (isZip == false && rom != null && outputFormat == OutputFormat.TorrentGzip) { Globals.Logger.User("Matches found for '{0}', rebuilding accordingly...", Path.GetFileName(datItem.Name)); @@ -4369,7 +4400,7 @@ namespace SabreTools.Library.DatFiles if (isZip != null) { string realName = null; - BaseArchive archive = Utilities.GetArchive(file); + Folder archive = Utilities.GetArchive(file); if (archive != null) { (fileStream, realName) = archive.ExtractEntryStream(datItem.Name); @@ -4397,7 +4428,7 @@ namespace SabreTools.Library.DatFiles foreach (DatItem item in dupes) { // Get the output archive, if possible - BaseArchive outputArchive = Utilities.GetArchive(outputFormat); + Folder outputArchive = Utilities.GetArchive(outputFormat); // Now rebuild to the output file outputArchive.Write(fileStream, outDir, (Rom)item, date: date, romba: romba); @@ -4414,7 +4445,7 @@ namespace SabreTools.Library.DatFiles // If we have a very specifc TGZ->TGZ case, just copy it accordingly GZipArchive tgz = new GZipArchive(file); - Rom rom = tgz.GetTorrentGZFileInfo(); + BaseFile rom = tgz.GetTorrentGZFileInfo(); if (isZip == false && rom != null && outputFormat == OutputFormat.TorrentGzip) { Globals.Logger.User("Matches found for '{0}', rebuilding accordingly...", Path.GetFileName(datItem.Name)); @@ -4453,7 +4484,7 @@ namespace SabreTools.Library.DatFiles if (isZip != null) { string realName = null; - BaseArchive archive = Utilities.GetArchive(file); + Folder archive = Utilities.GetArchive(file); if (archive != null) { (fileStream, realName) = archive.ExtractEntryStream(datItem.Name); @@ -4472,7 +4503,7 @@ namespace SabreTools.Library.DatFiles } // Get the item from the current file - Rom item = (Rom)Utilities.GetStreamInfo(fileStream, fileStream.Length, keepReadOpen: true); + Rom item = new Rom(Utilities.GetStreamInfo(fileStream, fileStream.Length, keepReadOpen: true)); item.MachineName = Path.GetFileNameWithoutExtension(item.Name); item.MachineDescription = Path.GetFileNameWithoutExtension(item.Name); @@ -4486,7 +4517,7 @@ namespace SabreTools.Library.DatFiles Globals.Logger.User("No matches found for '{0}', rebuilding accordingly from inverse flag...", Path.GetFileName(datItem.Name)); // Get the output archive, if possible - BaseArchive outputArchive = Utilities.GetArchive(outputFormat); + Folder outputArchive = Utilities.GetArchive(outputFormat); // Now rebuild to the output file if (outputArchive == null) @@ -4543,7 +4574,7 @@ namespace SabreTools.Library.DatFiles if (isZip != null) { string realName = null; - BaseArchive archive = Utilities.GetArchive(file); + Folder archive = Utilities.GetArchive(file); if (archive != null) { (fileStream, realName) = archive.ExtractEntryStream(datItem.Name); @@ -4572,7 +4603,7 @@ namespace SabreTools.Library.DatFiles if (rule.TransformStream(fileStream, transformStream, keepReadOpen: true, keepWriteOpen: true)) { // Get the file informations that we will be using - Rom headerless = (Rom)Utilities.GetStreamInfo(transformStream, transformStream.Length, keepReadOpen: true); + Rom headerless = new Rom(Utilities.GetStreamInfo(transformStream, transformStream.Length, keepReadOpen: true)); // Find if the file has duplicates in the DAT hasDuplicates = headerless.HasDuplicates(this); @@ -4603,7 +4634,7 @@ namespace SabreTools.Library.DatFiles bool eitherSuccess = false; // Get the output archive, if possible - BaseArchive outputArchive = Utilities.GetArchive(outputFormat); + Folder outputArchive = Utilities.GetArchive(outputFormat); // Now rebuild to the output file eitherSuccess |= outputArchive.Write(transformStream, outDir, (Rom)item, date: date, romba: romba); @@ -4693,7 +4724,7 @@ namespace SabreTools.Library.DatFiles // If we have a path, we want to try to get the rom information GZipArchive tgz = new GZipArchive(foundpath); - Rom fileinfo = tgz.GetTorrentGZFileInfo(); + BaseFile fileinfo = tgz.GetTorrentGZFileInfo(); // If the file information is null, then we continue if (fileinfo == null) @@ -4702,7 +4733,7 @@ namespace SabreTools.Library.DatFiles } // Now we want to remove all duplicates from the DAT - fileinfo.GetDuplicates(this, remove: true); + new Rom(fileinfo).GetDuplicates(this, remove: true); } watch.Stop(); diff --git a/SabreTools.Library/DatItems/Disk.cs b/SabreTools.Library/DatItems/Disk.cs index 2ac4301c..b1bc1c2c 100644 --- a/SabreTools.Library/DatItems/Disk.cs +++ b/SabreTools.Library/DatItems/Disk.cs @@ -1,6 +1,7 @@ using System.Linq; using SabreTools.Library.Data; +using SabreTools.Library.FileTypes; using SabreTools.Library.Tools; namespace SabreTools.Library.DatItems @@ -101,6 +102,20 @@ namespace SabreTools.Library.DatItems _itemStatus = ItemStatus.None; } + /// + /// Create a Rom object from a BaseFile + /// + /// + public Disk(BaseFile baseFile) + { + _name = baseFile.Filename; + _md5 = baseFile.MD5; + _sha1 = baseFile.SHA1; + _sha256 = baseFile.SHA256; + _sha384 = baseFile.SHA384; + _sha512 = baseFile.SHA512; + } + #endregion #region Cloning Methods diff --git a/SabreTools.Library/DatItems/Rom.cs b/SabreTools.Library/DatItems/Rom.cs index a6ddd4c5..aa0aec11 100644 --- a/SabreTools.Library/DatItems/Rom.cs +++ b/SabreTools.Library/DatItems/Rom.cs @@ -1,6 +1,7 @@ using System.Linq; using SabreTools.Library.Data; +using SabreTools.Library.FileTypes; using SabreTools.Library.Tools; namespace SabreTools.Library.DatItems @@ -165,6 +166,21 @@ namespace SabreTools.Library.DatItems }; } + /// + /// Create a Rom object from a BaseFile + /// + /// + public Rom(BaseFile baseFile) + { + _name = baseFile.Filename; + _crc = baseFile.CRC; + _md5 = baseFile.MD5; + _sha1 = baseFile.SHA1; + _sha256 = baseFile.SHA256; + _sha384 = baseFile.SHA384; + _sha512 = baseFile.SHA512; + } + #endregion #region Cloning Methods diff --git a/SabreTools.Library/FileTypes/BaseArchive.cs b/SabreTools.Library/FileTypes/BaseArchive.cs index e852bbf9..99043f95 100644 --- a/SabreTools.Library/FileTypes/BaseArchive.cs +++ b/SabreTools.Library/FileTypes/BaseArchive.cs @@ -12,7 +12,7 @@ using Stream = System.IO.Stream; namespace SabreTools.Library.FileTypes { - public abstract class BaseArchive : BaseFile + public abstract class BaseArchive : Folder { #region Protected instance variables @@ -48,7 +48,7 @@ namespace SabreTools.Library.FileTypes /// /// Output directory for archive extraction /// True if the extraction was a success, false otherwise - public abstract bool ExtractAll(string outDir); + public new abstract bool ExtractAll(string outDir); /// /// Attempt to extract an entry from an archive @@ -56,7 +56,7 @@ namespace SabreTools.Library.FileTypes /// Name of the entry to be extracted /// Output directory for archive extraction /// Name of the extracted file, null on error - public abstract string ExtractEntry(string entryName, string outDir); + public new abstract string ExtractEntry(string entryName, string outDir); /// /// Attempt to extract a stream from an archive @@ -64,7 +64,7 @@ namespace SabreTools.Library.FileTypes /// Name of the entry to be extracted /// Output representing the entry name that was found /// MemoryStream representing the entry, null on error - public abstract (MemoryStream, string) ExtractEntryStream(string entryName); + public new abstract (MemoryStream, string) ExtractEntryStream(string entryName); #endregion @@ -77,14 +77,14 @@ namespace SabreTools.Library.FileTypes /// 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 abstract List GetArchiveFileInfo(Hash omitFromScan = Hash.DeepHashes, bool date = false); + public new 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 abstract List GetEmptyFolders(); + public new abstract List GetEmptyFolders(); /// /// Check whether the input file is a standardized format diff --git a/SabreTools.Library/FileTypes/BaseFile.cs b/SabreTools.Library/FileTypes/BaseFile.cs index 072609ab..f0b8e676 100644 --- a/SabreTools.Library/FileTypes/BaseFile.cs +++ b/SabreTools.Library/FileTypes/BaseFile.cs @@ -4,13 +4,14 @@ using SabreTools.Library.Data; namespace SabreTools.Library.FileTypes { - public abstract class BaseFile + public class BaseFile { #region Protected instance variables protected FileType _fileType; protected string _filename; - protected List _children; + protected string _parent; + protected string _date; // External hash values for the file protected long? _size; @@ -26,11 +27,25 @@ namespace SabreTools.Library.FileTypes #region Publicly facing variables // TODO: Get all of these values automatically so there is no public "set" + public FileType Type + { + get { return _fileType; } + } public string Filename { get { return _filename; } set { _filename = value; } } + public string Parent + { + get { return _parent; } + set { _parent = value; } + } + public string Date + { + get { return _date; } + set { _date = value; } + } public long? Size { get { return _size; } diff --git a/SabreTools.Library/FileTypes/CoreRarArchive.cs b/SabreTools.Library/FileTypes/CoreRarArchive.cs index d81d4931..bf20813b 100644 --- a/SabreTools.Library/FileTypes/CoreRarArchive.cs +++ b/SabreTools.Library/FileTypes/CoreRarArchive.cs @@ -167,7 +167,7 @@ namespace SabreTools.Library.FileTypes throw new NotImplementedException(); } - public override List GetArchiveFileInfo(Hash omitFromScan = Hash.DeepHashes, bool date = false) + public override List GetChildren(Hash omitFromScan = Hash.DeepHashes, bool date = false) { throw new NotImplementedException(); } diff --git a/SabreTools.Library/FileTypes/Folder.cs b/SabreTools.Library/FileTypes/Folder.cs index 69cde234..0b7d2a95 100644 --- a/SabreTools.Library/FileTypes/Folder.cs +++ b/SabreTools.Library/FileTypes/Folder.cs @@ -27,8 +27,14 @@ namespace SabreTools.Library.FileTypes /// /// Represents a folder for reading and writing /// - public class Folder : BaseArchive + public class Folder : BaseFile { + #region Protected instance variables + + protected List _children; + + #endregion + #region Constructors /// @@ -60,7 +66,7 @@ namespace SabreTools.Library.FileTypes /// /// Output directory for archive extraction /// True if the extraction was a success, false otherwise - public override bool ExtractAll(string outDir) + public bool ExtractAll(string outDir) { // Copy all files from the current folder to the output directory recursively try @@ -86,7 +92,7 @@ namespace SabreTools.Library.FileTypes /// Name of the entry to be extracted /// Output directory for archive extraction /// Name of the extracted file, null on error - public override string ExtractEntry(string entryName, string outDir) + public string ExtractEntry(string entryName, string outDir) { string realentry = null; @@ -125,7 +131,7 @@ namespace SabreTools.Library.FileTypes /// Name of the entry to be extracted /// Output representing the entry name that was found /// MemoryStream representing the entry, null on error - public override (MemoryStream, string) ExtractEntryStream(string entryName) + public (MemoryStream, string) ExtractEntryStream(string entryName) { MemoryStream ms = new MemoryStream(); string realentry = null; @@ -163,33 +169,40 @@ namespace SabreTools.Library.FileTypes #region Information /// - /// Generate a list of DatItem objects from the header values in an archive + /// Generate a list of immediate children from the current folder /// /// 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 + /// List of BaseFile objects representing the found data /// TODO: All instances of Hash.DeepHashes should be made into 0x0 eventually - public override List GetArchiveFileInfo(Hash omitFromScan = Hash.DeepHashes, bool date = false) + public List GetChildren(Hash omitFromScan = Hash.DeepHashes, bool date = false) { - throw new NotImplementedException(); + if (_children == null || _children.Count == 0) + { + _children = new List(); + foreach (string file in Directory.EnumerateFiles(_filename, "*", SearchOption.TopDirectoryOnly)) + { + BaseFile nf = Utilities.GetFileInfo(file, omitFromScan: omitFromScan, date: date); + _children.Add(nf); + } + foreach (string dir in Directory.EnumerateDirectories(_filename, "*", SearchOption.TopDirectoryOnly)) + { + Folder fl = new Folder(dir); + _children.Add(fl); + } + } + + return _children; } /// /// Generate a list of empty folders in an archive /// /// Input file to get data from - /// List of empty folders in the archive - public override List GetEmptyFolders() + /// List of empty folders in the folder + public List GetEmptyFolders() { - throw new NotImplementedException(); - } - - /// - /// Check whether the input file is a standardized format - /// - public override bool IsTorrent() - { - throw new NotImplementedException(); + return Utilities.GetEmptyDirectories(_filename).ToList(); } #endregion @@ -206,7 +219,7 @@ namespace SabreTools.Library.FileTypes /// True if files should be output in Romba depot folders, false otherwise /// 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 override bool Write(string inputFile, string outDir, Rom rom, bool date = false, bool romba = false) + public bool Write(string inputFile, string outDir, Rom rom, bool date = false, bool romba = false) { throw new NotImplementedException(); } @@ -221,7 +234,7 @@ namespace SabreTools.Library.FileTypes /// True if files should be output in Romba depot folders, false otherwise /// 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 override bool Write(Stream inputStream, string outDir, Rom rom, bool date = false, bool romba = false) + public bool Write(Stream inputStream, string outDir, Rom rom, bool date = false, bool romba = false) { bool success = false; @@ -303,7 +316,7 @@ namespace SabreTools.Library.FileTypes /// 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 bool Write(List inputFiles, string outDir, List roms, bool date = false, bool romba = false) + public bool Write(List inputFiles, string outDir, List roms, bool date = false, bool romba = false) { throw new NotImplementedException(); } diff --git a/SabreTools.Library/FileTypes/GZipArchive.cs b/SabreTools.Library/FileTypes/GZipArchive.cs index 98ef07fa..f1a98333 100644 --- a/SabreTools.Library/FileTypes/GZipArchive.cs +++ b/SabreTools.Library/FileTypes/GZipArchive.cs @@ -194,54 +194,59 @@ namespace SabreTools.Library.FileTypes /// 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 List GetArchiveFileInfo(Hash omitFromScan = Hash.DeepHashes, bool date = false) + public override List GetChildren(Hash omitFromScan = Hash.DeepHashes, bool date = false) { - List found = new List(); - string gamename = Path.GetFileNameWithoutExtension(_filename); - - Rom possibleTgz = GetTorrentGZFileInfo(); - - // If it was, then add it to the outputs and continue - if (possibleTgz != null && possibleTgz.Name != null) + if (_children == null || _children.Count == 0) { - found.Add(possibleTgz); - return found; - } + _children = new List(); - try - { - // If secure hashes are disabled, do a quickscan - if (omitFromScan == Hash.SecureHashes) + string gamename = Path.GetFileNameWithoutExtension(_filename); + + BaseFile possibleTgz = GetTorrentGZFileInfo(); + + // If it was, then add it to the outputs and continue + if (possibleTgz != null && possibleTgz.Filename != null) { - Rom tempRom = new Rom(gamename, gamename, omitFromScan); - BinaryReader br = new BinaryReader(Utilities.TryOpenRead(_filename)); - br.BaseStream.Seek(-8, SeekOrigin.End); - byte[] headercrc = br.ReadBytesReverse(4); - tempRom.CRC = Utilities.ByteArrayToString(headercrc); - tempRom.Size = br.ReadInt32Reverse(); - br.Dispose(); - - found.Add(tempRom); + _children.Add(possibleTgz); } - // Otherwise, use the stream directly else { - GZipStream gzstream = new GZipStream(Utilities.TryOpenRead(_filename), Ionic.Zlib.CompressionMode.Decompress); - Rom gzipEntryRom = (Rom)Utilities.GetStreamInfo(gzstream, gzstream.Length, omitFromScan: omitFromScan); - gzipEntryRom.Name = gzstream.FileName; - gzipEntryRom.MachineName = gamename; - gzipEntryRom.Date = (date && gzstream.LastModified != null ? gzstream.LastModified?.ToString("yyyy/MM/dd hh:mm:ss") : null); - found.Add(gzipEntryRom); - gzstream.Dispose(); + try + { + // If secure hashes are disabled, do a quickscan + if (omitFromScan == Hash.SecureHashes) + { + BaseFile tempRom = new BaseFile(gamename); + BinaryReader br = new BinaryReader(Utilities.TryOpenRead(_filename)); + br.BaseStream.Seek(-8, SeekOrigin.End); + byte[] headercrc = br.ReadBytesReverse(4); + tempRom.CRC = headercrc; + tempRom.Size = br.ReadInt32Reverse(); + br.Dispose(); + + _children.Add(tempRom); + } + // Otherwise, use the stream directly + else + { + GZipStream gzstream = new GZipStream(Utilities.TryOpenRead(_filename), Ionic.Zlib.CompressionMode.Decompress); + BaseFile gzipEntryRom = Utilities.GetStreamInfo(gzstream, gzstream.Length, omitFromScan: omitFromScan); + gzipEntryRom.Filename = gzstream.FileName; + gzipEntryRom.Parent = gamename; + gzipEntryRom.Date = (date && gzstream.LastModified != null ? gzstream.LastModified?.ToString("yyyy/MM/dd hh:mm:ss") : null); + _children.Add(gzipEntryRom); + gzstream.Dispose(); + } + } + catch (Exception) + { + // Don't log file open errors + return null; + } } } - catch (Exception) - { - // Don't log file open errors - return null; - } - return found; + return _children; } /// @@ -325,7 +330,7 @@ namespace SabreTools.Library.FileTypes /// Retrieve file information for a single torrent GZ file /// /// Populated DatItem object if success, empty one on error - public Rom GetTorrentGZFileInfo() + public BaseFile GetTorrentGZFileInfo() { // Check for the file existing first if (!File.Exists(_filename)) @@ -386,23 +391,20 @@ namespace SabreTools.Library.FileTypes } // Now convert the data and get the right position - string gzmd5 = Utilities.ByteArrayToString(headermd5); - string gzcrc = Utilities.ByteArrayToString(headercrc); long extractedsize = (long)headersz; - Rom rom = new Rom + BaseFile baseFile = new BaseFile { - Type = ItemType.Rom, - Name = Path.GetFileNameWithoutExtension(_filename).ToLowerInvariant(), + Filename = Path.GetFileNameWithoutExtension(_filename).ToLowerInvariant(), Size = extractedsize, - CRC = gzcrc.ToLowerInvariant(), - MD5 = gzmd5.ToLowerInvariant(), - SHA1 = Path.GetFileNameWithoutExtension(_filename).ToLowerInvariant(), // TODO: When updating to SHA-256, this needs to update to SHA256 + CRC = headercrc, + MD5 = headermd5, + SHA1 = Utilities.StringToByteArray(Path.GetFileNameWithoutExtension(_filename)), // TODO: When updating to SHA-256, this needs to update to SHA256 - MachineName = Path.GetFileNameWithoutExtension(_filename).ToLowerInvariant(), + Parent = Path.GetFileNameWithoutExtension(_filename).ToLowerInvariant(), }; - return rom; + return baseFile; } #endregion @@ -461,7 +463,7 @@ namespace SabreTools.Library.FileTypes outDir = Path.GetFullPath(outDir); // Now get the Rom info for the file so we have hashes and size - rom = (Rom)Utilities.GetStreamInfo(inputStream, inputStream.Length, keepReadOpen: true); + rom = new Rom(Utilities.GetStreamInfo(inputStream, inputStream.Length, keepReadOpen: true)); // Get the output file name string outfile = null; diff --git a/SabreTools.Library/FileTypes/LRZipArchive.cs b/SabreTools.Library/FileTypes/LRZipArchive.cs index 212f6c1b..03515601 100644 --- a/SabreTools.Library/FileTypes/LRZipArchive.cs +++ b/SabreTools.Library/FileTypes/LRZipArchive.cs @@ -87,7 +87,7 @@ namespace SabreTools.Library.FileTypes /// 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 List GetArchiveFileInfo(Hash omitFromScan = Hash.DeepHashes, bool date = false) + public override List GetChildren(Hash omitFromScan = Hash.DeepHashes, bool date = false) { throw new NotImplementedException(); } diff --git a/SabreTools.Library/FileTypes/LZ4Archive.cs b/SabreTools.Library/FileTypes/LZ4Archive.cs index bd20b142..474b2add 100644 --- a/SabreTools.Library/FileTypes/LZ4Archive.cs +++ b/SabreTools.Library/FileTypes/LZ4Archive.cs @@ -87,7 +87,7 @@ namespace SabreTools.Library.FileTypes /// 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 List GetArchiveFileInfo(Hash omitFromScan = Hash.DeepHashes, bool date = false) + public override List GetChildren(Hash omitFromScan = Hash.DeepHashes, bool date = false) { throw new NotImplementedException(); } diff --git a/SabreTools.Library/FileTypes/RarArchive.cs b/SabreTools.Library/FileTypes/RarArchive.cs index e543f1f7..fca749b0 100644 --- a/SabreTools.Library/FileTypes/RarArchive.cs +++ b/SabreTools.Library/FileTypes/RarArchive.cs @@ -187,9 +187,9 @@ namespace SabreTools.Library.FileTypes /// 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 List GetArchiveFileInfo(Hash omitFromScan = Hash.DeepHashes, bool date = false) + public override List GetChildren(Hash omitFromScan = Hash.DeepHashes, bool date = false) { - List found = new List(); + List found = new List(); string gamename = Path.GetFileNameWithoutExtension(_filename); try @@ -200,24 +200,23 @@ namespace SabreTools.Library.FileTypes // If secure hashes are disabled, do a quickscan if (omitFromScan == Hash.SecureHashes) { - found.Add(new Rom + found.Add(new BaseFile { - Type = ItemType.Rom, - Name = entry.Key, + Filename = entry.Key, Size = entry.Size, - CRC = entry.Crc.ToString("X").ToLowerInvariant(), + CRC = BitConverter.GetBytes(entry.Crc), Date = (date && entry.LastModifiedTime != null ? entry.LastModifiedTime?.ToString("yyyy/MM/dd hh:mm:ss") : null), - MachineName = gamename, + Parent = gamename, }); } // Otherwise, use the stream directly else { Stream entryStream = entry.OpenEntryStream(); - Rom rarEntryRom = (Rom)Utilities.GetStreamInfo(entryStream, entry.Size, omitFromScan: omitFromScan); - rarEntryRom.Name = entry.Key; - rarEntryRom.MachineName = gamename; + BaseFile rarEntryRom = Utilities.GetStreamInfo(entryStream, entry.Size, omitFromScan: omitFromScan); + rarEntryRom.Filename = entry.Key; + rarEntryRom.Parent = gamename; rarEntryRom.Date = entry.LastModifiedTime?.ToString("yyyy/MM/dd hh:mm:ss"); found.Add(rarEntryRom); entryStream.Dispose(); diff --git a/SabreTools.Library/FileTypes/SevenZipArchive.cs b/SabreTools.Library/FileTypes/SevenZipArchive.cs index 9f577eac..b80cf491 100644 --- a/SabreTools.Library/FileTypes/SevenZipArchive.cs +++ b/SabreTools.Library/FileTypes/SevenZipArchive.cs @@ -191,9 +191,9 @@ namespace SabreTools.Library.FileTypes /// 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 List GetArchiveFileInfo(Hash omitFromScan = Hash.DeepHashes, bool date = false) + public override List GetChildren(Hash omitFromScan = Hash.DeepHashes, bool date = false) { - List found = new List(); + List found = new List(); string gamename = Path.GetFileNameWithoutExtension(_filename); try @@ -204,24 +204,23 @@ namespace SabreTools.Library.FileTypes // If secure hashes are disabled, do a quickscan if (omitFromScan == Hash.SecureHashes) { - found.Add(new Rom + found.Add(new BaseFile { - Type = ItemType.Rom, - Name = entry.Key, + Filename = entry.Key, Size = entry.Size, - CRC = entry.Crc.ToString("X").ToLowerInvariant(), + CRC = BitConverter.GetBytes(entry.Crc), Date = (date && entry.LastModifiedTime != null ? entry.LastModifiedTime?.ToString("yyyy/MM/dd hh:mm:ss") : null), - MachineName = gamename, + Parent = gamename, }); } // Otherwise, use the stream directly else { Stream entryStream = entry.OpenEntryStream(); - Rom sevenZipEntryRom = (Rom)Utilities.GetStreamInfo(entryStream, entry.Size, omitFromScan: omitFromScan); - sevenZipEntryRom.Name = entry.Key; - sevenZipEntryRom.MachineName = gamename; + BaseFile sevenZipEntryRom = Utilities.GetStreamInfo(entryStream, entry.Size, omitFromScan: omitFromScan); + sevenZipEntryRom.Filename = entry.Key; + sevenZipEntryRom.Parent = gamename; sevenZipEntryRom.Date = (date && entry.LastModifiedTime != null ? entry.LastModifiedTime?.ToString("yyyy/MM/dd hh:mm:ss") : null); found.Add(sevenZipEntryRom); entryStream.Dispose(); diff --git a/SabreTools.Library/FileTypes/TapeArchive.cs b/SabreTools.Library/FileTypes/TapeArchive.cs index b2d90863..c68addad 100644 --- a/SabreTools.Library/FileTypes/TapeArchive.cs +++ b/SabreTools.Library/FileTypes/TapeArchive.cs @@ -190,9 +190,9 @@ namespace SabreTools.Library.FileTypes /// 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 List GetArchiveFileInfo(Hash omitFromScan = Hash.DeepHashes, bool date = false) + public override List GetChildren(Hash omitFromScan = Hash.DeepHashes, bool date = false) { - List found = new List(); + List found = new List(); string gamename = Path.GetFileNameWithoutExtension(_filename); try @@ -203,24 +203,23 @@ namespace SabreTools.Library.FileTypes // If secure hashes are disabled, do a quickscan if (omitFromScan == Hash.SecureHashes) { - found.Add(new Rom + found.Add(new BaseFile { - Type = ItemType.Rom, - Name = entry.Key, + Filename = entry.Key, Size = entry.Size, - CRC = entry.Crc.ToString("X").ToLowerInvariant(), + CRC = BitConverter.GetBytes(entry.Crc), Date = (date && entry.LastModifiedTime != null ? entry.LastModifiedTime?.ToString("yyyy/MM/dd hh:mm:ss") : null), - MachineName = gamename, + Parent = gamename, }); } // Otherwise, use the stream directly else { Stream entryStream = entry.OpenEntryStream(); - Rom tarEntryRom = (Rom)Utilities.GetStreamInfo(entryStream, entry.Size, omitFromScan: omitFromScan); - tarEntryRom.Name = entry.Key; - tarEntryRom.MachineName = gamename; + BaseFile tarEntryRom = Utilities.GetStreamInfo(entryStream, entry.Size, omitFromScan: omitFromScan); + tarEntryRom.Filename = entry.Key; + tarEntryRom.Parent = gamename; tarEntryRom.Date = entry.LastModifiedTime?.ToString("yyyy/MM/dd hh:mm:ss"); found.Add(tarEntryRom); entryStream.Dispose(); diff --git a/SabreTools.Library/FileTypes/TorrentZipArchive.cs b/SabreTools.Library/FileTypes/TorrentZipArchive.cs index 340254b0..b04232f1 100644 --- a/SabreTools.Library/FileTypes/TorrentZipArchive.cs +++ b/SabreTools.Library/FileTypes/TorrentZipArchive.cs @@ -268,9 +268,9 @@ namespace SabreTools.Library.FileTypes /// 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 List GetArchiveFileInfo(Hash omitFromScan = Hash.DeepHashes, bool date = false) + public override List GetChildren(Hash omitFromScan = Hash.DeepHashes, bool date = false) { - List found = new List(); + List found = new List(); string gamename = Path.GetFileNameWithoutExtension(_filename); try @@ -300,26 +300,25 @@ namespace SabreTools.Library.FileTypes { string newname = zf.Entries[i].FileName; long newsize = (long)zf.Entries[i].UncompressedSize; - string newcrc = BitConverter.ToString(zf.Entries[i].CRC.Reverse().ToArray(), 0, zf.Entries[i].CRC.Length).Replace("-", string.Empty).ToLowerInvariant(); + byte[] newcrc = zf.Entries[i].CRC.Reverse().ToArray(); string convertedDate = Utilities.ConvertMsDosTimeFormatToDateTime(zf.Entries[i].LastMod).ToString("yyyy/MM/dd hh:mm:ss"); - found.Add(new Rom + found.Add(new BaseFile { - Type = ItemType.Rom, - Name = newname, + Filename = newname, Size = newsize, CRC = newcrc, Date = (date ? convertedDate : null), - MachineName = gamename, + Parent = gamename, }); } // Otherwise, use the stream directly else { - Rom zipEntryRom = (Rom)Utilities.GetStreamInfo(readStream, (long)zf.Entries[i].UncompressedSize, omitFromScan: omitFromScan); - zipEntryRom.Name = zf.Entries[i].FileName; - zipEntryRom.MachineName = gamename; + BaseFile zipEntryRom = Utilities.GetStreamInfo(readStream, (long)zf.Entries[i].UncompressedSize, omitFromScan: omitFromScan); + zipEntryRom.Filename = zf.Entries[i].FileName; + zipEntryRom.Parent = gamename; string convertedDate = Utilities.ConvertMsDosTimeFormatToDateTime(zf.Entries[i].LastMod).ToString("yyyy/MM/dd hh:mm:ss"); zipEntryRom.Date = (date ? convertedDate : null); found.Add(zipEntryRom); diff --git a/SabreTools.Library/FileTypes/XZArchive.cs b/SabreTools.Library/FileTypes/XZArchive.cs index 90f85ce3..74173c43 100644 --- a/SabreTools.Library/FileTypes/XZArchive.cs +++ b/SabreTools.Library/FileTypes/XZArchive.cs @@ -191,7 +191,7 @@ namespace SabreTools.Library.FileTypes /// 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 List GetArchiveFileInfo(Hash omitFromScan = Hash.DeepHashes, bool date = false) + public override List GetChildren(Hash omitFromScan = Hash.DeepHashes, bool date = false) { throw new NotImplementedException(); } diff --git a/SabreTools.Library/FileTypes/ZPAQArchive.cs b/SabreTools.Library/FileTypes/ZPAQArchive.cs index 969dafda..0664a3bb 100644 --- a/SabreTools.Library/FileTypes/ZPAQArchive.cs +++ b/SabreTools.Library/FileTypes/ZPAQArchive.cs @@ -87,7 +87,7 @@ namespace SabreTools.Library.FileTypes /// 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 List GetArchiveFileInfo(Hash omitFromScan = Hash.DeepHashes, bool date = false) + public override List GetChildren(Hash omitFromScan = Hash.DeepHashes, bool date = false) { throw new NotImplementedException(); } diff --git a/SabreTools.Library/FileTypes/ZstdArchive.cs b/SabreTools.Library/FileTypes/ZstdArchive.cs index 3e861b35..b712f46a 100644 --- a/SabreTools.Library/FileTypes/ZstdArchive.cs +++ b/SabreTools.Library/FileTypes/ZstdArchive.cs @@ -87,7 +87,7 @@ namespace SabreTools.Library.FileTypes /// 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 List GetArchiveFileInfo(Hash omitFromScan = Hash.DeepHashes, bool date = false) + public override List GetChildren(Hash omitFromScan = Hash.DeepHashes, bool date = false) { throw new NotImplementedException(); } diff --git a/SabreTools.Library/Tools/Utilities.cs b/SabreTools.Library/Tools/Utilities.cs index 1e6d237b..7578e2dc 100644 --- a/SabreTools.Library/Tools/Utilities.cs +++ b/SabreTools.Library/Tools/Utilities.cs @@ -440,7 +440,7 @@ namespace SabreTools.Library.Tools /// /// Name of the file to create the archive from /// Archive object representing the inputs - public static BaseArchive GetArchive(string input) + public static Folder GetArchive(string input) { BaseArchive archive = null; @@ -485,7 +485,7 @@ namespace SabreTools.Library.Tools /// /// SharpCompress.Common.ArchiveType representing the archive to create /// Archive object representing the inputs - public static BaseArchive GetArchive(FileType archiveType) + public static Folder GetArchive(FileType archiveType) { switch (archiveType) { @@ -509,7 +509,7 @@ namespace SabreTools.Library.Tools /// /// SabreTools.Library.Data.SharpCompress.OutputFormat representing the archive to create /// Archive object representing the inputs - public static BaseArchive GetArchive(OutputFormat outputFormat) + public static Folder GetArchive(OutputFormat outputFormat) { switch (outputFormat) { @@ -1033,14 +1033,14 @@ namespace SabreTools.Library.Tools /// Get internal metadata from a CHD /// /// Filename of possible CHD - /// A Disk object with internal SHA-1 on success, null on error, empty Disk otherwise + /// A CHDFile object with internal SHA-1 on success, null otherwise /// /// Original code had a "writable" param. This is not required for metadata checking /// - public static DatItem GetCHDInfo(string input) + public static BaseFile GetCHDInfo(string input) { FileStream fs = TryOpenRead(input); - DatItem datItem = GetCHDInfo(fs); + BaseFile datItem = GetCHDInfo(fs); fs.Dispose(); return datItem; } @@ -1217,18 +1217,18 @@ namespace SabreTools.Library.Tools /// True if the file Date should be included, false otherwise (default) /// Populated string representing the name of the skipper to use, a blank string to use the first available checker, null otherwise /// True if CHDs should be treated like regular files, false otherwise - /// Populated DatItem object if success, empty one on error - public static DatItem GetFileInfo(string input, Hash omitFromScan = 0x0, + /// Populated BaseFile object if success, empty one on error + public static BaseFile GetFileInfo(string input, Hash omitFromScan = 0x0, long offset = 0, bool date = false, string header = null, bool chdsAsFiles = true) { // Add safeguard if file doesn't exist if (!File.Exists(input)) { - return new Rom(); + return null; } // Get the information from the file stream - DatItem datItem = new Rom(); + BaseFile baseFile = new BaseFile(); if (header != null) { SkipperRule rule = Skipper.GetMatchingRule(input, Path.GetFileNameWithoutExtension(header)); @@ -1242,7 +1242,7 @@ namespace SabreTools.Library.Tools // Transform the stream and get the information from it rule.TransformStream(inputStream, outputStream, keepReadOpen: false, keepWriteOpen: true); - datItem = GetStreamInfo(outputStream, outputStream.Length, omitFromScan: omitFromScan, keepReadOpen: false, chdsAsFiles: chdsAsFiles); + baseFile = GetStreamInfo(outputStream, outputStream.Length, omitFromScan: omitFromScan, keepReadOpen: false, chdsAsFiles: chdsAsFiles); // Dispose of the streams outputStream.Dispose(); @@ -1252,23 +1252,20 @@ namespace SabreTools.Library.Tools else { long length = new FileInfo(input).Length; - datItem = GetStreamInfo(TryOpenRead(input), length, omitFromScan, offset, keepReadOpen: false, chdsAsFiles: chdsAsFiles); + baseFile = GetStreamInfo(TryOpenRead(input), length, omitFromScan, offset, keepReadOpen: false, chdsAsFiles: chdsAsFiles); } } else { long length = new FileInfo(input).Length; - datItem = GetStreamInfo(TryOpenRead(input), length, omitFromScan, offset, keepReadOpen: false, chdsAsFiles: chdsAsFiles); + baseFile = GetStreamInfo(TryOpenRead(input), length, omitFromScan, offset, keepReadOpen: false, chdsAsFiles: chdsAsFiles); } // Add unique data from the file - datItem.Name = Path.GetFileName(input); - if (datItem.Type == ItemType.Rom) - { - ((Rom)datItem).Date = (date ? new FileInfo(input).LastWriteTime.ToString("yyyy/MM/dd HH:mm:ss") : ""); - } + baseFile.Filename = Path.GetFileName(input); + baseFile.Date = (date ? new FileInfo(input).LastWriteTime.ToString("yyyy/MM/dd HH:mm:ss") : ""); - return datItem; + return baseFile; } /// @@ -1394,10 +1391,10 @@ namespace SabreTools.Library.Tools /// True if the file is a valid CHD, false otherwise public static bool IsValidCHD(string input) { - DatItem datItem = GetCHDInfo(input); - return datItem != null - && datItem.Type == ItemType.Disk - && ((Disk)datItem).SHA1 != null; + BaseFile baseFile = GetCHDInfo(input); + return baseFile != null + && (((CHDFile)baseFile).MD5 != null + || ((CHDFile)baseFile).SHA1 != null); } /// @@ -1563,8 +1560,8 @@ namespace SabreTools.Library.Tools // Now add the information to the database if it's not already there if (!nostore) { - Rom rom = (Rom)GetFileInfo(newfile, chdsAsFiles: true); - DatabaseTools.AddHeaderToDatabase(hstr, rom.SHA1, rule.SourceFile); + BaseFile baseFile = GetFileInfo(newfile, chdsAsFiles: true); + DatabaseTools.AddHeaderToDatabase(hstr, ByteArrayToString(baseFile.SHA1), rule.SourceFile); } return true; @@ -1698,10 +1695,10 @@ namespace SabreTools.Library.Tools } // First, get the SHA-1 hash of the file - Rom rom = (Rom)GetFileInfo(file, chdsAsFiles: true); + BaseFile baseFile = GetFileInfo(file, chdsAsFiles: true); // Retrieve a list of all related headers from the database - List headers = DatabaseTools.RetrieveHeadersFromDatabase(rom.SHA1); + List headers = DatabaseTools.RetrieveHeadersFromDatabase(ByteArrayToString(baseFile.SHA1)); // If we have nothing retrieved, we return false if (headers.Count == 0) @@ -1923,8 +1920,8 @@ namespace SabreTools.Library.Tools /// Set a >0 number for getting hash for part of the file, 0 otherwise (default) /// True if the underlying read stream should be kept open, false otherwise /// True if CHDs should be treated like regular files, false otherwise - /// Populated DatItem object if success, empty one on error - public static DatItem GetStreamInfo(Stream input, long size, Hash omitFromScan = 0x0, + /// Populated BaseFile object if success, empty one on error + public static BaseFile GetStreamInfo(Stream input, long size, Hash omitFromScan = 0x0, long offset = 0, bool keepReadOpen = false, bool chdsAsFiles = true) { // We first check to see if it's a CHD @@ -1956,7 +1953,7 @@ namespace SabreTools.Library.Tools } // Get the Disk from the information - DatItem disk = GetCHDInfo(input); + BaseFile disk = GetCHDInfo(input); // Seek to the beginning of the stream if possible try @@ -1980,16 +1977,9 @@ namespace SabreTools.Library.Tools return disk; } - Rom rom = new Rom + BaseFile rom = new BaseFile() { - Type = ItemType.Rom, Size = size, - CRC = string.Empty, - MD5 = string.Empty, - SHA1 = string.Empty, - SHA256 = string.Empty, - SHA384 = string.Empty, - SHA512 = string.Empty, }; try @@ -2061,32 +2051,32 @@ namespace SabreTools.Library.Tools } crc.Update(buffer, 0, 0); - rom.CRC = crc.Value.ToString("X8").ToLowerInvariant(); + rom.CRC = BitConverter.GetBytes(crc.Value); if ((omitFromScan & Hash.MD5) == 0) { md5.TransformFinalBlock(buffer, 0, 0); - rom.MD5 = ByteArrayToString(md5.Hash); + rom.MD5 = md5.Hash; } if ((omitFromScan & Hash.SHA1) == 0) { sha1.TransformFinalBlock(buffer, 0, 0); - rom.SHA1 = ByteArrayToString(sha1.Hash); + rom.SHA1 = sha1.Hash; } if ((omitFromScan & Hash.SHA256) == 0) { sha256.TransformFinalBlock(buffer, 0, 0); - rom.SHA256 = ByteArrayToString(sha256.Hash); + rom.SHA256 = sha256.Hash; } if ((omitFromScan & Hash.SHA384) == 0) { sha384.TransformFinalBlock(buffer, 0, 0); - rom.SHA384 = ByteArrayToString(sha384.Hash); + rom.SHA384 = sha384.Hash; } if ((omitFromScan & Hash.SHA512) == 0) { sha512.TransformFinalBlock(buffer, 0, 0); - rom.SHA512 = ByteArrayToString(sha512.Hash); + rom.SHA512 = sha512.Hash; } if ((omitFromScan & Hash.xxHash) == 0) { @@ -2103,7 +2093,7 @@ namespace SabreTools.Library.Tools } catch (IOException) { - return new Rom(); + return new BaseFile(); } finally { @@ -2134,32 +2124,31 @@ namespace SabreTools.Library.Tools /// Get internal metadata from a CHD /// /// Stream of possible CHD - /// A Disk object with internal SHA-1 on success, null on error, empty Disk otherwise + /// A CHDFile object with internal MD5 (v1, v2) or SHA-1 (v3, v4, v5) on success, null otherwise /// /// Original code had a "writable" param. This is not required for metadata checking /// - public static DatItem GetCHDInfo(Stream input) + public static BaseFile GetCHDInfo(Stream input) { - // Create a blank Disk to populate and return - Disk datItem = new Disk(); - // Get a CHD object to store the data CHDFile chd = new CHDFile(input); - // Get the best possible hash from the chd + // Ensure that the header is valid byte[] hash = chd.GetHashFromHeader(); // Set the proper hash of the Disk to return if (hash.Length == Constants.MD5Length) { - datItem.MD5 = (hash == null ? null : ByteArrayToString(hash)); + chd.MD5 = hash; + return chd; } else if (hash.Length == Constants.SHA1Length) { - datItem.SHA1 = (hash == null ? null : ByteArrayToString(hash)); + chd.SHA1 = hash; + return chd; } - return datItem; + return null; } /// @@ -2185,10 +2174,10 @@ namespace SabreTools.Library.Tools /// True if the stream is a valid CHD, false otherwise public static bool IsValidCHD(Stream input) { - DatItem datItem = GetCHDInfo(input); - return datItem != null - && datItem.Type == ItemType.Disk - && ((Disk)datItem).SHA1 != null; + BaseFile baseFile = GetCHDInfo(input); + return baseFile != null + && (((CHDFile)baseFile).MD5 != null + || ((CHDFile)baseFile).SHA1 != null); } #endregion