[SabreTools, Flags, DatFile] Add size split

This commit is contained in:
Matt Nadareski
2018-01-08 12:40:48 -08:00
parent 2e67c74c54
commit 85d7b13a09
6 changed files with 140 additions and 5 deletions

View File

@@ -4720,8 +4720,9 @@ namespace SabreTools.Library.DatFiles
/// <param name="extb">Second extension to split on (Extension Split only)</param>
/// <param name="shortname">True if short filenames should be used, false otherwise (Level Split only)</param>
/// <param name="basedat">True if original filenames should be used as the base for output filename, false otherwise (Level Split only)</param>
/// <param name="radix">Long value representing the split point (Size Split only)</param>
public void DetermineSplitType(List<string> inputs, string outDir, bool inplace, SplittingMode splittingMode,
List<string> exta, List<string> extb, bool shortname, bool basedat)
List<string> exta, List<string> extb, bool shortname, bool basedat, long radix)
{
// If we somehow have the "none" split type, return
if (splittingMode == SplittingMode.None)
@@ -4754,6 +4755,10 @@ namespace SabreTools.Library.DatFiles
{
SplitByLevel(outDir, shortname, basedat);
}
if ((splittingMode & SplittingMode.Size) != 0)
{
SplitBySize(outDir, radix);
}
if ((splittingMode & SplittingMode.Type) != 0)
{
SplitByType(outDir);
@@ -5212,7 +5217,94 @@ namespace SabreTools.Library.DatFiles
}
/// <summary>
/// Split a DAT by type of Rom
/// Split a DAT by size of Rom
/// </summary>
/// <param name="outDir">Name of the directory to write the DATs out to</param>
/// <param name="radix">Long value representing the split point</param>
/// <returns>True if split succeeded, false otherwise</returns>
public bool SplitBySize(string outDir, long radix)
{
// Create each of the respective output DATs
Globals.Logger.User("Creating and populating new DATs");
DatFile lessDat = new DatFile
{
FileName = this.FileName + " (less than " + radix + " )",
Name = this.Name + " (less than " + radix + " )",
Description = this.Description + " (less than " + radix + " )",
Category = this.Category,
Version = this.Version,
Date = this.Date,
Author = this.Author,
Email = this.Email,
Homepage = this.Homepage,
Url = this.Url,
Comment = this.Comment,
Header = this.Header,
Type = this.Type,
ForceMerging = this.ForceMerging,
ForceNodump = this.ForceNodump,
ForcePacking = this.ForcePacking,
DatFormat = this.DatFormat,
DedupeRoms = this.DedupeRoms,
};
DatFile greaterEqualDat = new DatFile
{
FileName = this.FileName + " (equal-greater than " + radix + " )",
Name = this.Name + " (equal-greater than " + radix + " )",
Description = this.Description + " (equal-greater than " + radix + " )",
Category = this.Category,
Version = this.Version,
Date = this.Date,
Author = this.Author,
Email = this.Email,
Homepage = this.Homepage,
Url = this.Url,
Comment = this.Comment,
Header = this.Header,
Type = this.Type,
ForceMerging = this.ForceMerging,
ForceNodump = this.ForceNodump,
ForcePacking = this.ForcePacking,
DatFormat = this.DatFormat,
DedupeRoms = this.DedupeRoms,
};
// Now populate each of the DAT objects in turn
List<string> keys = Keys;
Parallel.ForEach(keys, Globals.ParallelOptions, key =>
{
List<DatItem> items = this[key];
foreach (DatItem item in items)
{
// If the file is not a Rom, it automatically goes in the "lesser" dat
if (item.Type != ItemType.Rom)
{
lessDat.Add(key, item);
}
// If the file is a Rom and less than the radix, put it in the "lesser" dat
else if (item.Type == ItemType.Rom && ((Rom)item).Size < radix)
{
lessDat.Add(key, item);
}
// If the file is a Rom and greater than or equal to the radix, put it in the "greater" dat
else if (item.Type == ItemType.Rom && ((Rom)item).Size >= radix)
{
greaterEqualDat.Add(key, item);
}
}
});
// Now, output all of the files to the output directory
Globals.Logger.User("DAT information created, outputting new files");
bool success = true;
success &= lessDat.Write(outDir);
success &= greaterEqualDat.Write(outDir);
return success;
}
/// <summary>
/// Split a DAT by type of DatItem
/// </summary>
/// <param name="outDir">Name of the directory to write the DATs out to</param>
/// <returns>True if split succeeded, false otherwise</returns>

View File

@@ -287,6 +287,7 @@ namespace SabreTools.Library.Data
Hash = Extension << 1,
Level = Hash << 1,
Type = Level << 1,
Size = Type << 1,
}
/// <summary>

