[ALL] Rename a few things; fix GetSingleStreamInfo; add headerless DFD

This commit is contained in:
Matt Nadareski
2016-10-03 15:05:07 -07:00
parent c280253396
commit ccb063c74e
11 changed files with 189 additions and 94 deletions

View File

@@ -336,7 +336,7 @@ namespace SabreTools
// Loop through the datroot and add only needed files // Loop through the datroot and add only needed files
foreach (string file in Directory.EnumerateFiles(_dats, "*", SearchOption.AllDirectories)) foreach (string file in Directory.EnumerateFiles(_dats, "*", SearchOption.AllDirectories))
{ {
Rom dat = FileTools.GetSingleFileInfo(file); Rom dat = FileTools.GetSingleFileInfo(file, _logger);
// If the Dat isn't in the database and isn't already accounted for in the DatRoot, add it // If the Dat isn't in the database and isn't already accounted for in the DatRoot, add it
if (!databaseDats.Contains(dat.SHA1) && !toscan.ContainsKey(dat.SHA1)) if (!databaseDats.Contains(dat.SHA1) && !toscan.ContainsKey(dat.SHA1))
@@ -437,7 +437,7 @@ namespace SabreTools
if (datRootDats.Contains(input.ToLowerInvariant())) if (datRootDats.Contains(input.ToLowerInvariant()))
{ {
string fullpath = Path.GetFullPath(datRootDats[datRootDats.IndexOf(input.ToLowerInvariant())]); string fullpath = Path.GetFullPath(datRootDats[datRootDats.IndexOf(input.ToLowerInvariant())]);
string sha1 = FileTools.GetSingleFileInfo(fullpath).SHA1; string sha1 = FileTools.GetSingleFileInfo(fullpath, _logger).SHA1;
foundDats.Add(sha1, fullpath); foundDats.Add(sha1, fullpath);
} }
else else

View File

@@ -70,7 +70,8 @@ namespace SabreTools
foreach (string input in inputs) foreach (string input in inputs)
{ {
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 */, 4 /* maxDegreeOfParallelism */, _logger); true /* enableGzip */, false /* addBlanks */, false /* addDate */, "__temp__" /* tempDir */, false /* copyFiles */,
false /* removeHeader */, 4 /* maxDegreeOfParallelism */, _logger);
datdata.WriteToFile("", logger); datdata.WriteToFile("", logger);
} }
logger.Close(); logger.Close();

View File

@@ -134,6 +134,7 @@ namespace SabreTools.Helper
helptext.Add(" -ab, --add-blank Output blank files for folders"); helptext.Add(" -ab, --add-blank Output blank files for folders");
helptext.Add(" -ad, --add-date Output dates for each file parsed"); helptext.Add(" -ad, --add-date Output dates for each file parsed");
helptext.Add(" -cf, --copy-files Copy files to the temp directory before parsing"); helptext.Add(" -cf, --copy-files Copy files to the temp directory before parsing");
helptext.Add(" -rh, --rem-head Remove headers from hash calculations");
helptext.Add(" -t=, --temp= Set the temporary directory to use"); helptext.Add(" -t=, --temp= Set the temporary directory to use");
helptext.Add(" -mt={4} Amount of threads to use (-1 unlimted)"); helptext.Add(" -mt={4} Amount of threads to use (-1 unlimted)");
helptext.Add(" -es, --ext-split Split a DAT by two file extensions"); helptext.Add(" -es, --ext-split Split a DAT by two file extensions");

View File

