[ArchiveTools, DATFromDir, DatTools, SimpleSort] More code modularization to make it more stable and clean

This commit is contained in:
Matt Nadareski
2016-06-13 22:12:00 -07:00
parent b5e6828f47
commit 49bde7c33f
4 changed files with 247 additions and 379 deletions

View File

@@ -1,6 +1,8 @@
using System;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Text.RegularExpressions;
using SharpCompress.Archive;
using SharpCompress.Common;
@@ -151,5 +153,85 @@ namespace SabreTools.Helper
return !encounteredErrors;
}
/// <summary>
/// Retrieve file information for a single torrent GZ file
/// </summary>
/// <param name="input">Filename to get information from</param>
/// <returns>Populated RomData object if success, empty one on error</returns>
public static RomData GetTorrentGZFileInfo(string input, Logger logger)
{
string datum = Path.GetFileName(input).ToLowerInvariant();
long filesize = new FileInfo(input).Length;
// Check if the name is the right length
if (!Regex.IsMatch(datum, @"^[0-9a-f]{40}\.gz"))
{
logger.Warning("Non SHA-1 filename found, skipping: '" + datum + "'");
return new RomData();
}
// Check if the file is at least the minimum length
if (filesize < 32 /* bytes */)
{
logger.Warning("Possibly corrupt file '" + input + "' with size " + Style.GetBytesReadable(filesize));
return new RomData();
}
// Get the Romba-specific header data
byte[] header;
byte[] footer;
using (FileStream itemstream = File.OpenRead(input))
{
using (BinaryReader br = new BinaryReader(itemstream))
{
header = br.ReadBytes(32);
br.BaseStream.Seek(-4, SeekOrigin.End);
footer = br.ReadBytes(4);
}
}
// Now convert the data and get the right positions
string headerstring = BitConverter.ToString(header).Replace("-", string.Empty);
string gzmd5 = headerstring.Substring(24, 32);
string gzcrc = headerstring.Substring(56, 8);
string gzsize = BitConverter.ToString(footer.Reverse().ToArray()).Replace("-", string.Empty);
long extractedsize = Convert.ToInt64(gzsize, 16);
// Only try to add if the file size is greater than 750 MiB
if (filesize >= (750 * Constants.MibiByte))
{
// ISIZE is mod 4GiB, so we add that if the ISIZE is smaller than the filesize and greater than 1% different
bool shouldfollowup = false;
if (extractedsize < filesize && (100 * extractedsize / filesize) < 99 /* percent */)
{
logger.Log("mancalc - Filename: '" + Path.GetFullPath(input) + "'\nExtracted file size: " +
extractedsize + ", " + Style.GetBytesReadable(extractedsize) + "\nArchive file size: " + filesize + ", " + Style.GetBytesReadable(filesize));
}
while (extractedsize < filesize && (100 * extractedsize / filesize) < 99 /* percent */)
{
extractedsize += (4 * Constants.GibiByte);
shouldfollowup = true;
}
if (shouldfollowup)
{
logger.Log("Filename: '" + Path.GetFullPath(input) + "'\nFinal file size: " + extractedsize + ", " + Style.GetBytesReadable(extractedsize) +
"\nExtracted CRC: " + gzcrc + "\nExtracted MD5: " + gzmd5 + "\nSHA-1: " + Path.GetFileNameWithoutExtension(input));
}
}
RomData rom = new RomData
{
Type = "rom",
Game = Path.GetFileNameWithoutExtension(input),
Name = Path.GetFileNameWithoutExtension(input),
Size = extractedsize,
CRC = gzcrc,
MD5 = gzmd5,
SHA1 = Path.GetFileNameWithoutExtension(input),
};
return rom;
}
}
}

View File