View File

@@ -532,6 +532,15 @@ Options:
conjunction with --short to output in the format of "Original
Name (Name)" instead.
-szs, --size Split DAT(s) or folder by file sizes
For a DAT, or set of DATs, allow for splitting based on the sizes
of the files, specificially if the type is a rom (disks don't have
sizes)
-rad, --radix Set the midpoint to split at
Set the size at which all roms less than the size are put in the
first DAT, and everything greater than or equal goes in the second
-ts, --type Split DAT(s) or folder by file types (rom/disk)
For a DAT, or set of DATs, allow for splitting based on the types of
the files, specifically if the type is a rom or a disk.

View File

@@ -896,6 +896,17 @@ namespace SabreTools
null);
}
}
private static Feature sizeFlag
{
get
{
return new Feature(
new List<string>() { "-szs", "--size" },
"Split DAT(s) or folder by file sizes",
FeatureType.Flag,
null);
}
}
private static Feature skipFirstOutputFlag
{
get
@@ -1280,6 +1291,17 @@ namespace SabreTools
#region Private Int64 features
private static Feature radixInt64Input
{
get
{
return new Feature(
new List<string>() { "-rad", "--radix" },
"Set the midpoint to split at",
FeatureType.Int64,
null);
}
}
#endregion
@@ -2095,6 +2117,8 @@ namespace SabreTools
split.AddFeature("level", levelFlag);
split["level"].AddFeature("short", shortFlag);
split["level"].AddFeature("base", baseFlag);
split.AddFeature("size", sizeFlag);
split["size"].AddFeature("radix", radixInt64Input);
split.AddFeature("type", typeFlag);
#endregion

View File

@@ -189,12 +189,13 @@ namespace SabreTools
/// <param name="extb">Second extension to split on (Extension Split only)</param>
/// <param name="shortname">True if short filenames should be used, false otherwise (Level Split only)</param>
/// <param name="basedat">True if original filenames should be used as the base for output filename, false otherwise (Level Split only)</param>
/// <param name="radix">Long value representing the split point (Size Split only)</param>
private static void InitSplit(List<string> inputs, string outDir, bool inplace, DatFormat datFormat,
SplittingMode splittingMode, List<string> exta, List<string> extb, bool shortname, bool basedat)
SplittingMode splittingMode, List<string> exta, List<string> extb, bool shortname, bool basedat, long radix)
{
DatFile datfile = new DatFile();
datfile.DatFormat = datFormat;
datfile.DetermineSplitType(inputs, outDir, inplace, splittingMode, exta, extb, shortname, basedat);
datfile.DetermineSplitType(inputs, outDir, inplace, splittingMode, exta, extb, shortname, basedat, radix);
}
/// <summary>

View File

@@ -109,6 +109,7 @@ namespace SabreTools
rar = 1,
sevenzip = 1,
zip = 1;
long radix = 0;
string outDir = null,
tempDir = "";
DatHeader datHeader = new DatHeader();
@@ -421,6 +422,9 @@ namespace SabreTools
case "short":
shortname = true;
break;
case "size":
splittingMode |= SplittingMode.Size;
break;
case "skip-archives":
skipFileType = SkipFileType.Archive;
break;
@@ -540,6 +544,10 @@ namespace SabreTools
#region User Int64 Inputs
case "radix":
radix = (long)feat.Value.GetValue() == Int64.MinValue ? (long)feat.Value.GetValue() : 0;
break;
#endregion
#region User List<string> Inputs
@@ -755,7 +763,7 @@ namespace SabreTools
// Split a DAT by the split type
case "Split":
VerifyInputs(inputs, feature);
InitSplit(inputs, outDir, inplace, datHeader.DatFormat, splittingMode, exta, extb, shortname, basedat);
InitSplit(inputs, outDir, inplace, datHeader.DatFormat, splittingMode, exta, extb, shortname, basedat, radix);
break;
// Get statistics on input files
case "Stats":