mirror of
https://github.com/claunia/SabreTools.git
synced 2025-12-16 19:14:27 +00:00
[Skipper] Rearrange Skipper methods without changing logic
This commit is contained in:
@@ -4,6 +4,8 @@
|
|||||||
|
|
||||||
This project started as a desktop port of some core features of Wizard of DATz Redux, but it has since grown into a fully-featured DAT management tool. Below is a brief description of the features available in the suite. For more information about each feature, see the help text in each of the programs. For more information about the parent project, see <a href="https://github.com/mnadareski/wizzardRedux">here</a>.
|
This project started as a desktop port of some core features of Wizard of DATz Redux, but it has since grown into a fully-featured DAT management tool. Below is a brief description of the features available in the suite. For more information about each feature, see the help text in each of the programs. For more information about the parent project, see <a href="https://github.com/mnadareski/wizzardRedux">here</a>.
|
||||||
|
|
||||||
|
<!-- "tbh... i have no real idea what sabretools is xD. my best guess some prehistoric sort of swiss army knife" - Executer -->
|
||||||
|
|
||||||
<h3>Features</h3>
|
<h3>Features</h3>
|
||||||
|
|
||||||
For the most complete set of information, see the <a href="https://raw.githubusercontent.com/mnadareski/wizzardDesktop/master/SabreTools.Helper/README.1ST">README.1ST</a> file. Currently, the SabreTools suite consists of the following programs:
|
For the most complete set of information, see the <a href="https://raw.githubusercontent.com/mnadareski/wizzardDesktop/master/SabreTools.Helper/README.1ST">README.1ST</a> file. Currently, the SabreTools suite consists of the following programs:
|
||||||
|
|||||||
@@ -71,7 +71,7 @@ namespace SabreTools
|
|||||||
{
|
{
|
||||||
datdata.PopulateDatFromDir(input, false /* noMD5 */, false /* noSHA1 */, true /* bare */, false /* archivesAsFiles */,
|
datdata.PopulateDatFromDir(input, false /* noMD5 */, false /* noSHA1 */, true /* bare */, false /* archivesAsFiles */,
|
||||||
true /* enableGzip */, false /* addBlanks */, false /* addDate */, "__temp__" /* tempDir */, false /* copyFiles */,
|
true /* enableGzip */, false /* addBlanks */, false /* addDate */, "__temp__" /* tempDir */, false /* copyFiles */,
|
||||||
false /* removeHeader */, 4 /* maxDegreeOfParallelism */, _logger);
|
null /* headerToCheckAgainst */, 4 /* maxDegreeOfParallelism */, _logger);
|
||||||
datdata.WriteToFile("", logger);
|
datdata.WriteToFile("", logger);
|
||||||
}
|
}
|
||||||
logger.Close();
|
logger.Close();
|
||||||
|
|||||||
@@ -1,46 +0,0 @@
|
|||||||
using System.Collections.Generic;
|
|
||||||
|
|
||||||
namespace SabreTools.Helper
|
|
||||||
{
|
|
||||||
#region Skipper structs
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Intermediate struct for holding header skipper information
|
|
||||||
/// </summary>
|
|
||||||
public struct Skipper
|
|
||||||
{
|
|
||||||
public string Name;
|
|
||||||
public string Author;
|
|
||||||
public string Version;
|
|
||||||
public List<SkipperRule> Rules;
|
|
||||||
public string SourceFile;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Intermediate struct for holding header skipper rule information
|
|
||||||
/// </summary>
|
|
||||||
public struct SkipperRule
|
|
||||||
{
|
|
||||||
public long? StartOffset; // null is EOF
|
|
||||||
public long? EndOffset; // null if EOF
|
|
||||||
public HeaderSkipOperation Operation;
|
|
||||||
public List<SkipperTest> Tests;
|
|
||||||
public string SourceFile;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Intermediate struct for holding header test information
|
|
||||||
/// </summary>
|
|
||||||
public struct SkipperTest
|
|
||||||
{
|
|
||||||
public HeaderSkipTest Type;
|
|
||||||
public long? Offset; // null is EOF
|
|
||||||
public byte[] Value;
|
|
||||||
public bool Result;
|
|
||||||
public byte[] Mask;
|
|
||||||
public long? Size; // null is PO2, "power of 2" filesize
|
|
||||||
public HeaderSkipTestFileOperator Operator;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
}
|
|
||||||
@@ -4564,11 +4564,12 @@ namespace SabreTools.Helper
|
|||||||
/// <param name="addDate">True if dates should be archived for all files, false otherwise</param>
|
/// <param name="addDate">True if dates should be archived for all files, false otherwise</param>
|
||||||
/// <param name="tempDir">Name of the directory to create a temp folder in (blank is current directory)</param>
|
/// <param name="tempDir">Name of the directory to create a temp folder in (blank is current directory)</param>
|
||||||
/// <param name="copyFiles">True if files should be copied to the temp directory before hashing, false otherwise</param>
|
/// <param name="copyFiles">True if files should be copied to the temp directory before hashing, false otherwise</param>
|
||||||
/// <param name="tryRemoveHeader">True if headers should be removed from files if possible, false otherwise</param>
|
/// <param name="headerToCheckAgainst">Populated string representing the name of the skipper to use, a blank string to use the first available checker, null otherwise</param>
|
||||||
/// <param name="maxDegreeOfParallelism">Integer representing the maximum amount of parallelization to be used</param>
|
/// <param name="maxDegreeOfParallelism">Integer representing the maximum amount of parallelization to be used</param>
|
||||||
/// <param name="logger">Logger object for console and file output</param>
|
/// <param name="logger">Logger object for console and file output</param>
|
||||||
public bool PopulateDatFromDir(string basePath, bool noMD5, bool noSHA1, bool bare, bool archivesAsFiles,
|
public bool PopulateDatFromDir(string basePath, bool noMD5, bool noSHA1, bool bare, bool archivesAsFiles,
|
||||||
bool enableGzip, bool addBlanks, bool addDate, string tempDir, bool copyFiles, bool tryRemoveHeader, int maxDegreeOfParallelism, Logger logger)
|
bool enableGzip, bool addBlanks, bool addDate, string tempDir, bool copyFiles, string headerToCheckAgainst,
|
||||||
|
int maxDegreeOfParallelism, Logger logger)
|
||||||
{
|
{
|
||||||
// If the description is defined but not the name, set the name from the description
|
// If the description is defined but not the name, set the name from the description
|
||||||
if (String.IsNullOrEmpty(Name) && !String.IsNullOrEmpty(Description))
|
if (String.IsNullOrEmpty(Name) && !String.IsNullOrEmpty(Description))
|
||||||
@@ -4599,7 +4600,7 @@ namespace SabreTools.Helper
|
|||||||
item =>
|
item =>
|
||||||
{
|
{
|
||||||
DFDProcessPossibleArchive(item, basePath, noMD5, noSHA1, bare, archivesAsFiles, enableGzip, addBlanks, addDate,
|
DFDProcessPossibleArchive(item, basePath, noMD5, noSHA1, bare, archivesAsFiles, enableGzip, addBlanks, addDate,
|
||||||
tempDir, copyFiles, tryRemoveHeader, maxDegreeOfParallelism, logger);
|
tempDir, copyFiles, headerToCheckAgainst, maxDegreeOfParallelism, logger);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Now find all folders that are empty, if we are supposed to
|
// Now find all folders that are empty, if we are supposed to
|
||||||
@@ -4688,11 +4689,12 @@ namespace SabreTools.Helper
|
|||||||
/// <param name="addDate">True if dates should be archived for all files, false otherwise</param>
|
/// <param name="addDate">True if dates should be archived for all files, false otherwise</param>
|
||||||
/// <param name="tempDir">Name of the directory to create a temp folder in (blank is current directory)</param>
|
/// <param name="tempDir">Name of the directory to create a temp folder in (blank is current directory)</param>
|
||||||
/// <param name="copyFiles">True if files should be copied to the temp directory before hashing, false otherwise</param>
|
/// <param name="copyFiles">True if files should be copied to the temp directory before hashing, false otherwise</param>
|
||||||
/// <param name="tryRemoveHeader">True if headers should be removed from files if possible, false otherwise</param>
|
/// <param name="headerToCheckAgainst">Populated string representing the name of the skipper to use, a blank string to use the first available checker, null otherwise</param>
|
||||||
/// <param name="maxDegreeOfParallelism">Integer representing the maximum amount of parallelization to be used</param>
|
/// <param name="maxDegreeOfParallelism">Integer representing the maximum amount of parallelization to be used</param>
|
||||||
/// <param name="logger">Logger object for console and file output</param>
|
/// <param name="logger">Logger object for console and file output</param>
|
||||||
private void DFDProcessPossibleArchive(string item, string basePath, bool noMD5, bool noSHA1, bool bare, bool archivesAsFiles,
|
private void DFDProcessPossibleArchive(string item, string basePath, bool noMD5, bool noSHA1, bool bare, bool archivesAsFiles,
|
||||||
bool enableGzip, bool addBlanks, bool addDate, string tempDir, bool copyFiles, bool tryRemoveHeader, int maxDegreeOfParallelism, Logger logger)
|
bool enableGzip, bool addBlanks, bool addDate, string tempDir, bool copyFiles, string headerToCheckAgainst,
|
||||||
|
int maxDegreeOfParallelism, Logger logger)
|
||||||
{
|
{
|
||||||
// Define the temporary directory
|
// Define the temporary directory
|
||||||
string tempSubDir = Path.GetFullPath(Path.Combine(tempDir, Path.GetRandomFileName())) + Path.DirectorySeparatorChar;
|
string tempSubDir = Path.GetFullPath(Path.Combine(tempDir, Path.GetRandomFileName())) + Path.DirectorySeparatorChar;
|
||||||
@@ -4762,7 +4764,7 @@ namespace SabreTools.Helper
|
|||||||
// Otherwise, just get the info on the file itself
|
// Otherwise, just get the info on the file itself
|
||||||
else if (File.Exists(newItem))
|
else if (File.Exists(newItem))
|
||||||
{
|
{
|
||||||
DFDProcessFile(newItem, "", newBasePath, noMD5, noSHA1, addDate, tryRemoveHeader, logger);
|
DFDProcessFile(newItem, "", newBasePath, noMD5, noSHA1, addDate, headerToCheckAgainst, logger);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Otherwise, attempt to extract the files to the temporary directory
|
// Otherwise, attempt to extract the files to the temporary directory
|
||||||
@@ -4794,14 +4796,14 @@ namespace SabreTools.Helper
|
|||||||
noMD5,
|
noMD5,
|
||||||
noSHA1,
|
noSHA1,
|
||||||
addDate,
|
addDate,
|
||||||
tryRemoveHeader,
|
headerToCheckAgainst,
|
||||||
logger);
|
logger);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
// Otherwise, just get the info on the file itself
|
// Otherwise, just get the info on the file itself
|
||||||
else if (File.Exists(newItem))
|
else if (File.Exists(newItem))
|
||||||
{
|
{
|
||||||
DFDProcessFile(newItem, "", newBasePath, noMD5, noSHA1, addDate, tryRemoveHeader, logger);
|
DFDProcessFile(newItem, "", newBasePath, noMD5, noSHA1, addDate, headerToCheckAgainst, logger);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -4831,12 +4833,12 @@ namespace SabreTools.Helper
|
|||||||
/// <param name="noMD5">True if MD5 hashes should be skipped over, false otherwise</param>
|
/// <param name="noMD5">True if MD5 hashes should be skipped over, false otherwise</param>
|
||||||
/// <param name="noSHA1">True if SHA-1 hashes should be skipped over, false otherwise</param>
|
/// <param name="noSHA1">True if SHA-1 hashes should be skipped over, false otherwise</param>
|
||||||
/// <param name="addDate">True if dates should be archived for all files, false otherwise</param>
|
/// <param name="addDate">True if dates should be archived for all files, false otherwise</param>
|
||||||
/// <param name="tryRemoveHeader">True if headers should be removed from files if possible, false otherwise</param>
|
/// <param name="headerToCheckAgainst">Populated string representing the name of the skipper to use, a blank string to use the first available checker, null otherwise</param>
|
||||||
/// <param name="logger">Logger object for console and file output</param>
|
/// <param name="logger">Logger object for console and file output</param>
|
||||||
private void DFDProcessFile(string item, string parent, string basePath, bool noMD5, bool noSHA1, bool addDate, bool tryRemoveHeader, Logger logger)
|
private void DFDProcessFile(string item, string parent, string basePath, bool noMD5, bool noSHA1, bool addDate, string headerToCheckAgainst, Logger logger)
|
||||||
{
|
{
|
||||||
logger.Verbose(Path.GetFileName(item) + " treated like a file");
|
logger.Verbose(Path.GetFileName(item) + " treated like a file");
|
||||||
Rom rom = FileTools.GetFileInfo(item, logger, noMD5: noMD5, noSHA1: noSHA1, date: addDate, tryRemoveHeader: tryRemoveHeader);
|
Rom rom = FileTools.GetFileInfo(item, logger, noMD5: noMD5, noSHA1: noSHA1, date: addDate, header: headerToCheckAgainst);
|
||||||
|
|
||||||
DFDProcessFileHelper(item, rom, basePath, parent, logger);
|
DFDProcessFileHelper(item, rom, basePath, parent, logger);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -139,7 +139,7 @@ namespace SabreTools.Helper
|
|||||||
{
|
{
|
||||||
_datdata.PopulateDatFromDir(input, false /* noMD5 */, false /* noSHA1 */, true /* bare */, false /* archivesAsFiles */,
|
_datdata.PopulateDatFromDir(input, false /* noMD5 */, false /* noSHA1 */, true /* bare */, false /* archivesAsFiles */,
|
||||||
true /* enableGzip */, false /* addBlanks */, false /* addDate */, "" /* tempDir */, false /* copyFiles */,
|
true /* enableGzip */, false /* addBlanks */, false /* addDate */, "" /* tempDir */, false /* copyFiles */,
|
||||||
false /* removeHeader */, 4 /* maxDegreeOfParallelism */, _logger);
|
null /* headerToCheckAgainst */, 4 /* maxDegreeOfParallelism */, _logger);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Setup the fixdat
|
// Setup the fixdat
|
||||||
@@ -486,7 +486,7 @@ namespace SabreTools.Helper
|
|||||||
|
|
||||||
// Now attempt to see if the file has a header
|
// Now attempt to see if the file has a header
|
||||||
FileStream input = File.OpenRead(file);
|
FileStream input = File.OpenRead(file);
|
||||||
SkipperRule rule = Skippers.GetMatchingRule(input, "", _logger);
|
SkipperRule rule = Skipper.GetMatchingRule(input, "", _logger);
|
||||||
|
|
||||||
// If there's a match, get the new information from the stream
|
// If there's a match, get the new information from the stream
|
||||||
if (rule.Tests != null && rule.Tests.Count != 0)
|
if (rule.Tests != null && rule.Tests.Count != 0)
|
||||||
@@ -495,7 +495,7 @@ namespace SabreTools.Helper
|
|||||||
MemoryStream output = new MemoryStream();
|
MemoryStream output = new MemoryStream();
|
||||||
|
|
||||||
// Transform the stream and get the information from it
|
// Transform the stream and get the information from it
|
||||||
Skippers.TransformStream(input, output, rule, _logger, false, true);
|
rule.TransformStream(input, output, _logger, false, true);
|
||||||
Rom romNH = FileTools.GetStreamInfo(output, output.Length);
|
Rom romNH = FileTools.GetStreamInfo(output, output.Length);
|
||||||
romNH.Name = "HEAD::" + rom.Name;
|
romNH.Name = "HEAD::" + rom.Name;
|
||||||
romNH.MachineName = rom.MachineName;
|
romNH.MachineName = rom.MachineName;
|
||||||
@@ -610,14 +610,14 @@ namespace SabreTools.Helper
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Now get the transformed file if it exists
|
// Now get the transformed file if it exists
|
||||||
SkipperRule rule = Skippers.GetMatchingRule(input, "", _logger);
|
SkipperRule rule = Skipper.GetMatchingRule(input, "", _logger);
|
||||||
|
|
||||||
// If we have have a non-empty rule, apply it
|
// If we have have a non-empty rule, apply it
|
||||||
if (rule.Tests != null && rule.Tests.Count != 0)
|
if (rule.Tests != null && rule.Tests.Count != 0)
|
||||||
{
|
{
|
||||||
// Otherwise, apply the rule to the file
|
// Otherwise, apply the rule to the file
|
||||||
string newinput = input + ".new";
|
string newinput = input + ".new";
|
||||||
Skippers.TransformFile(input, newinput, rule, _logger);
|
rule.TransformFile(input, newinput, _logger);
|
||||||
Rom drom = FileTools.GetFileInfo(newinput, _logger);
|
Rom drom = FileTools.GetFileInfo(newinput, _logger);
|
||||||
|
|
||||||
// If we have a blank RomData, it's an error
|
// If we have a blank RomData, it's an error
|
||||||
|
|||||||
@@ -6,8 +6,16 @@ using System.Xml;
|
|||||||
|
|
||||||
namespace SabreTools.Helper
|
namespace SabreTools.Helper
|
||||||
{
|
{
|
||||||
public class Skippers
|
public class Skipper
|
||||||
{
|
{
|
||||||
|
#region Fields
|
||||||
|
|
||||||
|
public string Name;
|
||||||
|
public string Author;
|
||||||
|
public string Version;
|
||||||
|
public List<SkipperRule> Rules;
|
||||||
|
public string SourceFile;
|
||||||
|
|
||||||
// Local paths
|
// Local paths
|
||||||
public const string LocalPath = "Skippers";
|
public const string LocalPath = "Skippers";
|
||||||
|
|
||||||
@@ -25,50 +33,30 @@ namespace SabreTools.Helper
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
#endregion
|
||||||
/// Populate the entire list of header Skippers
|
|
||||||
/// </summary>
|
|
||||||
/// <remarks>
|
|
||||||
/// http://mamedev.emulab.it/clrmamepro/docs/xmlheaders.txt
|
|
||||||
/// http://www.emulab.it/forum/index.php?topic=127.0
|
|
||||||
/// </remarks>
|
|
||||||
private static void PopulateSkippers()
|
|
||||||
{
|
|
||||||
if (_list == null)
|
|
||||||
{
|
|
||||||
_list = new List<Skipper>();
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (string skipperFile in Directory.EnumerateFiles(LocalPath, "*", SearchOption.AllDirectories))
|
#region Constructors
|
||||||
{
|
|
||||||
_list.Add(PopulateSkippersHelper(Path.GetFullPath(skipperFile)));
|
public Skipper()
|
||||||
}
|
{
|
||||||
|
Name = "";
|
||||||
|
Author = "";
|
||||||
|
Version = "";
|
||||||
|
Rules = new List<SkipperRule>();
|
||||||
|
SourceFile = "";
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
public Skipper(string filename)
|
||||||
/// Populate an individual Skipper from file
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="filename">Name of the file to be read from</param>
|
|
||||||
/// <returns>The Skipper object associated with the file</returns>
|
|
||||||
private static Skipper PopulateSkippersHelper(string filename)
|
|
||||||
{
|
{
|
||||||
Skipper skipper = new Skipper
|
Rules = new List<SkipperRule>();
|
||||||
{
|
SourceFile = Path.GetFileNameWithoutExtension(filename);
|
||||||
Rules = new List<SkipperRule>(),
|
|
||||||
SourceFile = Path.GetFileName(filename),
|
|
||||||
};
|
|
||||||
|
|
||||||
if (!File.Exists(filename))
|
|
||||||
{
|
|
||||||
return skipper;
|
|
||||||
}
|
|
||||||
|
|
||||||
Logger logger = new Logger(false, "");
|
Logger logger = new Logger(false, "");
|
||||||
XmlReader xtr = FileTools.GetXmlTextReader(filename, logger);
|
XmlReader xtr = FileTools.GetXmlTextReader(filename, logger);
|
||||||
|
|
||||||
if (xtr == null)
|
if (xtr == null)
|
||||||
{
|
{
|
||||||
return skipper;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool valid = false;
|
bool valid = false;
|
||||||
@@ -87,13 +75,13 @@ namespace SabreTools.Helper
|
|||||||
xtr.Read();
|
xtr.Read();
|
||||||
break;
|
break;
|
||||||
case "name":
|
case "name":
|
||||||
skipper.Name = xtr.ReadElementContentAsString();
|
Name = xtr.ReadElementContentAsString();
|
||||||
break;
|
break;
|
||||||
case "author":
|
case "author":
|
||||||
skipper.Author = xtr.ReadElementContentAsString();
|
Author = xtr.ReadElementContentAsString();
|
||||||
break;
|
break;
|
||||||
case "version":
|
case "version":
|
||||||
skipper.Version = xtr.ReadElementContentAsString();
|
Version = xtr.ReadElementContentAsString();
|
||||||
break;
|
break;
|
||||||
case "rule":
|
case "rule":
|
||||||
// Get the information from the rule first
|
// Get the information from the rule first
|
||||||
@@ -103,7 +91,7 @@ namespace SabreTools.Helper
|
|||||||
EndOffset = 0,
|
EndOffset = 0,
|
||||||
Operation = HeaderSkipOperation.None,
|
Operation = HeaderSkipOperation.None,
|
||||||
Tests = new List<SkipperTest>(),
|
Tests = new List<SkipperTest>(),
|
||||||
SourceFile = Path.GetFileName(filename),
|
SourceFile = Path.GetFileNameWithoutExtension(filename),
|
||||||
};
|
};
|
||||||
|
|
||||||
if (xtr.GetAttribute("start_offset") != null)
|
if (xtr.GetAttribute("start_offset") != null)
|
||||||
@@ -279,7 +267,7 @@ namespace SabreTools.Helper
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Add the created rule to the skipper
|
// Add the created rule to the skipper
|
||||||
skipper.Rules.Add(rule);
|
Rules.Add(rule);
|
||||||
xtr.Skip();
|
xtr.Skip();
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@@ -288,14 +276,46 @@ namespace SabreTools.Helper
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return (valid ? skipper : new Skipper());
|
// If we somehow have an invalid file, zero out the fields
|
||||||
|
if (!valid)
|
||||||
|
{
|
||||||
|
Name = null;
|
||||||
|
Author = null;
|
||||||
|
Version = null;
|
||||||
|
Rules = null;
|
||||||
|
SourceFile = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Static Methods
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Populate the entire list of header Skippers
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// http://mamedev.emulab.it/clrmamepro/docs/xmlheaders.txt
|
||||||
|
/// http://www.emulab.it/forum/index.php?topic=127.0
|
||||||
|
/// </remarks>
|
||||||
|
private static void PopulateSkippers()
|
||||||
|
{
|
||||||
|
if (_list == null)
|
||||||
|
{
|
||||||
|
_list = new List<Skipper>();
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (string skipperFile in Directory.EnumerateFiles(LocalPath, "*", SearchOption.AllDirectories))
|
||||||
|
{
|
||||||
|
_list.Add(new Skipper(Path.GetFullPath(skipperFile)));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Get the SkipperRule associated with a given file
|
/// Get the SkipperRule associated with a given file
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="input">Name of the file to be checked</param>
|
/// <param name="input">Name of the file to be checked</param>
|
||||||
/// <param name="skipperName">Name of the skipper to be used</param>
|
/// <param name="skipperName">Name of the skipper to be used, blank to find a matching skipper</param>
|
||||||
/// <param name="logger">Logger object for file and console output</param>
|
/// <param name="logger">Logger object for file and console output</param>
|
||||||
/// <returns>The SkipperRule that matched the file</returns>
|
/// <returns>The SkipperRule that matched the file</returns>
|
||||||
public static SkipperRule GetMatchingRule(string input, string skipperName, Logger logger)
|
public static SkipperRule GetMatchingRule(string input, string skipperName, Logger logger)
|
||||||
@@ -314,7 +334,7 @@ namespace SabreTools.Helper
|
|||||||
/// Get the SkipperRule associated with a given stream
|
/// Get the SkipperRule associated with a given stream
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="input">Name of the file to be checked</param>
|
/// <param name="input">Name of the file to be checked</param>
|
||||||
/// <param name="skipperName">Name of the skipper to be used</param>
|
/// <param name="skipperName">Name of the skipper to be used, blank to find a matching skipper</param>
|
||||||
/// <param name="logger">Logger object for file and console output</param>
|
/// <param name="logger">Logger object for file and console output</param>
|
||||||
/// <param name="keepOpen">True if the underlying stream should be kept open, false otherwise</param>
|
/// <param name="keepOpen">True if the underlying stream should be kept open, false otherwise</param>
|
||||||
/// <returns>The SkipperRule that matched the file</returns>
|
/// <returns>The SkipperRule that matched the file</returns>
|
||||||
@@ -329,7 +349,10 @@ namespace SabreTools.Helper
|
|||||||
|
|
||||||
foreach (Skipper skipper in tempList)
|
foreach (Skipper skipper in tempList)
|
||||||
{
|
{
|
||||||
if (String.IsNullOrEmpty(skipperName) || (!String.IsNullOrEmpty(skipper.Name) && skipperName.ToLowerInvariant() == skipper.Name.ToLowerInvariant()))
|
// If we're searching for the skipper OR we have a match to an inputted one
|
||||||
|
if (String.IsNullOrEmpty(skipperName)
|
||||||
|
|| (!String.IsNullOrEmpty(skipper.Name) && skipperName.ToLowerInvariant() == skipper.Name.ToLowerInvariant())
|
||||||
|
|| (!String.IsNullOrEmpty(skipper.Name) && skipperName.ToLowerInvariant() == skipper.SourceFile.ToLowerInvariant()))
|
||||||
{
|
{
|
||||||
// Loop through the rules until one is found that works
|
// Loop through the rules until one is found that works
|
||||||
BinaryReader br = new BinaryReader(input);
|
BinaryReader br = new BinaryReader(input);
|
||||||
@@ -492,187 +515,6 @@ namespace SabreTools.Helper
|
|||||||
return skipperRule;
|
return skipperRule;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
#endregion
|
||||||
/// Transform an input file using the given rule
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="input">Input file name</param>
|
|
||||||
/// <param name="output">Output file name</param>
|
|
||||||
/// <param name="rule">SkipperRule to apply to the file</param>
|
|
||||||
/// <param name="logger">Logger object for file and console output</param>
|
|
||||||
/// <returns>True if the file was transformed properly, false otherwise</returns>
|
|
||||||
public static bool TransformFile(string input, string output, SkipperRule rule, Logger logger)
|
|
||||||
{
|
|
||||||
bool success = true;
|
|
||||||
|
|
||||||
// If the input file doesn't exist, fail
|
|
||||||
if (!File.Exists(input))
|
|
||||||
{
|
|
||||||
logger.Error("I'm sorry but '" + input + "' doesn't exist!");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create the output directory if it doesn't already
|
|
||||||
if (!Directory.Exists(Path.GetDirectoryName(output)))
|
|
||||||
{
|
|
||||||
Directory.CreateDirectory(Path.GetDirectoryName(output));
|
|
||||||
}
|
|
||||||
|
|
||||||
logger.User("Attempting to apply rule to '" + input + "'");
|
|
||||||
success = TransformStream(File.Open(input, FileMode.Open, FileAccess.Read, FileShare.ReadWrite), File.OpenWrite(output), rule, logger);
|
|
||||||
|
|
||||||
// If the output file has size 0, delete it
|
|
||||||
if (new FileInfo(output).Length == 0)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
File.Delete(output);
|
|
||||||
success = false;
|
|
||||||
}
|
|
||||||
catch
|
|
||||||
{
|
|
||||||
// Don't log this file deletion error
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return success;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Transform an input stream using the given rule
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="input">Input stream</param>
|
|
||||||
/// <param name="output">Output stream</param>
|
|
||||||
/// <param name="rule">SkipperRule to apply to the stream</param>
|
|
||||||
/// <param name="logger">Logger object for file and console output</param>
|
|
||||||
/// <param name="keepReadOpen">True if the underlying read stream should be kept open, false otherwise</param>
|
|
||||||
/// <param name="keepWriteOpen">True if the underlying write stream should be kept open, false otherwise</param>
|
|
||||||
/// <returns>True if the file was transformed properly, false otherwise</returns>
|
|
||||||
public static bool TransformStream(Stream input, Stream output, SkipperRule rule, Logger logger, bool keepReadOpen = false, bool keepWriteOpen = false)
|
|
||||||
{
|
|
||||||
bool success = true;
|
|
||||||
|
|
||||||
// If the sizes are wrong for the values, fail
|
|
||||||
long extsize = input.Length;
|
|
||||||
if ((rule.Operation > HeaderSkipOperation.Bitswap && (extsize % 2) != 0)
|
|
||||||
|| (rule.Operation > HeaderSkipOperation.Byteswap && (extsize % 4) != 0)
|
|
||||||
|| (rule.Operation > HeaderSkipOperation.Bitswap && (rule.StartOffset == null || rule.StartOffset % 2 == 0)))
|
|
||||||
{
|
|
||||||
logger.Error("The stream did not have the correct size to be transformed!");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Now read the proper part of the file and apply the rule
|
|
||||||
BinaryWriter bw = null;
|
|
||||||
BinaryReader br = null;
|
|
||||||
try
|
|
||||||
{
|
|
||||||
logger.User("Applying found rule to input stream");
|
|
||||||
bw = new BinaryWriter(output);
|
|
||||||
br = new BinaryReader(input);
|
|
||||||
|
|
||||||
// Seek to the beginning offset
|
|
||||||
if (rule.StartOffset == null)
|
|
||||||
{
|
|
||||||
success = false;
|
|
||||||
}
|
|
||||||
else if (Math.Abs((long)rule.StartOffset) > input.Length)
|
|
||||||
{
|
|
||||||
success = false;
|
|
||||||
}
|
|
||||||
else if (rule.StartOffset > 0)
|
|
||||||
{
|
|
||||||
input.Seek((long)rule.StartOffset, SeekOrigin.Begin);
|
|
||||||
}
|
|
||||||
else if (rule.StartOffset < 0)
|
|
||||||
{
|
|
||||||
input.Seek((long)rule.StartOffset, SeekOrigin.End);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Then read and apply the operation as you go
|
|
||||||
if (success)
|
|
||||||
{
|
|
||||||
byte[] buffer = new byte[4];
|
|
||||||
int pos = 0;
|
|
||||||
while (input.Position < (rule.EndOffset != null ? rule.EndOffset : input.Length)
|
|
||||||
&& input.Position < input.Length)
|
|
||||||
{
|
|
||||||
byte b = br.ReadByte();
|
|
||||||
switch (rule.Operation)
|
|
||||||
{
|
|
||||||
case HeaderSkipOperation.Bitswap:
|
|
||||||
// http://stackoverflow.com/questions/3587826/is-there-a-built-in-function-to-reverse-bit-order
|
|
||||||
uint r = b;
|
|
||||||
int s = 7;
|
|
||||||
for (b >>= 1; b != 0; b >>= 1)
|
|
||||||
{
|
|
||||||
r <<= 1;
|
|
||||||
r |= (byte)(b & 1);
|
|
||||||
s--;
|
|
||||||
}
|
|
||||||
r <<= s;
|
|
||||||
buffer[pos] = (byte)r;
|
|
||||||
break;
|
|
||||||
case HeaderSkipOperation.Byteswap:
|
|
||||||
if (pos % 2 == 1)
|
|
||||||
{
|
|
||||||
buffer[pos - 1] = b;
|
|
||||||
}
|
|
||||||
if (pos % 2 == 0)
|
|
||||||
{
|
|
||||||
buffer[pos + 1] = b;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case HeaderSkipOperation.Wordswap:
|
|
||||||
buffer[3 - pos] = b;
|
|
||||||
break;
|
|
||||||
case HeaderSkipOperation.WordByteswap:
|
|
||||||
buffer[(pos + 2) % 4] = b;
|
|
||||||
break;
|
|
||||||
case HeaderSkipOperation.None:
|
|
||||||
default:
|
|
||||||
buffer[pos] = b;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set the buffer position to default write to
|
|
||||||
pos = (pos + 1) % 4;
|
|
||||||
|
|
||||||
// If we filled a buffer, flush to the stream
|
|
||||||
if (pos == 0)
|
|
||||||
{
|
|
||||||
bw.Write(buffer);
|
|
||||||
bw.Flush();
|
|
||||||
buffer = new byte[4];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// If there's anything more in the buffer, write only the left bits
|
|
||||||
for (int i = 0; i < pos; i++)
|
|
||||||
{
|
|
||||||
bw.Write(buffer[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
logger.Error(ex.ToString());
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
finally
|
|
||||||
{
|
|
||||||
// If we're not keeping the read stream open, dispose of the binary reader
|
|
||||||
if (!keepReadOpen)
|
|
||||||
{
|
|
||||||
br?.Dispose();
|
|
||||||
}
|
|
||||||
|
|
||||||
// If we're not keeping the write stream open, dispose of the binary reader
|
|
||||||
if (!keepWriteOpen)
|
|
||||||
{
|
|
||||||
bw?.Dispose();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return success;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
211
SabreTools.Helper/Objects/Skippers/SkipperRule.cs
Normal file
211
SabreTools.Helper/Objects/Skippers/SkipperRule.cs
Normal file
@@ -0,0 +1,211 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
|
||||||
|
namespace SabreTools.Helper
|
||||||
|
{
|
||||||
|
public class SkipperRule
|
||||||
|
{
|
||||||
|
// Public variables
|
||||||
|
public long? StartOffset; // null is EOF
|
||||||
|
public long? EndOffset; // null if EOF
|
||||||
|
public HeaderSkipOperation Operation;
|
||||||
|
public List<SkipperTest> Tests;
|
||||||
|
public string SourceFile;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Transform an input file using the given rule
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="input">Input file name</param>
|
||||||
|
/// <param name="output">Output file name</param>
|
||||||
|
/// <param name="logger">Logger object for file and console output</param>
|
||||||
|
/// <returns>True if the file was transformed properly, false otherwise</returns>
|
||||||
|
public bool TransformFile(string input, string output, Logger logger)
|
||||||
|
{
|
||||||
|
bool success = true;
|
||||||
|
|
||||||
|
// If the input file doesn't exist, fail
|
||||||
|
if (!File.Exists(input))
|
||||||
|
{
|
||||||
|
logger.Error("I'm sorry but '" + input + "' doesn't exist!");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create the output directory if it doesn't already
|
||||||
|
if (!Directory.Exists(Path.GetDirectoryName(output)))
|
||||||
|
{
|
||||||
|
Directory.CreateDirectory(Path.GetDirectoryName(output));
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.User("Attempting to apply rule to '" + input + "'");
|
||||||
|
success = TransformStream(File.Open(input, FileMode.Open, FileAccess.Read, FileShare.ReadWrite), File.OpenWrite(output), logger);
|
||||||
|
|
||||||
|
// If the output file has size 0, delete it
|
||||||
|
if (new FileInfo(output).Length == 0)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
File.Delete(output);
|
||||||
|
success = false;
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
// Don't log this file deletion error
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Transform an input stream using the given rule
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="input">Input stream</param>
|
||||||
|
/// <param name="output">Output stream</param>
|
||||||
|
/// <param name="logger">Logger object for file and console output</param>
|
||||||
|
/// <param name="keepReadOpen">True if the underlying read stream should be kept open, false otherwise</param>
|
||||||
|
/// <param name="keepWriteOpen">True if the underlying write stream should be kept open, false otherwise</param>
|
||||||
|
/// <returns>True if the file was transformed properly, false otherwise</returns>
|
||||||
|
public bool TransformStream(Stream input, Stream output, Logger logger, bool keepReadOpen = false, bool keepWriteOpen = false)
|
||||||
|
{
|
||||||
|
bool success = true;
|
||||||
|
|
||||||
|
// If the sizes are wrong for the values, fail
|
||||||
|
long extsize = input.Length;
|
||||||
|
if ((Operation > HeaderSkipOperation.Bitswap && (extsize % 2) != 0)
|
||||||
|
|| (Operation > HeaderSkipOperation.Byteswap && (extsize % 4) != 0)
|
||||||
|
|| (Operation > HeaderSkipOperation.Bitswap && (StartOffset == null || StartOffset % 2 == 0)))
|
||||||
|
{
|
||||||
|
logger.Error("The stream did not have the correct size to be transformed!");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Now read the proper part of the file and apply the rule
|
||||||
|
BinaryWriter bw = null;
|
||||||
|
BinaryReader br = null;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
logger.User("Applying found rule to input stream");
|
||||||
|
bw = new BinaryWriter(output);
|
||||||
|
br = new BinaryReader(input);
|
||||||
|
|
||||||
|
// Seek to the beginning offset
|
||||||
|
if (StartOffset == null)
|
||||||
|
{
|
||||||
|
success = false;
|
||||||
|
}
|
||||||
|
else if (Math.Abs((long)StartOffset) > input.Length)
|
||||||
|
{
|
||||||
|
success = false;
|
||||||
|
}
|
||||||
|
else if (StartOffset > 0)
|
||||||
|
{
|
||||||
|
input.Seek((long)StartOffset, SeekOrigin.Begin);
|
||||||
|
}
|
||||||
|
else if (StartOffset < 0)
|
||||||
|
{
|
||||||
|
input.Seek((long)StartOffset, SeekOrigin.End);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Then read and apply the operation as you go
|
||||||
|
if (success)
|
||||||
|
{
|
||||||
|
byte[] buffer = new byte[4];
|
||||||
|
int pos = 0;
|
||||||
|
while (input.Position < (EndOffset != null ? EndOffset : input.Length)
|
||||||
|
&& input.Position < input.Length)
|
||||||
|
{
|
||||||
|
byte b = br.ReadByte();
|
||||||
|
switch (Operation)
|
||||||
|
{
|
||||||
|
case HeaderSkipOperation.Bitswap:
|
||||||
|
// http://stackoverflow.com/questions/3587826/is-there-a-built-in-function-to-reverse-bit-order
|
||||||
|
uint r = b;
|
||||||
|
int s = 7;
|
||||||
|
for (b >>= 1; b != 0; b >>= 1)
|
||||||
|
{
|
||||||
|
r <<= 1;
|
||||||
|
r |= (byte)(b & 1);
|
||||||
|
s--;
|
||||||
|
}
|
||||||
|
r <<= s;
|
||||||
|
buffer[pos] = (byte)r;
|
||||||
|
break;
|
||||||
|
case HeaderSkipOperation.Byteswap:
|
||||||
|
if (pos % 2 == 1)
|
||||||
|
{
|
||||||
|
buffer[pos - 1] = b;
|
||||||
|
}
|
||||||
|
if (pos % 2 == 0)
|
||||||
|
{
|
||||||
|
buffer[pos + 1] = b;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case HeaderSkipOperation.Wordswap:
|
||||||
|
buffer[3 - pos] = b;
|
||||||
|
break;
|
||||||
|
case HeaderSkipOperation.WordByteswap:
|
||||||
|
buffer[(pos + 2) % 4] = b;
|
||||||
|
break;
|
||||||
|
case HeaderSkipOperation.None:
|
||||||
|
default:
|
||||||
|
buffer[pos] = b;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set the buffer position to default write to
|
||||||
|
pos = (pos + 1) % 4;
|
||||||
|
|
||||||
|
// If we filled a buffer, flush to the stream
|
||||||
|
if (pos == 0)
|
||||||
|
{
|
||||||
|
bw.Write(buffer);
|
||||||
|
bw.Flush();
|
||||||
|
buffer = new byte[4];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// If there's anything more in the buffer, write only the left bits
|
||||||
|
for (int i = 0; i < pos; i++)
|
||||||
|
{
|
||||||
|
bw.Write(buffer[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
logger.Error(ex.ToString());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
// If we're not keeping the read stream open, dispose of the binary reader
|
||||||
|
if (!keepReadOpen)
|
||||||
|
{
|
||||||
|
br?.Dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
// If we're not keeping the write stream open, dispose of the binary reader
|
||||||
|
if (!keepWriteOpen)
|
||||||
|
{
|
||||||
|
bw?.Dispose();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Intermediate class for storing Skipper Test information
|
||||||
|
/// </summary>
|
||||||
|
public struct SkipperTest
|
||||||
|
{
|
||||||
|
public HeaderSkipTest Type;
|
||||||
|
public long? Offset; // null is EOF
|
||||||
|
public byte[] Value;
|
||||||
|
public bool Result;
|
||||||
|
public byte[] Mask;
|
||||||
|
public long? Size; // null is PO2, "power of 2" filesize
|
||||||
|
public HeaderSkipTestFileOperator Operator;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -113,6 +113,8 @@
|
|||||||
<Compile Include="Objects\SimpleSort.cs" />
|
<Compile Include="Objects\SimpleSort.cs" />
|
||||||
<Compile Include="Objects\Archive\ZipFileEntry.cs" />
|
<Compile Include="Objects\Archive\ZipFileEntry.cs" />
|
||||||
<Compile Include="Objects\Archive\ZipFile.cs" />
|
<Compile Include="Objects\Archive\ZipFile.cs" />
|
||||||
|
<Compile Include="Objects\Skippers\Skipper.cs" />
|
||||||
|
<Compile Include="Objects\Skippers\SkipperRule.cs" />
|
||||||
<Compile Include="Resources\Resources.de-DE.Designer.cs">
|
<Compile Include="Resources\Resources.de-DE.Designer.cs">
|
||||||
<AutoGen>True</AutoGen>
|
<AutoGen>True</AutoGen>
|
||||||
<DesignTime>True</DesignTime>
|
<DesignTime>True</DesignTime>
|
||||||
@@ -133,14 +135,12 @@
|
|||||||
<DesignTime>True</DesignTime>
|
<DesignTime>True</DesignTime>
|
||||||
<DependentUpon>Resources.fr-FR.resx</DependentUpon>
|
<DependentUpon>Resources.fr-FR.resx</DependentUpon>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="Skippers\Skippers.cs" />
|
|
||||||
<Compile Include="Tools\ArchiveTools.cs" />
|
<Compile Include="Tools\ArchiveTools.cs" />
|
||||||
<Compile Include="Tools\FileTools.cs" />
|
<Compile Include="Tools\FileTools.cs" />
|
||||||
<Compile Include="Tools\DatabaseTools.cs" />
|
<Compile Include="Tools\DatabaseTools.cs" />
|
||||||
<Compile Include="Data\Enums.cs" />
|
<Compile Include="Data\Enums.cs" />
|
||||||
<Compile Include="Objects\Logger.cs" />
|
<Compile Include="Objects\Logger.cs" />
|
||||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||||
<Compile Include="Data\Structs.cs" />
|
|
||||||
<Compile Include="Tools\Style.cs" />
|
<Compile Include="Tools\Style.cs" />
|
||||||
<Compile Include="Data\Build.cs" />
|
<Compile Include="Data\Build.cs" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|||||||
@@ -156,9 +156,9 @@ namespace SabreTools.Helper
|
|||||||
/// <param name="noSHA1">True if SHA-1 hashes should not be calcluated, false otherwise (default)</param>
|
/// <param name="noSHA1">True if SHA-1 hashes should not be calcluated, false otherwise (default)</param>
|
||||||
/// <param name="offset">Set a >0 number for getting hash for part of the file, 0 otherwise (default)</param>
|
/// <param name="offset">Set a >0 number for getting hash for part of the file, 0 otherwise (default)</param>
|
||||||
/// <param name="date">True if the file Date should be included, false otherwise (default)</param>
|
/// <param name="date">True if the file Date should be included, false otherwise (default)</param>
|
||||||
/// <param name="tryRemoveHeader">True if headers should be removed from files if possible, false otherwise (default)</param>
|
/// <param name="header">Populated string representing the name of the skipper to use, a blank string to use the first available checker, null otherwise</param>
|
||||||
/// <returns>Populated RomData object if success, empty one on error</returns>
|
/// <returns>Populated RomData object if success, empty one on error</returns>
|
||||||
public static Rom GetFileInfo(string input, Logger logger, bool noMD5 = false, bool noSHA1 = false, long offset = 0, bool date = false, bool tryRemoveHeader = false)
|
public static Rom GetFileInfo(string input, Logger logger, bool noMD5 = false, bool noSHA1 = false, long offset = 0, bool date = false, string header = null)
|
||||||
{
|
{
|
||||||
// Add safeguard if file doesn't exist
|
// Add safeguard if file doesn't exist
|
||||||
if (!File.Exists(input))
|
if (!File.Exists(input))
|
||||||
@@ -168,9 +168,9 @@ namespace SabreTools.Helper
|
|||||||
|
|
||||||
// Get the information from the file stream
|
// Get the information from the file stream
|
||||||
Rom rom = new Rom();
|
Rom rom = new Rom();
|
||||||
if (tryRemoveHeader)
|
if (header != null)
|
||||||
{
|
{
|
||||||
SkipperRule rule = Skippers.GetMatchingRule(input, "", logger);
|
SkipperRule rule = Skipper.GetMatchingRule(input, Path.GetFileNameWithoutExtension(header), logger);
|
||||||
|
|
||||||
// If there's a match, get the new information from the stream
|
// If there's a match, get the new information from the stream
|
||||||
if (rule.Tests != null && rule.Tests.Count != 0)
|
if (rule.Tests != null && rule.Tests.Count != 0)
|
||||||
@@ -180,7 +180,7 @@ namespace SabreTools.Helper
|
|||||||
FileStream inputStream = File.OpenRead(input);
|
FileStream inputStream = File.OpenRead(input);
|
||||||
|
|
||||||
// Transform the stream and get the information from it
|
// Transform the stream and get the information from it
|
||||||
Skippers.TransformStream(inputStream, outputStream, rule, logger, keepReadOpen: false, keepWriteOpen: true);
|
rule.TransformStream(inputStream, outputStream, logger, keepReadOpen: false, keepWriteOpen: true);
|
||||||
rom = GetStreamInfo(outputStream, outputStream.Length);
|
rom = GetStreamInfo(outputStream, outputStream.Length);
|
||||||
|
|
||||||
// Dispose of the streams
|
// Dispose of the streams
|
||||||
@@ -328,7 +328,7 @@ namespace SabreTools.Helper
|
|||||||
logger.User("\nGetting skipper information for '" + file + "'");
|
logger.User("\nGetting skipper information for '" + file + "'");
|
||||||
|
|
||||||
// Get the skipper rule that matches the file, if any
|
// Get the skipper rule that matches the file, if any
|
||||||
SkipperRule rule = Skippers.GetMatchingRule(file, "", logger);
|
SkipperRule rule = Skipper.GetMatchingRule(file, "", logger);
|
||||||
|
|
||||||
// If we have an empty rule, return false
|
// If we have an empty rule, return false
|
||||||
if (rule.Tests == null || rule.Tests.Count == 0 || rule.Operation != HeaderSkipOperation.None)
|
if (rule.Tests == null || rule.Tests.Count == 0 || rule.Operation != HeaderSkipOperation.None)
|
||||||
@@ -352,7 +352,7 @@ namespace SabreTools.Helper
|
|||||||
|
|
||||||
// Apply the rule to the file
|
// Apply the rule to the file
|
||||||
string newfile = (outDir == "" ? Path.GetFullPath(file) + ".new" : Path.Combine(outDir, Path.GetFileName(file)));
|
string newfile = (outDir == "" ? Path.GetFullPath(file) + ".new" : Path.Combine(outDir, Path.GetFileName(file)));
|
||||||
Skippers.TransformFile(file, newfile, rule, logger);
|
rule.TransformFile(file, newfile, logger);
|
||||||
|
|
||||||
// If the output file doesn't exist, return false
|
// If the output file doesn't exist, return false
|
||||||
if (!File.Exists(newfile))
|
if (!File.Exists(newfile))
|
||||||
|
|||||||
@@ -71,7 +71,7 @@ namespace SabreTools
|
|||||||
/// <param name="addFileDates">True if dates should be archived for all files, false otherwise</param>
|
/// <param name="addFileDates">True if dates should be archived for all files, false otherwise</param>
|
||||||
/// <param name="tempDir">Name of the directory to create a temp folder in (blank is current directory</param>
|
/// <param name="tempDir">Name of the directory to create a temp folder in (blank is current directory</param>
|
||||||
/// <param name="copyFiles">True if files should be copied to the temp directory before hashing, false otherwise</param>
|
/// <param name="copyFiles">True if files should be copied to the temp directory before hashing, false otherwise</param>
|
||||||
/// <param name="removeHeader">True if headers should be removed from files if possible, false otherwise</param>
|
/// <param name="headerToCheckAgainst">Populated string representing the name of the skipper to use, a blank string to use the first available checker, null otherwise</param>
|
||||||
/// <param name="maxDegreeOfParallelism">Integer representing the maximum amount of parallelization to be used</param>
|
/// <param name="maxDegreeOfParallelism">Integer representing the maximum amount of parallelization to be used</param>
|
||||||
private static void InitDatFromDir(List<string> inputs,
|
private static void InitDatFromDir(List<string> inputs,
|
||||||
string filename,
|
string filename,
|
||||||
@@ -93,7 +93,7 @@ namespace SabreTools
|
|||||||
bool addFileDates,
|
bool addFileDates,
|
||||||
string tempDir,
|
string tempDir,
|
||||||
bool copyFiles,
|
bool copyFiles,
|
||||||
bool removeHeader,
|
string headerToCheckAgainst,
|
||||||
int maxDegreeOfParallelism)
|
int maxDegreeOfParallelism)
|
||||||
{
|
{
|
||||||
ForcePacking fp = ForcePacking.None;
|
ForcePacking fp = ForcePacking.None;
|
||||||
@@ -139,7 +139,7 @@ namespace SabreTools
|
|||||||
|
|
||||||
string basePath = Path.GetFullPath(path);
|
string basePath = Path.GetFullPath(path);
|
||||||
bool success = datdata.PopulateDatFromDir(basePath, noMD5, noSHA1, removeDateFromAutomaticName, parseArchivesAsFiles, enableGzip,
|
bool success = datdata.PopulateDatFromDir(basePath, noMD5, noSHA1, removeDateFromAutomaticName, parseArchivesAsFiles, enableGzip,
|
||||||
addBlankFilesForEmptyFolder, addFileDates, tempDir, copyFiles, removeHeader, maxDegreeOfParallelism, _logger);
|
addBlankFilesForEmptyFolder, addFileDates, tempDir, copyFiles, headerToCheckAgainst, maxDegreeOfParallelism, _logger);
|
||||||
|
|
||||||
// If it was a success, write the DAT out
|
// If it was a success, write the DAT out
|
||||||
if (success)
|
if (success)
|
||||||
|
|||||||
@@ -75,7 +75,6 @@ namespace SabreTools
|
|||||||
rem = false,
|
rem = false,
|
||||||
remext = false,
|
remext = false,
|
||||||
removeDateFromAutomaticName = false,
|
removeDateFromAutomaticName = false,
|
||||||
removeHeader = false,
|
|
||||||
restore = false,
|
restore = false,
|
||||||
romba = false,
|
romba = false,
|
||||||
showBaddumpColumn = false,
|
showBaddumpColumn = false,
|
||||||
@@ -95,41 +94,41 @@ namespace SabreTools
|
|||||||
seq = -1;
|
seq = -1;
|
||||||
OutputFormat outputFormat = 0x0;
|
OutputFormat outputFormat = 0x0;
|
||||||
StatOutputFormat statOutputFormat = StatOutputFormat.None;
|
StatOutputFormat statOutputFormat = StatOutputFormat.None;
|
||||||
string addext = "",
|
string addext = null,
|
||||||
author = "",
|
author = null,
|
||||||
category = "",
|
category = null,
|
||||||
comment = "",
|
comment = null,
|
||||||
crc = "",
|
crc = null,
|
||||||
currentAllMerged = "",
|
currentAllMerged = null,
|
||||||
currentMissingMerged = "",
|
currentMissingMerged = null,
|
||||||
currentNewMerged = "",
|
currentNewMerged = null,
|
||||||
date = "",
|
date = null,
|
||||||
description = "",
|
description = null,
|
||||||
email = "",
|
email = null,
|
||||||
exta = "",
|
exta = null,
|
||||||
extb = "",
|
extb = null,
|
||||||
filename = "",
|
filename = null,
|
||||||
forcemerge = "",
|
forcemerge = null,
|
||||||
forcend = "",
|
forcend = null,
|
||||||
forcepack = "",
|
forcepack = null,
|
||||||
gamename = "",
|
gamename = null,
|
||||||
header = "",
|
header = null,
|
||||||
homepage = "",
|
homepage = null,
|
||||||
name = "",
|
name = null,
|
||||||
md5 = "",
|
md5 = null,
|
||||||
outDir = "",
|
outDir = null,
|
||||||
postfix = "",
|
postfix = null,
|
||||||
prefix = "",
|
prefix = null,
|
||||||
repext = "",
|
repext = null,
|
||||||
romname = "",
|
romname = null,
|
||||||
romtype = "",
|
romtype = null,
|
||||||
root = "",
|
root = null,
|
||||||
rootdir = "",
|
rootdir = null,
|
||||||
sha1 = "",
|
sha1 = null,
|
||||||
status = "",
|
status = null,
|
||||||
tempDir = "",
|
tempDir = null,
|
||||||
url = "",
|
url = null,
|
||||||
version = "";
|
version = null;
|
||||||
List<string> inputs = new List<string>();
|
List<string> inputs = new List<string>();
|
||||||
|
|
||||||
// Determine which switches are enabled (with values if necessary)
|
// Determine which switches are enabled (with values if necessary)
|
||||||
@@ -308,10 +307,6 @@ namespace SabreTools
|
|||||||
case "--restore":
|
case "--restore":
|
||||||
restore = true;
|
restore = true;
|
||||||
break;
|
break;
|
||||||
case "-rh":
|
|
||||||
case "--rem-head":
|
|
||||||
removeHeader = true;
|
|
||||||
break;
|
|
||||||
case "-rme":
|
case "-rme":
|
||||||
case "--rem-ext":
|
case "--rem-ext":
|
||||||
remext = true;
|
remext = true;
|
||||||
@@ -591,7 +586,7 @@ namespace SabreTools
|
|||||||
addFileDates,
|
addFileDates,
|
||||||
tempDir,
|
tempDir,
|
||||||
copyFiles,
|
copyFiles,
|
||||||
removeHeader,
|
header,
|
||||||
maxParallelism);
|
maxParallelism);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user