@@ -2,9 +2,12 @@
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Security.Cryptography;
using System.Text.RegularExpressions;
using System.Xml;
using DamienG.Security.Cryptography;
namespace SabreTools.Helper
{
public class DatTools
@@ -1831,7 +1834,8 @@ namespace SabreTools.Helper
/// <param name="nodump">Select roms with nodump status as follows: null (match all), true (match Nodump only), false (exclude Nodump)</param>
/// <param name="logger">Logging object for console and file output</param>
/// <returns>Returns filtered DatData object</returns>
public static DatData Filter(DatData datdata, string gamename, string romname, string romtype, long sgt, long slt, long seq, string crc, string md5, string sha1, bool? nodump, Logger logger)
public static DatData Filter(DatData datdata, string gamename, string romname, string romtype, long sgt,
long slt, long seq, string crc, string md5, string sha1, bool? nodump, Logger logger)
{
// Now loop through and create a new Rom dictionary using filtered values
Dictionary<string, List<RomData>> dict = new Dictionary<string, List<RomData>>();
@@ -1981,5 +1985,52 @@ namespace SabreTools.Helper
return datdata;
}
/// <summary>
/// Retrieve file information for a single file
/// </summary>
/// <param name="input">Filename to get information from</param>
/// <returns>Populated RomData object if success, empty one on error</returns>
public static RomData GetSingleFileInfo(string input)
{
RomData rom = new RomData
{
Name = Path.GetFileName(input),
Type = "rom",
Size = (new FileInfo(input)).Length,
CRC = string.Empty,
MD5 = string.Empty,
SHA1 = string.Empty,
};
try
{
Crc32 crc = new Crc32();
MD5 md5 = MD5.Create();
SHA1 sha1 = SHA1.Create();
using (FileStream fs = File.Open(input, FileMode.Open))
{
foreach (byte b in crc.ComputeHash(fs))
{
rom.CRC += b.ToString("x2").ToLowerInvariant();
}
}
using (FileStream fs = File.Open(input, FileMode.Open))
{
rom.MD5 = BitConverter.ToString(md5.ComputeHash(fs)).Replace("-", "").ToLowerInvariant();
}
using (FileStream fs = File.Open(input, FileMode.Open))
{
rom.SHA1 = BitConverter.ToString(sha1.ComputeHash(fs)).Replace("-", "").ToLowerInvariant();
}
}
catch (IOException)
{
return new RomData();
}
return rom;
}
}
}

View File