@@ -4564,10 +4564,11 @@ 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="removeHeader">True if headers should be removed from files if possible, false 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, int maxDegreeOfParallelism, Logger logger) bool enableGzip, bool addBlanks, bool addDate, string tempDir, bool copyFiles, bool removeHeader, 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))
@@ -4598,7 +4599,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, maxDegreeOfParallelism, logger); tempDir, copyFiles, removeHeader, 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
@@ -4687,10 +4688,11 @@ 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="removeHeader">True if headers should be removed from files if possible, false 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, int maxDegreeOfParallelism, Logger logger) bool enableGzip, bool addBlanks, bool addDate, string tempDir, bool copyFiles, bool removeHeader, 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;
@@ -4760,7 +4762,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, logger); DFDProcessFile(newItem, "", newBasePath, noMD5, noSHA1, addDate, removeHeader, logger);
} }
} }
// Otherwise, attempt to extract the files to the temporary directory // Otherwise, attempt to extract the files to the temporary directory
@@ -4792,13 +4794,14 @@ namespace SabreTools.Helper
noMD5, noMD5,
noSHA1, noSHA1,
addDate, addDate,
removeHeader,
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, logger); DFDProcessFile(newItem, "", newBasePath, noMD5, noSHA1, addDate, removeHeader, logger);
} }
} }
@@ -4823,12 +4826,17 @@ namespace SabreTools.Helper
/// Process a single file as a file /// Process a single file as a file
/// </summary> /// </summary>
/// <param name="item">File to be added</param> /// <param name="item">File to be added</param>
/// <param name="basepath">Path the represents the parent directory</param>
/// <param name="parent">Parent game to be used</param> /// <param name="parent">Parent game to be used</param>
private void DFDProcessFile(string item, string parent, string basePath, bool noMD5, bool noSHA1, bool addDate, Logger logger) /// <param name="basePath">Path the represents the parent directory</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="addDate">True if dates should be archived for all files, false otherwise</param>
/// <param name="removeHeader">True if headers should be removed from files if possible, false otherwise</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 removeHeader, Logger logger)
{ {
logger.Verbose(Path.GetFileName(item) + " treated like a file"); logger.Verbose(Path.GetFileName(item) + " treated like a file");
Rom rom = FileTools.GetSingleFileInfo(item, noMD5: noMD5, noSHA1: noSHA1, date: addDate); Rom rom = FileTools.GetSingleFileInfo(item, logger, noMD5: noMD5, noSHA1: noSHA1, date: addDate, removeHeader: removeHeader);
DFDProcessFileHelper(item, rom, basePath, parent, logger); DFDProcessFileHelper(item, rom, basePath, parent, logger);
} }

View File

