[CHDFile, Utilities] The great CHD cleanup

This commit is contained in:
Matt Nadareski
2018-02-16 00:25:28 -08:00
parent 60f3f2d2c9
commit cef409cb92
2 changed files with 136 additions and 143 deletions

View File

@@ -1,7 +1,4 @@
using System; using SabreTools.Library.Data;
using System.Linq;
using SabreTools.Library.Data;
using SabreTools.Library.Tools; using SabreTools.Library.Tools;
#if MONO #if MONO
@@ -88,7 +85,7 @@ namespace SabreTools.Library.FileTypes
/// 0x68-0x7b - Parent SHA-1 /// 0x68-0x7b - Parent SHA-1
/// ---------------------------------------------- /// ----------------------------------------------
/// </remarks> /// </remarks>
public class CHDFile : BaseFile, IDisposable public class CHDFile : BaseFile
{ {
#region Private instance variables #region Private instance variables
@@ -110,12 +107,61 @@ namespace SabreTools.Library.FileTypes
private uint m_mapentrybytes; // length of each entry in a map private uint m_mapentrybytes; // length of each entry in a map
// additional required vars // additional required vars
private uint? _headerVersion;
private BinaryReader m_br; // Binary reader representing the CHD stream private BinaryReader m_br; // Binary reader representing the CHD stream
#endregion #endregion
#region Pubically facing variables
public uint? Version
{
get
{
if (_headerVersion == null)
{
_headerVersion = ValidateHeaderVersion();
}
return _headerVersion;
}
}
#endregion
#region Constructors #region Constructors
/// <summary>
/// Create a new, blank CHDFile
/// </summary>
public CHDFile()
{
this._fileType = FileType.CHD;
}
/// <summary>
/// Create a new CHDFile from an input file
/// </summary>
/// <param name="filename"></param>
public CHDFile(string filename)
: base(filename)
{
_fileType = FileType.CHD;
m_br = new BinaryReader(Utilities.TryOpenRead(filename));
_headerVersion = ValidateHeaderVersion();
byte[] hash = GetHashFromHeader();
if (hash.Length == Constants.MD5Length)
{
_md5 = hash;
}
else if (hash.Length == Constants.SHA1Length)
{
_sha1 = hash;
}
}
/// <summary> /// <summary>
/// Create a new CHDFile from an input stream /// Create a new CHDFile from an input stream
/// </summary> /// </summary>
@@ -124,14 +170,18 @@ namespace SabreTools.Library.FileTypes
{ {
_fileType = FileType.CHD; _fileType = FileType.CHD;
m_br = new BinaryReader(chdstream); m_br = new BinaryReader(chdstream);
}
/// <summary> _headerVersion = ValidateHeaderVersion();
/// Dispose of the CHDFile
/// </summary> byte[] hash = GetHashFromHeader();
public void Dispose() if (hash.Length == Constants.MD5Length)
{ {
m_br.Dispose(); _md5 = hash;
}
else if (hash.Length == Constants.SHA1Length)
{
_sha1 = hash;
}
} }
#endregion #endregion
@@ -142,7 +192,9 @@ namespace SabreTools.Library.FileTypes
/// Validate the initial signature, version, and header size /// Validate the initial signature, version, and header size
/// </summary> /// </summary>
/// <returns>Unsigned int containing the version number, null if invalid</returns> /// <returns>Unsigned int containing the version number, null if invalid</returns>
public uint? ValidateHeaderVersion() private uint? ValidateHeaderVersion()
{
try
{ {
// Seek to the beginning to make sure we're reading the correct bytes // Seek to the beginning to make sure we're reading the correct bytes
m_br.BaseStream.Seek(0, SeekOrigin.Begin); m_br.BaseStream.Seek(0, SeekOrigin.Begin);
@@ -180,12 +232,17 @@ namespace SabreTools.Library.FileTypes
return m_version; return m_version;
} }
catch
{
return null;
}
}
/// <summary> /// <summary>
/// Get the internal MD5 (v1, v2) or SHA-1 (v3, v4, v5) from the CHD /// Get the internal MD5 (v1, v2) or SHA-1 (v3, v4, v5) from the CHD
/// </summary> /// </summary>
/// <returns>MD5 as a byte array, null on error</returns> /// <returns>MD5 as a byte array, null on error</returns>
public byte[] GetHashFromHeader() private byte[] GetHashFromHeader()
{ {
// Validate the header by default just in case // Validate the header by default just in case
uint? version = ValidateHeaderVersion(); uint? version = ValidateHeaderVersion();
@@ -194,6 +251,8 @@ namespace SabreTools.Library.FileTypes
byte[] hash; byte[] hash;
// Now parse the rest of the header according to the version // Now parse the rest of the header according to the version
try
{
switch (version) switch (version)
{ {
case 1: case 1:
@@ -216,6 +275,12 @@ namespace SabreTools.Library.FileTypes
// throw CHDERR_INVALID_FILE; // throw CHDERR_INVALID_FILE;
return null; return null;
} }
}
catch
{
// throw CHDERR_INVALID_FILE;
return null;
}
return hash; return hash;
} }

View File

@@ -1040,9 +1040,9 @@ namespace SabreTools.Library.Tools
public static BaseFile GetCHDInfo(string input) public static BaseFile GetCHDInfo(string input)
{ {
FileStream fs = TryOpenRead(input); FileStream fs = TryOpenRead(input);
BaseFile datItem = GetCHDInfo(fs); BaseFile chd = GetCHDInfo(fs);
fs.Dispose(); fs.Dispose();
return datItem; return chd;
} }
/// <summary> /// <summary>
@@ -1371,32 +1371,6 @@ namespace SabreTools.Library.Tools
} }
} }
/// <summary>
/// Get if file has a known CHD header
/// </summary>
/// <param name="input">Filename of possible CHD</param>
/// <returns>True if the file has a valid CHD header, false otherwise</returns>
public static bool HasCHDHeader(string input)
{
FileStream fs = TryOpenRead(input);
bool output = HasCHDHeader(fs);
fs.Dispose();
return output;
}
/// <summary>
/// Get if file is a valid CHD
/// </summary>
/// <param name="input">Filename of possible CHD</param>
/// <returns>True if the file is a valid CHD, false otherwise</returns>
public static bool IsValidCHD(string input)
{
BaseFile baseFile = GetCHDInfo(input);
return baseFile != null
&& (((CHDFile)baseFile).MD5 != null
|| ((CHDFile)baseFile).SHA1 != null);
}
/// <summary> /// <summary>
/// Retrieve a list of files from a directory recursively in proper order /// Retrieve a list of files from a directory recursively in proper order
/// </summary> /// </summary>
@@ -1925,7 +1899,7 @@ namespace SabreTools.Library.Tools
long offset = 0, bool keepReadOpen = false, bool chdsAsFiles = true) long offset = 0, bool keepReadOpen = false, bool chdsAsFiles = true)
{ {
// We first check to see if it's a CHD // We first check to see if it's a CHD
if (chdsAsFiles == false && HasCHDHeader(input)) if (chdsAsFiles == false && GetCHDInfo(input) != null)
{ {
// Seek to the starting position, if one is set // Seek to the starting position, if one is set
try try
@@ -1952,8 +1926,8 @@ namespace SabreTools.Library.Tools
Globals.Logger.Warning("Stream does not support seeking. Stream position not changed"); Globals.Logger.Warning("Stream does not support seeking. Stream position not changed");
} }
// Get the Disk from the information // Get the BaseFile from the information
BaseFile disk = GetCHDInfo(input); BaseFile chd = GetCHDInfo(input);
// Seek to the beginning of the stream if possible // Seek to the beginning of the stream if possible
try try
@@ -1974,7 +1948,7 @@ namespace SabreTools.Library.Tools
input.Dispose(); input.Dispose();
} }
return disk; return chd;
} }
BaseFile rom = new BaseFile() BaseFile rom = new BaseFile()
@@ -2130,54 +2104,8 @@ namespace SabreTools.Library.Tools
/// </remarks> /// </remarks>
public static BaseFile GetCHDInfo(Stream input) public static BaseFile GetCHDInfo(Stream input)
{ {
// Get a CHD object to store the data
CHDFile chd = new CHDFile(input); CHDFile chd = new CHDFile(input);
return (chd.Version != null && (chd.MD5 != null || chd.SHA1 != null) ? chd : null);
// Ensure that the header is valid
byte[] hash = chd.GetHashFromHeader();
// Set the proper hash of the Disk to return
if (hash.Length == Constants.MD5Length)
{
chd.MD5 = hash;
return chd;
}
else if (hash.Length == Constants.SHA1Length)
{
chd.SHA1 = hash;
return chd;
}
return null;
}
/// <summary>
/// Get if stream has a known CHD header
/// </summary>
/// <param name="input">Stream of possible CHD</param>
/// <returns>True if the stream has a valid CHD header, false otherwise</returns>
public static bool HasCHDHeader(Stream input)
{
// Get a CHD object to store the data
CHDFile chd = new CHDFile(input);
// Now try to get the header version
uint? version = chd.ValidateHeaderVersion();
return version != null;
}
/// <summary>
/// Get if stream is a valid CHD
/// </summary>
/// <param name="input">Stream of possible CHD</param>
/// <returns>True if the stream is a valid CHD, false otherwise</returns>
public static bool IsValidCHD(Stream input)
{
BaseFile baseFile = GetCHDInfo(input);
return baseFile != null
&& (((CHDFile)baseFile).MD5 != null
|| ((CHDFile)baseFile).SHA1 != null);
} }
#endregion #endregion