@@ -124,7 +124,7 @@ namespace SabreTools
// This is where the main loop would go
if (File.Exists(_basePath))
{
lastparent = ProcessFile(_basePath, sw, lastparent);
lastparent = ProcessPossibleArchive(_basePath, sw, lastparent);
}
else if (Directory.Exists(_basePath))
{
@@ -133,7 +133,7 @@ namespace SabreTools
// Process the files in the base folder first
foreach (string item in Directory.EnumerateFiles(_basePath, "*", SearchOption.TopDirectoryOnly))
{
lastparent = ProcessFile(item, sw, lastparent);
lastparent = ProcessPossibleArchive(item, sw, lastparent);
}
// Then process each of the subfolders themselves
@@ -150,7 +150,7 @@ namespace SabreTools
foreach (string subitem in Directory.EnumerateFiles(item, "*", SearchOption.AllDirectories))
{
items = true;
lastparent = ProcessFile(subitem, sw, lastparent);
lastparent = ProcessPossibleArchive(subitem, sw, lastparent);
}
// In romba mode we ignore empty folders completely
@@ -295,7 +295,7 @@ namespace SabreTools
/// <param name="sw">StreamWriter representing the output file</param>
/// <param name="lastparent">Name of the last parent rom to make sure that everything is grouped as well as possible</param>
/// <returns>New parent to be used</returns>
private string ProcessFile(string item, StreamWriter sw, string lastparent)
private string ProcessPossibleArchive(string item, StreamWriter sw, string lastparent)
{
// Define the temporary directory
string tempdir = (String.IsNullOrEmpty(_tempDir) ? Environment.CurrentDirectory : _tempDir);
@@ -305,255 +305,46 @@ namespace SabreTools
// Special case for if we are in Romba mode (all names are supposed to be SHA-1 hashes)
if (_datdata.Romba)
{
string datum = Path.GetFileName(item).ToLowerInvariant();
long filesize = new FileInfo(item).Length;
RomData rom = ArchiveTools.GetTorrentGZFileInfo(item, _logger);
// Check if the name is the right length
if (!Regex.IsMatch(datum, @"^[0-9a-f]{40}\.gz"))
// If the rom is valid, write it out
if (rom.Name != null)
{
_logger.Warning("Non SHA-1 filename found, skipping: '" + datum + "'");
return "";
}
// Check if the file is at least the minimum length
if (filesize < 32 /* bytes */)
{
_logger.Warning("Possibly corrupt file '" + item + "' with size " + Style.GetBytesReadable(filesize));
return "";
}
// Get the Romba-specific header data
byte[] header;
byte[] footer;
using (FileStream itemstream = File.OpenRead(item))
{
using (BinaryReader br = new BinaryReader(itemstream))
{
header = br.ReadBytes(32);
br.BaseStream.Seek(-4, SeekOrigin.End);
footer = br.ReadBytes(4);
}
}
// Now convert the data and get the right positions
string headerstring = BitConverter.ToString(header).Replace("-", string.Empty);
string gzmd5 = headerstring.Substring(24, 32);
string gzcrc = headerstring.Substring(56, 8);
string gzsize = BitConverter.ToString(footer.Reverse().ToArray()).Replace("-", string.Empty);
long extractedsize = Convert.ToInt64(gzsize, 16);
// Only try to add if the file size is greater than 750 MiB
if (filesize >= (750 * Constants.MibiByte))
{
// ISIZE is mod 4GiB, so we add that if the ISIZE is smaller than the filesize and greater than 1% different
bool shouldfollowup = false;
if (extractedsize < filesize && (100 * extractedsize / filesize) < 99 /* percent */)
{
_logger.Log("mancalc - Filename: '" + Path.GetFullPath(item) + "'\nExtracted file size: " +
extractedsize + ", " + Style.GetBytesReadable(extractedsize) + "\nArchive file size: " + filesize + ", " + Style.GetBytesReadable(filesize));
}
while (extractedsize < filesize && (100 * extractedsize / filesize) < 99 /* percent */)
{
extractedsize += (4 * Constants.GibiByte);
shouldfollowup = true;
}
if (shouldfollowup)
{
_logger.Log("Filename: '" + Path.GetFullPath(item) + "'\nFinal file size: " + extractedsize + ", " + Style.GetBytesReadable(extractedsize) +
"\nExtracted CRC: " + gzcrc + "\nExtracted MD5: " + gzmd5 + "\nSHA-1: " + Path.GetFileNameWithoutExtension(item));
}
}
RomData rom = new RomData
{
Type = "rom",
Game = Path.GetFileNameWithoutExtension(item),
Name = Path.GetFileNameWithoutExtension(item),
Size = extractedsize,
CRC = gzcrc,
MD5 = gzmd5,
SHA1 = Path.GetFileNameWithoutExtension(item),
};
int last = 0;
Output.WriteStartGame(sw, rom, new List<string>(), "", _datdata, 0, 0, _logger);
Output.WriteRomData(sw, rom, "", _datdata, 0, _logger);
Output.WriteEndGame(sw, rom, new List<string>(), new List<string>(), "", _datdata, 0, out last, _logger);
}
else
{
return string.Empty;
}
_logger.User("File added: " + Path.GetFileNameWithoutExtension(item) + Environment.NewLine);
return rom.Game;
}
// Create the temporary output directory
bool encounteredErrors = true;
if (!_archivesAsFiles)
{
IArchive archive = null;
try
{
archive = ArchiveFactory.Open(item);
ArchiveType at = archive.Type;
_logger.Log("Found archive of type: " + at);
if (at == ArchiveType.Zip || at == ArchiveType.SevenZip || at == ArchiveType.Rar)
{
// Create the temp directory
DirectoryInfo di = Directory.CreateDirectory(tempdir);
// Extract all files to the temp directory
IReader reader = archive.ExtractAllEntries();
reader.WriteAllToDirectory(tempdir, ExtractOptions.ExtractFullPath);
encounteredErrors = false;
}
else if (at == ArchiveType.GZip && _enableGzip)
{
// Close the original archive handle
archive.Dispose();
// Create the temp directory
DirectoryInfo di = Directory.CreateDirectory(tempdir);
using (FileStream itemstream = File.OpenRead(item))
{
using (FileStream outstream = File.Create(tempdir + Path.GetFileNameWithoutExtension(item)))
{
using (GZipStream gz = new GZipStream(itemstream, CompressionMode.Decompress))
{
gz.CopyTo(outstream);
}
}
}
encounteredErrors = false;
}
archive.Dispose();
}
catch (InvalidOperationException)
{
encounteredErrors = true;
if (archive != null)
{
archive.Dispose();
}
}
catch (Exception ex)
{
_logger.Error(ex.ToString());
encounteredErrors = true;
if (archive != null)
{
archive.Dispose();
}
}
}
// Get a list of files including size and hashes
Crc32 crc = new Crc32();
MD5 md5 = MD5.Create();
SHA1 sha1 = SHA1.Create();
// Attempt to extract the files to the temporary directory
bool encounteredErrors = !ArchiveTools.ExtractArchive(item,
tempdir,
(_archivesAsFiles ? ArchiveScanLevel.External : ArchiveScanLevel.Internal),
(!_archivesAsFiles && _enableGzip ? ArchiveScanLevel.Internal : ArchiveScanLevel.External),
(_archivesAsFiles ? ArchiveScanLevel.External : ArchiveScanLevel.Internal),
(_archivesAsFiles ? ArchiveScanLevel.External : ArchiveScanLevel.Internal),
_logger);
// If the file was an archive and was extracted successfully, check it
if (!encounteredErrors)
{
int last = 0;
_logger.Log(Path.GetFileName(item) + " treated like an archive");
foreach (string entry in Directory.EnumerateFiles(tempdir, "*", SearchOption.AllDirectories))
{
_logger.Log("Found file: " + entry);
string fileCRC = string.Empty;
string fileMD5 = string.Empty;
string fileSHA1 = string.Empty;
try
{
using (FileStream fs = File.Open(entry, FileMode.Open))
{
foreach (byte b in crc.ComputeHash(fs))
{
fileCRC += b.ToString("x2").ToLower();
}
}
if (!_noMD5)
{
using (FileStream fs = File.Open(entry, FileMode.Open))
{
fileMD5 = BitConverter.ToString(md5.ComputeHash(fs)).Replace("-", "");
}
}
if (!_noSHA1)
{
using (FileStream fs = File.Open(entry, FileMode.Open))
{
fileSHA1 = BitConverter.ToString(sha1.ComputeHash(fs)).Replace("-", "");
}
}
}
catch (IOException)
{
continue;
lastparent = ProcessFile(Path.GetFullPath(entry), sw, Path.GetFullPath(tempdir),
(Path.GetDirectoryName(Path.GetFullPath(item)) + Path.DirectorySeparatorChar).Remove(0, _basePath.Length) +
Path.DirectorySeparatorChar + Path.GetFileNameWithoutExtension(item), _datdata, lastparent);
}
string actualroot = "";
string actualitem = "";
actualitem = entry.Remove(0, tempdir.Length);
// If we're in SuperDAT mode, make sure the added item is by itself
if (_datdata.Type == "SuperDAT")
{
actualroot = Path.GetDirectoryName(item.Remove(0, _basePath.Length));
actualroot = (actualroot == "" ? _basePath.Split(Path.DirectorySeparatorChar).Last() : actualroot);
actualroot += Path.DirectorySeparatorChar + Path.GetFileNameWithoutExtension(item) + Path.DirectorySeparatorChar + Path.GetDirectoryName(actualitem);
actualroot = actualroot.TrimEnd(Path.DirectorySeparatorChar);
actualitem = Path.GetFileName(actualitem);
}
// Otherwise, set the correct root and such
else
{
actualroot = Path.GetFileNameWithoutExtension(item);
actualroot = actualroot.TrimEnd(Path.DirectorySeparatorChar);
}
RomData rom = new RomData
{
Type = "rom",
Game = (_datdata.Type == "SuperDAT" ?
_datdata.Name + (actualroot != "" && !actualroot.StartsWith(Path.DirectorySeparatorChar.ToString()) ?
Path.DirectorySeparatorChar.ToString() :
"") + actualroot :
actualroot),
Name = actualitem,
Size = (new FileInfo(entry)).Length,
CRC = fileCRC,
MD5 = fileMD5,
SHA1 = fileSHA1,
};
// If we have a different game and we're not at the start of the list, output the end of last item
if (lastparent != null && lastparent.ToLowerInvariant() != rom.Game.ToLowerInvariant())
{
Output.WriteEndGame(sw, rom, new List<string>(), new List<string>(), lastparent, _datdata, 0, out last, _logger);
}
// If we have a different game and we're not at the start of the list, output the end of the last item
else if (lastparent != null && lastparent.ToLowerInvariant() != rom.Game.ToLowerInvariant())
{
Output.WriteEndGame(sw, rom, new List<string>(), new List<string>(), lastparent, _datdata, 0, out last, _logger);
}
// If we have a new game, output the beginning of the new item
if (lastparent == null || lastparent.ToLowerInvariant() != rom.Game.ToLowerInvariant())
{
Output.WriteStartGame(sw, rom, new List<string>(), lastparent, _datdata, 0, last, _logger);
}
// Write out the rom data
Output.WriteRomData(sw, rom, lastparent, _datdata, 0, _logger);
_logger.User("File added: " + entry + Environment.NewLine);
lastparent = rom.Game;
}
// Delete the temp directory
// Clear the temp directory
if (Directory.Exists(tempdir))
{
Directory.Delete(tempdir, true);
@@ -562,52 +353,53 @@ namespace SabreTools
// Otherwise, just get the info on the file itself
else if (!Directory.Exists(item) && File.Exists(item))
{
_logger.Log(Path.GetFileName(item) + " treated like a file");
lastparent = ProcessFile(item, sw, _basePath, "", _datdata, lastparent);
}
return lastparent;
}
string fileCRC = String.Empty;
string fileMD5 = String.Empty;
string fileSHA1 = String.Empty;
/// <summary>
/// Process a single file as a file
/// </summary>
/// <param name="item">File to be added</param>
/// <param name="sw">StreamWriter representing the output file</param>
/// <param name="basepath">Path the represents the parent directory</param>
/// <param name="parent">Parent game to be used</param>
/// <param name="datdata">DatData object with output information</param>
/// <param name="lastparent">Last known parent game name</param>
/// <returns>New last known parent game name</returns>
private string ProcessFile(string item, StreamWriter sw, string basepath, string parent, DatData datdata, string lastparent)
{
_logger.Log(Path.GetFileName(item) + " treated like a file");
RomData rom = DatTools.GetSingleFileInfo(item);
try
{
using (FileStream fs = File.Open(item, FileMode.Open))
if (basepath.EndsWith(Path.DirectorySeparatorChar.ToString()))
{
foreach (byte b in crc.ComputeHash(fs))
{
fileCRC += b.ToString("x2").ToLower();
}
}
if (!_noMD5)
{
using (FileStream fs = File.Open(item, FileMode.Open))
{
fileMD5 = BitConverter.ToString(md5.ComputeHash(fs)).Replace("-", "");
}
}
if (!_noSHA1)
{
using (FileStream fs = File.Open(item, FileMode.Open))
{
fileSHA1 = BitConverter.ToString(sha1.ComputeHash(fs)).Replace("-", "");
}
basepath = basepath.Substring(0, basepath.Length - 1);
}
if (_basePath.EndsWith(Path.DirectorySeparatorChar.ToString()))
string actualroot = (item == basepath ? item.Split(Path.DirectorySeparatorChar).Last() : item.Remove(0, basepath.Length).Split(Path.DirectorySeparatorChar)[0]);
if (parent == "")
{
_basePath = _basePath.Substring(0, _basePath.Length - 1);
actualroot = (actualroot == "" && datdata.Type != "SuperDAT" ? basepath.Split(Path.DirectorySeparatorChar).Last() : actualroot);
}
string actualroot = (item == _basePath ? item.Split(Path.DirectorySeparatorChar).Last() : item.Remove(0, _basePath.Length).Split(Path.DirectorySeparatorChar)[0]);
actualroot = (actualroot == "" && _datdata.Type != "SuperDAT" ? _basePath.Split(Path.DirectorySeparatorChar).Last() : actualroot);
string actualitem = (item == _basePath ? item : item.Remove(0, _basePath.Length + 1));
string actualitem = (item == basepath ? item : item.Remove(0, basepath.Length + 1));
// If we're in SuperDAT mode, make sure the added item is by itself
if (_datdata.Type == "SuperDAT")
if (datdata.Type == "SuperDAT")
{
actualroot += (actualroot != "" ? Path.DirectorySeparatorChar.ToString() : "") + Path.GetDirectoryName(actualitem);
actualroot += (actualroot != "" ? Path.DirectorySeparatorChar.ToString() : "") +
(parent != "" ? parent + Path.DirectorySeparatorChar : "") +
Path.GetDirectoryName(actualitem);
actualroot = actualroot.TrimEnd(Path.DirectorySeparatorChar);
actualitem = Path.GetFileName(actualitem);
}
else if (parent != "")
{
actualroot = parent.TrimEnd(Path.DirectorySeparatorChar);
}
// Drag and drop is funny
if (actualitem == Path.GetFullPath(actualitem))
@@ -617,36 +409,30 @@ namespace SabreTools
_logger.Log("Actual item added: " + actualitem);
RomData rom = new RomData
{
Type = "rom",
Game = (_datdata.Type == "SuperDAT" ?
_datdata.Name + (actualroot != "" && !actualroot.StartsWith(Path.DirectorySeparatorChar.ToString()) ?
// Update rom information
rom.Game = (datdata.Type == "SuperDAT" ?
datdata.Name + (actualroot != "" && !actualroot.StartsWith(Path.DirectorySeparatorChar.ToString()) ?
Path.DirectorySeparatorChar.ToString() :
"") + actualroot :
actualroot),
Name = actualitem,
Size = (new FileInfo(item)).Length,
CRC = fileCRC,
MD5 = fileMD5,
SHA1 = fileSHA1,
};
actualroot);
rom.Game = rom.Game.Replace(Path.DirectorySeparatorChar.ToString() + Path.DirectorySeparatorChar.ToString(), Path.DirectorySeparatorChar.ToString());
rom.Name = actualitem;
// If we have a different game and we're not at the start of the list, output the end of last item
int last = 0;
if (lastparent != null && lastparent.ToLowerInvariant() != rom.Game.ToLowerInvariant())
{
Output.WriteEndGame(sw, rom, new List<string>(), new List<string>(), lastparent, _datdata, 0, out last, _logger);
Output.WriteEndGame(sw, rom, new List<string>(), new List<string>(), lastparent, datdata, 0, out last, _logger);
}
// If we have a new game, output the beginning of the new item
if (lastparent == null || lastparent.ToLowerInvariant() != rom.Game.ToLowerInvariant())
{
Output.WriteStartGame(sw, rom, new List<string>(), lastparent, _datdata, 0, last, _logger);
Output.WriteStartGame(sw, rom, new List<string>(), lastparent, datdata, 0, last, _logger);
}
// Write out the rom data
Output.WriteRomData(sw, rom, lastparent, _datdata, 0, _logger);
Output.WriteRomData(sw, rom, lastparent, datdata, 0, _logger);
_logger.User("File added: " + actualitem + Environment.NewLine);
return rom.Game;
@@ -657,7 +443,5 @@ namespace SabreTools
return null;
}
}
return lastparent;
}
}
}