@@ -138,7 +138,8 @@ namespace SabreTools.Helper
foreach (string input in _inputs) foreach (string input in _inputs)
{ {
_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 */, 4 /* maxDegreeOfParallelism */, _logger); true /* enableGzip */, false /* addBlanks */, false /* addDate */, "" /* tempDir */, false /* copyFiles */,
false /* removeHeader */, 4 /* maxDegreeOfParallelism */, _logger);
} }
// Setup the fixdat // Setup the fixdat
@@ -354,7 +355,7 @@ namespace SabreTools.Helper
// Hash and match the external files // Hash and match the external files
if (shouldExternalScan) if (shouldExternalScan)
{ {
RebuildToOutputAlternateParseRomHelper(file, ref matchdat); RebuildToOutputAlternateParseRomHelper(file, ref matchdat, _logger);
} }
// If we should scan the file as an archive // If we should scan the file as an archive
@@ -370,7 +371,7 @@ namespace SabreTools.Helper
// Now add all of the roms to the DAT // Now add all of the roms to the DAT
for (int i = 0; i < internalRomData.Count; i++) for (int i = 0; i < internalRomData.Count; i++)
{ {
RebuildToOutputAlternateParseRomHelper(file, ref matchdat); RebuildToOutputAlternateParseRomHelper(file, ref matchdat, _logger);
} }
} }
// Otherwise, try to extract the file to the temp folder // Otherwise, try to extract the file to the temp folder
@@ -385,13 +386,13 @@ namespace SabreTools.Helper
List<string> extractedFiles = Directory.EnumerateFiles(_tempDir, "*", SearchOption.AllDirectories).ToList(); List<string> extractedFiles = Directory.EnumerateFiles(_tempDir, "*", SearchOption.AllDirectories).ToList();
foreach (string extractedFile in extractedFiles) foreach (string extractedFile in extractedFiles)
{ {
RebuildToOutputAlternateParseRomHelper(extractedFile, ref matchdat); RebuildToOutputAlternateParseRomHelper(extractedFile, ref matchdat, _logger);
} }
} }
// Otherwise, skip extracting and just get information on the file itself (if we didn't already) // Otherwise, skip extracting and just get information on the file itself (if we didn't already)
else if (!shouldExternalScan) else if (!shouldExternalScan)
{ {
RebuildToOutputAlternateParseRomHelper(file, ref matchdat); RebuildToOutputAlternateParseRomHelper(file, ref matchdat, _logger);
} }
// Clean the temp directory for the next round // Clean the temp directory for the next round
@@ -455,10 +456,11 @@ namespace SabreTools.Helper
/// </summary> /// </summary>
/// <param name="file">Name of the file to attempt to add</param> /// <param name="file">Name of the file to attempt to add</param>
/// <param name="matchdat">Reference to the Dat to add to</param> /// <param name="matchdat">Reference to the Dat to add to</param>
/// <param name="logger">Logger object for file and console output</param>
/// <returns>True if the file could be added, false otherwise</returns> /// <returns>True if the file could be added, false otherwise</returns>
public bool RebuildToOutputAlternateParseRomHelper(string file, ref DatFile matchdat) public bool RebuildToOutputAlternateParseRomHelper(string file, ref DatFile matchdat, Logger logger)
{ {
Rom rom = FileTools.GetSingleFileInfo(file); Rom rom = FileTools.GetSingleFileInfo(file, logger);
// If we have a blank RomData, it's an error // If we have a blank RomData, it's an error
if (rom.Name == null) if (rom.Name == null)
@@ -494,7 +496,7 @@ namespace SabreTools.Helper
// 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); Skippers.TransformStream(input, output, rule, _logger, false, true);
Rom romNH = FileTools.GetSingleStreamInfo(output); Rom romNH = FileTools.GetSingleStreamInfo(output, output.Length);
romNH.Name = "HEAD::" + rom.Name; romNH.Name = "HEAD::" + rom.Name;
romNH.MachineName = rom.MachineName; romNH.MachineName = rom.MachineName;
@@ -544,7 +546,7 @@ namespace SabreTools.Helper
// Hash and match the external files // Hash and match the external files
if (shouldExternalScan) if (shouldExternalScan)
{ {
Rom rom = FileTools.GetSingleFileInfo(input); Rom rom = FileTools.GetSingleFileInfo(input, _logger);
// If we have a blank RomData, it's an error // If we have a blank RomData, it's an error
if (rom.Name == null) if (rom.Name == null)
@@ -614,7 +616,7 @@ namespace SabreTools.Helper
// 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); Skippers.TransformFile(input, newinput, rule, _logger);
Rom drom = FileTools.GetSingleFileInfo(newinput); Rom drom = FileTools.GetSingleFileInfo(newinput, _logger);
// If we have a blank RomData, it's an error // If we have a blank RomData, it's an error
if (drom.Name == null) if (drom.Name == null)
@@ -912,7 +914,7 @@ namespace SabreTools.Helper
ArchiveTools.ExtractArchive(Path.GetFullPath(archive), temparcdir, _logger); ArchiveTools.ExtractArchive(Path.GetFullPath(archive), temparcdir, _logger);
foreach (string tempfile in Directory.EnumerateFiles(temparcdir, "*", SearchOption.AllDirectories)) foreach (string tempfile in Directory.EnumerateFiles(temparcdir, "*", SearchOption.AllDirectories))
{ {
roms.Add(FileTools.GetSingleFileInfo(Path.GetFullPath(tempfile))); roms.Add(FileTools.GetSingleFileInfo(Path.GetFullPath(tempfile), _logger));
} }
// Clear the temporary archive directory // Clear the temporary archive directory

View File

@@ -154,10 +154,9 @@ Options:
Normally, the DAT will be created with the date in the file name. This flag removes Normally, the DAT will be created with the date in the file name. This flag removes
that but keeps the date tag intact. that but keeps the date tag intact.
-u, --unzip Force unzipping in created DAT -fp=, --forcepack= Set force packing
This sets the 'forcepacking="unzip"' flag in the outputted DAT. When used with a Set the forcepacking flag to one of the supported values:
file manager that allows for it, this will force the outputted files to be in None, Zip, Unzip
subdirectories instead of archives.
-f, --files Treat archives as files -f, --files Treat archives as files
Instead of trying to enumerate the files within archives, treat the archives as Instead of trying to enumerate the files within archives, treat the archives as
@@ -241,6 +240,11 @@ Options:
If this flag is set, then all files that are going to be parsed are moved to the temporary directory before being hashed. This can be helpful in cases where the If this flag is set, then all files that are going to be parsed are moved to the temporary directory before being hashed. This can be helpful in cases where the
temp folder is located on an SSD and the user wants to take advantage of this. temp folder is located on an SSD and the user wants to take advantage of this.
-rh, --rem-head Remove headers from hash calculations
If this flag is set, then all files that have copier headers that are detected will
have them removed from the hash calculation. This will allow for a headered collection
to be hashed without possibly variant information.
-t=, --temp= Set the name of the temporary directory -t=, --temp= Set the name of the temporary directory
Optionally, a temp folder can be supplied in the case the default temp directory Optionally, a temp folder can be supplied in the case the default temp directory
(inside the running folder) is not preferred. This is used for any operations (inside the running folder) is not preferred. This is used for any operations
@@ -1101,6 +1105,11 @@ Below are originally from SabreTools / DATabase -
By default, this will set the forcepacking="unzip" flag on the output DAT. This By default, this will set the forcepacking="unzip" flag on the output DAT. This
flag disables this output flag disables this output
-u, --unzip Force unzipping in created DAT
This sets the 'forcepacking="unzip"' flag in the outputted DAT. When used with a
file manager that allows for it, this will force the outputted files to be in
subdirectories instead of archives.
Below are originally from SingleGame (Standalone) - Below are originally from SingleGame (Standalone) -
-r=rootdir Set the directory name for path size -r=rootdir Set the directory name for path size

View File

@@ -324,7 +324,10 @@ namespace SabreTools.Helper
// Loop through and find a Skipper that has the right name // Loop through and find a Skipper that has the right name
logger.Verbose("Beginning search for matching header skip rules"); logger.Verbose("Beginning search for matching header skip rules");
foreach (Skipper skipper in List) List<Skipper> tempList = new List<Skipper>();
tempList.AddRange(List);
foreach (Skipper skipper in tempList)
{ {
if (String.IsNullOrEmpty(skipperName) || (!String.IsNullOrEmpty(skipper.Name) && skipperName.ToLowerInvariant() == skipper.Name.ToLowerInvariant())) if (String.IsNullOrEmpty(skipperName) || (!String.IsNullOrEmpty(skipper.Name) && skipperName.ToLowerInvariant() == skipper.Name.ToLowerInvariant()))
{ {

View File

@@ -965,7 +965,7 @@ namespace SabreTools.Helper
outDir = Path.GetFullPath(outDir); outDir = Path.GetFullPath(outDir);
// Now get the Rom info for the file so we have hashes and size // Now get the Rom info for the file so we have hashes and size
Rom rom = FileTools.GetSingleFileInfo(input); Rom rom = FileTools.GetSingleFileInfo(input, logger);
// If it doesn't exist, create the output file and then write // If it doesn't exist, create the output file and then write
string outfile = Path.Combine(outDir, rom.SHA1 + ".gz"); string outfile = Path.Combine(outDir, rom.SHA1 + ".gz");

View File

@@ -151,12 +151,14 @@ namespace SabreTools.Helper
/// Retrieve file information for a single file /// Retrieve file information for a single file
/// </summary> /// </summary>
/// <param name="input">Filename to get information from</param> /// <param name="input">Filename to get information from</param>
/// <param name="logger">Logger object for console and file output</param>
/// <param name="noMD5">True if MD5 hashes should not be calculated, false otherwise (default)</param> /// <param name="noMD5">True if MD5 hashes should not be calculated, false otherwise (default)</param>
/// <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="removeHeader">True if headers should be removed from files if possible, false otherwise (default)</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 GetSingleFileInfo(string input, bool noMD5 = false, bool noSHA1 = false, long offset = 0, bool date = false) public static Rom GetSingleFileInfo(string input, Logger logger, bool noMD5 = false, bool noSHA1 = false, long offset = 0, bool date = false, bool removeHeader = false)
{ {
// Add safeguard if file doesn't exist // Add safeguard if file doesn't exist
if (!File.Exists(input)) if (!File.Exists(input))
@@ -165,7 +167,36 @@ namespace SabreTools.Helper
} }
// Get the information from the file stream // Get the information from the file stream
Rom rom = GetSingleStreamInfo(File.OpenRead(input), noMD5, noSHA1, offset, false); Rom rom = new Rom();
if (removeHeader)
{
SkipperRule rule = Skippers.MatchesSkipper(input, "", logger);
// If there's a match, get the new information from the stream
if (rule.Tests != null && rule.Tests.Count != 0)
{
// Create the input and output streams
MemoryStream outputStream = new MemoryStream();
FileStream inputStream = File.OpenRead(input);
// Transform the stream and get the information from it
Skippers.TransformStream(inputStream, outputStream, rule, logger, false, true);
rom = GetSingleStreamInfo(outputStream, outputStream.Length);
// Dispose of the streams
outputStream.Dispose();
inputStream.Dispose();
}
// Otherwise, just get the info
else
{
rom = GetSingleStreamInfo(File.OpenRead(input), new FileInfo(input).Length, noMD5, noSHA1, offset, false);
}
}
else
{
rom = GetSingleStreamInfo(File.OpenRead(input), new FileInfo(input).Length, noMD5, noSHA1, offset, false);
}
// Add unique data from the file // Add unique data from the file
rom.Name = Path.GetFileName(input); rom.Name = Path.GetFileName(input);
@@ -330,7 +361,7 @@ namespace SabreTools.Helper
} }
// Now add the information to the database if it's not already there // Now add the information to the database if it's not already there
Rom rom = GetSingleFileInfo(newfile); Rom rom = GetSingleFileInfo(newfile, logger);
DatabaseTools.AddHeaderToDatabase(hstr, rom.SHA1, rule.SourceFile, logger); DatabaseTools.AddHeaderToDatabase(hstr, rom.SHA1, rule.SourceFile, logger);
return true; return true;
@@ -354,7 +385,7 @@ namespace SabreTools.Helper
bool success = true; bool success = true;
// First, get the SHA-1 hash of the file // First, get the SHA-1 hash of the file
Rom rom = GetSingleFileInfo(file); Rom rom = GetSingleFileInfo(file, logger);
// Then try to pull the corresponding headers from the database // Then try to pull the corresponding headers from the database
string header = ""; string header = "";
@@ -428,12 +459,13 @@ namespace SabreTools.Helper
/// Retrieve file information for a single file /// Retrieve file information for a single file
/// </summary> /// </summary>
/// <param name="input">Filename to get information from</param> /// <param name="input">Filename to get information from</param>
/// <param name="size">Size of the input stream</param>
/// <param name="noMD5">True if MD5 hashes should not be calculated, false otherwise (default)</param> /// <param name="noMD5">True if MD5 hashes should not be calculated, false otherwise (default)</param>
/// <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="keepReadOpen">True if the underlying read stream should be kept open, false otherwise</param> /// <param name="keepReadOpen">True if the underlying read stream should be kept open, false 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 GetSingleStreamInfo(Stream input, bool noMD5 = false, bool noSHA1 = false, long offset = 0, bool keepReadOpen = false) public static Rom GetSingleStreamInfo(Stream input, long size, bool noMD5 = false, bool noSHA1 = false, long offset = 0, bool keepReadOpen = false)
{ {
// If we have a negative offset, zero it out since we don't support it yet // If we have a negative offset, zero it out since we don't support it yet
if (offset < 0) if (offset < 0)
@@ -444,7 +476,7 @@ namespace SabreTools.Helper
Rom rom = new Rom Rom rom = new Rom
{ {
Type = ItemType.Rom, Type = ItemType.Rom,
Size = input.Length - Math.Abs(offset), Size = size,
CRC = string.Empty, CRC = string.Empty,
MD5 = string.Empty, MD5 = string.Empty,
SHA1 = string.Empty, SHA1 = string.Empty,
@@ -458,10 +490,7 @@ namespace SabreTools.Helper
SHA1 sha1 = SHA1.Create(); SHA1 sha1 = SHA1.Create();
// Seek to the starting position, if one is set // Seek to the starting position, if one is set
if (offset > 0)
{
input.Seek(offset, SeekOrigin.Begin); input.Seek(offset, SeekOrigin.Begin);
}
byte[] buffer = new byte[1024]; byte[] buffer = new byte[1024];
int read; int read;

View File

@@ -64,13 +64,14 @@ namespace SabreTools
/// <param name="superdat">True to enable SuperDAT-style reading, false otherwise</param> /// <param name="superdat">True to enable SuperDAT-style reading, false otherwise</param>
/// <param name="noMD5">True to disable getting MD5 hash, false otherwise</param> /// <param name="noMD5">True to disable getting MD5 hash, false otherwise</param>
/// <param name="noSHA1">True to disable getting SHA-1 hash, false otherwise</param> /// <param name="noSHA1">True to disable getting SHA-1 hash, false otherwise</param>
/// <param name="bare">True if the date should be omitted from the DAT, false otherwise</param> /// <param name="removeDateFromAutomaticName">True if the date should be omitted from the DAT, false otherwise</param>
/// <param name="archivesAsFiles">True if archives should be treated as files, false otherwise</param> /// <param name="parseArchivesAsFiles">True if archives should be treated as files, false otherwise</param>
/// <param name="enableGzip">True if GZIP archives should be treated as files, false otherwise</param> /// <param name="enableGzip">True if GZIP archives should be treated as files, false otherwise</param>
/// <param name="addBlanks">True if blank items should be created for empty folders, false otherwise</param> /// <param name="addBlankFilesForEmptyFolder">True if blank items should be created for empty folders, false otherwise</param>
/// <param name="addDate">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="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,
@@ -79,21 +80,37 @@ namespace SabreTools
string category, string category,
string version, string version,
string author, string author,
bool forceunpack, string forcepack,
OutputFormat outputFormat, OutputFormat outputFormat,
bool romba, bool romba,
bool superdat, bool superdat,
bool noMD5, bool noMD5,
bool noSHA1, bool noSHA1,
bool bare, bool removeDateFromAutomaticName,
bool archivesAsFiles, bool parseArchivesAsFiles,
bool enableGzip, bool enableGzip,
bool addBlanks, bool addBlankFilesForEmptyFolder,
bool addDate, bool addFileDates,
string tempDir, string tempDir,
bool copyFiles, bool copyFiles,
bool removeHeader,
int maxDegreeOfParallelism) int maxDegreeOfParallelism)
{ {
ForcePacking fp = ForcePacking.None;
switch (forcepack.ToLowerInvariant())
{
case "none":
default:
fp = ForcePacking.None;
break;
case "zip":
fp = ForcePacking.Zip;
break;
case "unzip":
fp = ForcePacking.Unzip;
break;
}
// Create a new DATFromDir object and process the inputs // Create a new DATFromDir object and process the inputs
DatFile basedat = new DatFile DatFile basedat = new DatFile
{ {
@@ -104,7 +121,7 @@ namespace SabreTools
Version = version, Version = version,
Date = DateTime.Now.ToString("yyyy-MM-dd"), Date = DateTime.Now.ToString("yyyy-MM-dd"),
Author = author, Author = author,
ForcePacking = (forceunpack ? ForcePacking.Unzip : ForcePacking.None), ForcePacking = fp,
OutputFormat = (outputFormat == 0 ? OutputFormat.Logiqx : outputFormat), OutputFormat = (outputFormat == 0 ? OutputFormat.Logiqx : outputFormat),
Romba = romba, Romba = romba,
Type = (superdat ? "SuperDAT" : ""), Type = (superdat ? "SuperDAT" : ""),
@@ -121,7 +138,8 @@ namespace SabreTools
datdata.Files = new SortedDictionary<string, List<DatItem>>(); datdata.Files = new SortedDictionary<string, List<DatItem>>();
string basePath = Path.GetFullPath(path); string basePath = Path.GetFullPath(path);
bool success = datdata.PopulateDatFromDir(basePath, noMD5, noSHA1, bare, archivesAsFiles, enableGzip, addBlanks, addDate, tempDir, copyFiles, maxDegreeOfParallelism, _logger); bool success = datdata.PopulateDatFromDir(basePath, noMD5, noSHA1, removeDateFromAutomaticName, parseArchivesAsFiles, enableGzip,
addBlankFilesForEmptyFolder, addFileDates, tempDir, copyFiles, removeHeader, maxDegreeOfParallelism, _logger);
// If it was a success, write the DAT out // If it was a success, write the DAT out
if (success) if (success)

View File

@@ -48,39 +48,43 @@ namespace SabreTools
// Set all default values // Set all default values
bool help = false, bool help = false,
addBlanks = false,
addDate = false, // Feature flags
archivesAsFiles = false, datFromDir = false,
baddumpColumn = false, headerer = false,
bare = false, splitByExt = false,
clean = false, splitByHash = false,
splitByType = false,
stats = false,
update = false,
// Other flags
addBlankFilesForEmptyFolder = false,
addFileDates = false,
cleanGameNames = false,
copyFiles = false, copyFiles = false,
datfromdir = false, datPrefix = false,
datprefix = false,
dedup = false, dedup = false,
enableGzip = false, enableGzip = false,
extsplit = false,
forceunpack = false,
hashsplit = false,
headerer = false,
inplace = false, inplace = false,
merge = false, merge = false,
nodumpColumn = false,
noMD5 = false, noMD5 = false,
noSHA1 = false, noSHA1 = false,
parseArchivesAsFiles = false,
quotes = false, quotes = false,
rem = false, rem = false,
remext = false, remext = false,
removeDateFromAutomaticName = false,
removeHeader = false,
restore = false, restore = false,
romba = false, romba = false,
showBaddumpColumn = false,
showNodumpColumn = false,
single = false, single = false,
softlist = false, softlist = false,
stats = false,
superdat = false, superdat = false,
trim = false, trim = false,
typesplit = false,
skip = false, skip = false,
update = false,
usegame = true; usegame = true;
bool? cascade = null, bool? cascade = null,
tsv = null; tsv = null;
@@ -140,19 +144,19 @@ namespace SabreTools
break; break;
case "-ab": case "-ab":
case "--add-blank": case "--add-blank":
addBlanks = true; addBlankFilesForEmptyFolder = true;
break; break;
case "-ad": case "-ad":
case "--add-date": case "--add-date":
addDate = true; addFileDates = true;
break; break;
case "-b": case "-b":
case "--bare": case "--bare":
bare = true; removeDateFromAutomaticName = true;
break; break;
case "-bc": case "-bc":
case "--baddump-col": case "--baddump-col":
baddumpColumn = true; showBaddumpColumn = true;
break; break;
case "-c": case "-c":
case "--cascade": case "--cascade":
@@ -169,12 +173,12 @@ namespace SabreTools
break; break;
case "-clean": case "-clean":
case "--clean": case "--clean":
clean = true; cleanGameNames = true;
break; break;
case "-d": case "-d":
case "--d2d": case "--d2d":
case "--dfd": case "--dfd":
datfromdir = true; datFromDir = true;
break; break;
case "-dd": case "-dd":
case "--dedup": case "--dedup":
@@ -198,15 +202,15 @@ namespace SabreTools
break; break;
case "-es": case "-es":
case "--ext-split": case "--ext-split":
extsplit = true; splitByExt = true;
break; break;
case "-f": case "-f":
case "--files": case "--files":
archivesAsFiles = true; parseArchivesAsFiles = true;
break; break;
case "-gp": case "-gp":
case "--game-prefix": case "--game-prefix":
datprefix = true; datPrefix = true;
break; break;
case "-gz": case "-gz":
case "--gz-files": case "--gz-files":
@@ -218,7 +222,7 @@ namespace SabreTools
break; break;
case "-hs": case "-hs":
case "--hash-split": case "--hash-split":
hashsplit = true; splitByHash = true;
break; break;
case "-html": case "-html":
case "--html": case "--html":
@@ -234,7 +238,7 @@ namespace SabreTools
break; break;
case "-nc": case "-nc":
case "--nodump-col": case "--nodump-col":
nodumpColumn = true; showNodumpColumn = true;
break; break;
case "-nm": case "-nm":
case "--noMD5": case "--noMD5":
@@ -304,6 +308,10 @@ 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;
@@ -338,17 +346,13 @@ namespace SabreTools
break; break;
case "-ts": case "-ts":
case "--type-split": case "--type-split":
typesplit = true; splitByType = true;
break; break;
case "-tsv": case "-tsv":
case "--tsv": case "--tsv":
tsv = true; tsv = true;
statOutputFormat = StatOutputFormat.TSV; statOutputFormat = StatOutputFormat.TSV;
break; break;
case "-u":
case "--unzip":
forceunpack = true;
break;
case "-ud": case "-ud":
case "--update": case "--update":
update = true; update = true;
@@ -543,8 +547,8 @@ namespace SabreTools
} }
// If more than one switch is enabled, show the help screen // If more than one switch is enabled, show the help screen
if (!(extsplit ^ hashsplit ^ headerer ^ (datfromdir || merge || diffMode != 0 || update if (!(splitByExt ^ splitByHash ^ headerer ^ (datFromDir || merge || diffMode != 0 || update
|| outputFormat != 0 || trim) ^ rem ^ stats ^ typesplit)) || outputFormat != 0 || trim) ^ rem ^ stats ^ splitByType))
{ {
_logger.Error("Only one feature switch is allowed at a time"); _logger.Error("Only one feature switch is allowed at a time");
Build.Help(); Build.Help();
@@ -553,8 +557,8 @@ namespace SabreTools
} }
// If a switch that requires a filename is set and no file is, show the help screen // If a switch that requires a filename is set and no file is, show the help screen
if (inputs.Count == 0 && (datfromdir || extsplit || hashsplit || headerer if (inputs.Count == 0 && (datFromDir || splitByExt || splitByHash || headerer
|| (merge || diffMode != 0 || update || outputFormat != 0) || stats || trim || typesplit)) || (merge || diffMode != 0 || update || outputFormat != 0) || stats || trim || splitByType))
{ {
_logger.Error("This feature requires at least one input"); _logger.Error("This feature requires at least one input");
Build.Help(); Build.Help();
@@ -565,20 +569,40 @@ namespace SabreTools
// Now take care of each mode in succesion // Now take care of each mode in succesion
// Create a DAT from a directory or set of directories // Create a DAT from a directory or set of directories
if (datfromdir) if (datFromDir)
{ {
InitDatFromDir(inputs, filename, name, description, category, version, author, forceunpack, outputFormat, romba, InitDatFromDir(inputs,
superdat, noMD5, noSHA1, bare, archivesAsFiles, enableGzip, addBlanks, addDate, tempDir, copyFiles, maxParallelism); filename,
name,
description,
category,
version,
author,
forcepack,
outputFormat,
romba,
superdat,
noMD5,
noSHA1,
removeDateFromAutomaticName,
parseArchivesAsFiles,
enableGzip,
addBlankFilesForEmptyFolder,
addFileDates,
tempDir,
copyFiles,
removeHeader,
maxParallelism);
} }
// Split a DAT by extension // Split a DAT by extension
else if (extsplit) else if (splitByExt)
{ {
InitExtSplit(inputs, exta, extb, outDir); InitExtSplit(inputs, exta, extb, outDir);
} }
// Split a DAT by available hashes // Split a DAT by available hashes
else if (hashsplit) else if (splitByHash)
{ {
InitHashSplit(inputs, outDir); InitHashSplit(inputs, outDir);
} }
@@ -592,11 +616,11 @@ namespace SabreTools
// Get statistics on input files // Get statistics on input files
else if (stats) else if (stats)
{ {
InitStats(inputs, filename, single, baddumpColumn, nodumpColumn, statOutputFormat); InitStats(inputs, filename, single, showBaddumpColumn, showNodumpColumn, statOutputFormat);
} }
// Split a DAT by item type // Split a DAT by item type
else if (typesplit) else if (splitByType)
{ {
InitTypeSplit(inputs, outDir); InitTypeSplit(inputs, outDir);
} }
@@ -606,8 +630,8 @@ namespace SabreTools
{ {
InitUpdate(inputs, filename, name, description, rootdir, category, version, date, author, email, homepage, url, comment, header, InitUpdate(inputs, filename, name, description, rootdir, category, version, date, author, email, homepage, url, comment, header,
superdat, forcemerge, forcend, forcepack, outputFormat, usegame, prefix, superdat, forcemerge, forcend, forcepack, outputFormat, usegame, prefix,
postfix, quotes, repext, addext, remext, datprefix, romba, tsv, merge, diffMode, cascade, inplace, skip, bare, gamename, romname, postfix, quotes, repext, addext, remext, datPrefix, romba, tsv, merge, diffMode, cascade, inplace, skip, removeDateFromAutomaticName, gamename, romname,
romtype, sgt, slt, seq, crc, md5, sha1, status, trim, single, root, outDir, clean, softlist, dedup, maxParallelism); romtype, sgt, slt, seq, crc, md5, sha1, status, trim, single, root, outDir, cleanGameNames, softlist, dedup, maxParallelism);
} }
// If nothing is set, show the help // If nothing is set, show the help