View File

@@ -1,10 +1,8 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Security.Cryptography;
using SabreTools.Helper;
using DamienG.Security.Cryptography;
using SharpCompress.Common;
namespace SabreTools
@@ -299,7 +297,7 @@ namespace SabreTools
_logger.User("Beginning processing of '" + input + "'");
// Get the hash of the file first
RomData rom = GetSingleFileInfo(input);
RomData rom = DatTools.GetSingleFileInfo(input);
// If we have a blank RomData, it's an error
if (rom.Name == null)
@@ -336,52 +334,5 @@ namespace SabreTools
return success;
}
/// <summary>
/// Retrieve file information for a single file
/// </summary>
/// <param name="input">Filename to get information from</param>
/// <returns>Populated RomData object if success, empty one on error</returns>
public static RomData GetSingleFileInfo(string input)
{
RomData rom = new RomData
{
Name = Path.GetFileName(input),
Type = "rom",
Size = (new FileInfo(input)).Length,
CRC = string.Empty,
MD5 = string.Empty,
SHA1 = string.Empty,
};
try
{
Crc32 crc = new Crc32();
MD5 md5 = MD5.Create();
SHA1 sha1 = SHA1.Create();
using (FileStream fs = File.Open(input, FileMode.Open))
{
foreach (byte b in crc.ComputeHash(fs))
{
rom.CRC += b.ToString("x2").ToLowerInvariant();
}
}
using (FileStream fs = File.Open(input, FileMode.Open))
{
rom.MD5 = BitConverter.ToString(md5.ComputeHash(fs)).Replace("-", "").ToLowerInvariant();
}
using (FileStream fs = File.Open(input, FileMode.Open))
{
rom.SHA1 = BitConverter.ToString(sha1.ComputeHash(fs)).Replace("-", "").ToLowerInvariant();
}
}
catch (IOException)
{
return new RomData();
}
return rom;
}
}
}