mirror of
https://github.com/claunia/SabreTools.git
synced 2025-12-16 19:14:27 +00:00
Distinguish IO extensions and helpers
This commit is contained in:
@@ -58,7 +58,7 @@ structure according to the original DAT master directory tree structure.";
|
|||||||
|
|
||||||
// Create the new output directory if it doesn't exist
|
// Create the new output directory if it doesn't exist
|
||||||
string outputFolder = Path.Combine(outdat, Path.GetFileNameWithoutExtension(foundDats[key]));
|
string outputFolder = Path.Combine(outdat, Path.GetFileNameWithoutExtension(foundDats[key]));
|
||||||
DirectoryExtensions.Ensure(outputFolder, create: true);
|
outputFolder.Ensure(create: true);
|
||||||
|
|
||||||
// Get all online depots
|
// Get all online depots
|
||||||
List<string> onlineDepots = _depots.Where(d => d.Value.Item2).Select(d => d.Key).ToList();
|
List<string> onlineDepots = _depots.Where(d => d.Value.Item2).Select(d => d.Key).ToList();
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ in -old DAT file. Ignores those entries in -old that are not in -new.";
|
|||||||
string outdat = GetString(features, OutStringValue);
|
string outdat = GetString(features, OutStringValue);
|
||||||
|
|
||||||
// Ensure the output directory
|
// Ensure the output directory
|
||||||
DirectoryExtensions.Ensure(outdat, create: true);
|
outdat.Ensure(create: true);
|
||||||
|
|
||||||
// Check that all required files exist
|
// Check that all required files exist
|
||||||
if (!File.Exists(olddat))
|
if (!File.Exists(olddat))
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ namespace RombaSharp.Features
|
|||||||
string outdat = GetString(features, OutStringValue);
|
string outdat = GetString(features, OutStringValue);
|
||||||
|
|
||||||
// Ensure the output directory
|
// Ensure the output directory
|
||||||
DirectoryExtensions.Ensure(outdat, create: true);
|
outdat.Ensure(create: true);
|
||||||
|
|
||||||
// Check that all required directories exist
|
// Check that all required directories exist
|
||||||
if (!Directory.Exists(source))
|
if (!Directory.Exists(source))
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ namespace RombaSharp.Features
|
|||||||
string newdat = GetString(features, NewStringValue);
|
string newdat = GetString(features, NewStringValue);
|
||||||
|
|
||||||
// Ensure the output directory
|
// Ensure the output directory
|
||||||
DirectoryExtensions.Ensure(outdat, create: true);
|
outdat.Ensure(create: true);
|
||||||
|
|
||||||
// Check that all required files exist
|
// Check that all required files exist
|
||||||
if (!File.Exists(olddat))
|
if (!File.Exists(olddat))
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ namespace RombaSharp.Features
|
|||||||
logger.Error("This feature is not yet implemented: import");
|
logger.Error("This feature is not yet implemented: import");
|
||||||
|
|
||||||
// First ensure the inputs and database connection
|
// First ensure the inputs and database connection
|
||||||
Inputs = DirectoryExtensions.GetFilesOnly(Inputs).Select(p => p.CurrentPath).ToList();
|
Inputs = PathTool.GetFilesOnly(Inputs).Select(p => p.CurrentPath).ToList();
|
||||||
SqliteConnection dbc = new SqliteConnection(_connectionString);
|
SqliteConnection dbc = new SqliteConnection(_connectionString);
|
||||||
SqliteCommand slc = new SqliteCommand();
|
SqliteCommand slc = new SqliteCommand();
|
||||||
dbc.Open();
|
dbc.Open();
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ namespace RombaSharp.Features
|
|||||||
logger.Error("This feature is not yet implemented: merge");
|
logger.Error("This feature is not yet implemented: merge");
|
||||||
|
|
||||||
// Verify that the inputs are valid directories
|
// Verify that the inputs are valid directories
|
||||||
Inputs = DirectoryExtensions.GetDirectoriesOnly(Inputs).Select(p => p.CurrentPath).ToList();
|
Inputs = PathTool.GetDirectoriesOnly(Inputs).Select(p => p.CurrentPath).ToList();
|
||||||
|
|
||||||
// Loop over all input directories
|
// Loop over all input directories
|
||||||
foreach (string input in Inputs)
|
foreach (string input in Inputs)
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ namespace RombaSharp.Features
|
|||||||
Dictionary<string, string> foundDats = GetValidDats(Inputs);
|
Dictionary<string, string> foundDats = GetValidDats(Inputs);
|
||||||
|
|
||||||
// Create the new output directory if it doesn't exist
|
// Create the new output directory if it doesn't exist
|
||||||
DirectoryExtensions.Ensure(Path.Combine(Globals.ExeDir, "out"), create: true);
|
Path.Combine(Globals.ExeDir, "out").Ensure(create: true);
|
||||||
|
|
||||||
// Now that we have the dictionary, we can loop through and output to a new folder for each
|
// Now that we have the dictionary, we can loop through and output to a new folder for each
|
||||||
foreach (string key in foundDats.Keys)
|
foreach (string key in foundDats.Keys)
|
||||||
|
|||||||
@@ -3,9 +3,8 @@ using System.Linq;
|
|||||||
using System.Security.Cryptography;
|
using System.Security.Cryptography;
|
||||||
|
|
||||||
using Aaru.Checksums;
|
using Aaru.Checksums;
|
||||||
using SabreTools.Core;
|
|
||||||
|
|
||||||
namespace SabreTools.IO
|
namespace SabreTools.Core.Tools
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Async hashing class wraper
|
/// Async hashing class wraper
|
||||||
@@ -116,6 +116,36 @@ namespace SabreTools.Core.Tools
|
|||||||
(int)((msDosDateTime >> 11) & 0x1F), (int)((msDosDateTime >> 5) & 0x3F), (int)((msDosDateTime & 0x1F) * 2));
|
(int)((msDosDateTime >> 11) & 0x1F), (int)((msDosDateTime >> 5) & 0x3F), (int)((msDosDateTime & 0x1F) * 2));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Get a proper romba sub path
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="hash">SHA-1 hash to get the path for</param>
|
||||||
|
/// <param name="depth">Positive value representing the depth of the depot</param>
|
||||||
|
/// <returns>Subfolder path for the given hash</returns>
|
||||||
|
public static string GetDepotPath(string hash, int depth)
|
||||||
|
{
|
||||||
|
// If the hash isn't the right size, then we return null
|
||||||
|
if (hash.Length != Constants.SHA1Length)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
// Cap the depth between 0 and 20, for now
|
||||||
|
if (depth < 0)
|
||||||
|
depth = 0;
|
||||||
|
else if (depth > Constants.SHA1ZeroBytes.Length)
|
||||||
|
depth = Constants.SHA1ZeroBytes.Length;
|
||||||
|
|
||||||
|
// Loop through and generate the subdirectory
|
||||||
|
string path = string.Empty;
|
||||||
|
for (int i = 0; i < depth; i++)
|
||||||
|
{
|
||||||
|
path += hash.Substring(i * 2, 2) + Path.DirectorySeparatorChar;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Now append the filename
|
||||||
|
path += $"{hash}.gz";
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
|
||||||
/// Indicates whether the specified array is null or has a length of zero
|
/// Indicates whether the specified array is null or has a length of zero
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="array">The array to test</param>
|
/// <param name="array">The array to test</param>
|
||||||
@@ -123,7 +153,7 @@ namespace SabreTools.Core.Tools
|
|||||||
/// <link>https://stackoverflow.com/questions/8560106/isnullorempty-equivalent-for-array-c-sharp</link>
|
/// <link>https://stackoverflow.com/questions/8560106/isnullorempty-equivalent-for-array-c-sharp</link>
|
||||||
public static bool IsNullOrEmpty(this Array array)
|
public static bool IsNullOrEmpty(this Array array)
|
||||||
{
|
{
|
||||||
return (array == null || array.Length == 0);
|
return array == null || array.Length == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -136,5 +166,33 @@ namespace SabreTools.Core.Tools
|
|||||||
List<char> invalidPath = Path.GetInvalidPathChars().ToList();
|
List<char> invalidPath = Path.GetInvalidPathChars().ToList();
|
||||||
return new string(s.Where(c => !invalidPath.Contains(c)).ToArray());
|
return new string(s.Where(c => !invalidPath.Contains(c)).ToArray());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Returns if the first byte array starts with the second array
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="arr1">First byte array to compare</param>
|
||||||
|
/// <param name="arr2">Second byte array to compare</param>
|
||||||
|
/// <param name="exact">True if the input arrays should match exactly, false otherwise (default)</param>
|
||||||
|
/// <returns>True if the first byte array starts with the second, false otherwise</returns>
|
||||||
|
public static bool StartsWith(this byte[] arr1, byte[] arr2, bool exact = false)
|
||||||
|
{
|
||||||
|
// If we have any invalid inputs, we return false
|
||||||
|
if (arr1 == null || arr2 == null
|
||||||
|
|| arr1.Length == 0 || arr2.Length == 0
|
||||||
|
|| arr2.Length > arr1.Length
|
||||||
|
|| (exact && arr1.Length != arr2.Length))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Otherwise, loop through and see
|
||||||
|
for (int i = 0; i < arr2.Length; i++)
|
||||||
|
{
|
||||||
|
if (arr1[i] != arr2[i])
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,9 +5,9 @@ using System.Linq;
|
|||||||
using System.Xml.Serialization;
|
using System.Xml.Serialization;
|
||||||
|
|
||||||
using SabreTools.Core;
|
using SabreTools.Core;
|
||||||
|
using SabreTools.Core.Tools;
|
||||||
using SabreTools.DatFiles.Formats;
|
using SabreTools.DatFiles.Formats;
|
||||||
using SabreTools.DatItems;
|
using SabreTools.DatItems;
|
||||||
using SabreTools.IO;
|
|
||||||
using SabreTools.Logging;
|
using SabreTools.Logging;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
|
|
||||||
@@ -467,7 +467,7 @@ namespace SabreTools.DatFiles
|
|||||||
// We can only write out if there's a SHA-1
|
// We can only write out if there's a SHA-1
|
||||||
if (!string.IsNullOrWhiteSpace(disk.SHA1))
|
if (!string.IsNullOrWhiteSpace(disk.SHA1))
|
||||||
{
|
{
|
||||||
name = PathExtensions.GetDepotPath(disk.SHA1, Header.OutputDepot.Depth).Replace('\\', '/');
|
name = Utilities.GetDepotPath(disk.SHA1, Header.OutputDepot.Depth).Replace('\\', '/');
|
||||||
item.SetFields(new Dictionary<Field, string> { [Field.DatItem_Name] = $"{pre}{name}{post}" } );
|
item.SetFields(new Dictionary<Field, string> { [Field.DatItem_Name] = $"{pre}{name}{post}" } );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -478,7 +478,7 @@ namespace SabreTools.DatFiles
|
|||||||
// We can only write out if there's a SHA-1
|
// We can only write out if there's a SHA-1
|
||||||
if (!string.IsNullOrWhiteSpace(media.SHA1))
|
if (!string.IsNullOrWhiteSpace(media.SHA1))
|
||||||
{
|
{
|
||||||
name = PathExtensions.GetDepotPath(media.SHA1, Header.OutputDepot.Depth).Replace('\\', '/');
|
name = Utilities.GetDepotPath(media.SHA1, Header.OutputDepot.Depth).Replace('\\', '/');
|
||||||
item.SetFields(new Dictionary<Field, string> { [Field.DatItem_Name] = $"{pre}{name}{post}" });
|
item.SetFields(new Dictionary<Field, string> { [Field.DatItem_Name] = $"{pre}{name}{post}" });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -489,7 +489,7 @@ namespace SabreTools.DatFiles
|
|||||||
// We can only write out if there's a SHA-1
|
// We can only write out if there's a SHA-1
|
||||||
if (!string.IsNullOrWhiteSpace(rom.SHA1))
|
if (!string.IsNullOrWhiteSpace(rom.SHA1))
|
||||||
{
|
{
|
||||||
name = PathExtensions.GetDepotPath(rom.SHA1, Header.OutputDepot.Depth).Replace('\\', '/');
|
name = Utilities.GetDepotPath(rom.SHA1, Header.OutputDepot.Depth).Replace('\\', '/');
|
||||||
item.SetFields(new Dictionary<Field, string> { [Field.DatItem_Name] = $"{pre}{name}{post}" });
|
item.SetFields(new Dictionary<Field, string> { [Field.DatItem_Name] = $"{pre}{name}{post}" });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ namespace SabreTools.DatFiles
|
|||||||
Hash hashes = Hash.Standard)
|
Hash hashes = Hash.Standard)
|
||||||
{
|
{
|
||||||
// Clean the temp directory path
|
// Clean the temp directory path
|
||||||
Globals.TempDir = DirectoryExtensions.Ensure(Globals.TempDir, temp: true);
|
Globals.TempDir = Globals.TempDir.Ensure(temp: true);
|
||||||
|
|
||||||
// Set the progress variables
|
// Set the progress variables
|
||||||
long totalSize = 0;
|
long totalSize = 0;
|
||||||
@@ -269,7 +269,7 @@ namespace SabreTools.DatFiles
|
|||||||
if (datFile.Header.OutputDepot?.IsActive == true)
|
if (datFile.Header.OutputDepot?.IsActive == true)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
List<string> empties = DirectoryExtensions.ListEmpty(basePath);
|
List<string> empties = basePath.ListEmpty();
|
||||||
Parallel.ForEach(empties, Globals.ParallelOptions, dir =>
|
Parallel.ForEach(empties, Globals.ParallelOptions, dir =>
|
||||||
{
|
{
|
||||||
// Get the full path for the directory
|
// Get the full path for the directory
|
||||||
|
|||||||
@@ -1058,10 +1058,10 @@ namespace SabreTools.DatFiles
|
|||||||
/// <returns>String containing the new filename</returns>
|
/// <returns>String containing the new filename</returns>
|
||||||
private string CreateOutFileNamesHelper(string outDir, string extension, bool overwrite)
|
private string CreateOutFileNamesHelper(string outDir, string extension, bool overwrite)
|
||||||
{
|
{
|
||||||
string filename = (string.IsNullOrWhiteSpace(FileName) ? Description : FileName);
|
string filename = string.IsNullOrWhiteSpace(FileName) ? Description : FileName;
|
||||||
|
|
||||||
// Strip off the extension if it's a holdover from the DAT
|
// Strip off the extension if it's a holdover from the DAT
|
||||||
if (PathExtensions.HasValidDatExtension(filename))
|
if (Parser.HasValidDatExtension(filename))
|
||||||
filename = Path.GetFileNameWithoutExtension(filename);
|
filename = Path.GetFileNameWithoutExtension(filename);
|
||||||
|
|
||||||
string outfile = $"{outDir}{filename}{extension}";
|
string outfile = $"{outDir}{filename}{extension}";
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ namespace SabreTools.DatFiles.Formats
|
|||||||
public override void ParseFile(string filename, int indexId, bool keep, bool throwOnError = false)
|
public override void ParseFile(string filename, int indexId, bool keep, bool throwOnError = false)
|
||||||
{
|
{
|
||||||
// Open a file reader
|
// Open a file reader
|
||||||
Encoding enc = FileExtensions.GetEncoding(filename);
|
Encoding enc = filename.GetEncoding();
|
||||||
SeparatedValueReader svr = new SeparatedValueReader(File.OpenRead(filename), enc)
|
SeparatedValueReader svr = new SeparatedValueReader(File.OpenRead(filename), enc)
|
||||||
{
|
{
|
||||||
Header = true,
|
Header = true,
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ namespace SabreTools.DatFiles.Formats
|
|||||||
public override void ParseFile(string filename, int indexId, bool keep, bool throwOnError = false)
|
public override void ParseFile(string filename, int indexId, bool keep, bool throwOnError = false)
|
||||||
{
|
{
|
||||||
// Open a file reader
|
// Open a file reader
|
||||||
Encoding enc = FileExtensions.GetEncoding(filename);
|
Encoding enc = filename.GetEncoding();
|
||||||
ClrMameProReader cmpr = new ClrMameProReader(File.OpenRead(filename), enc)
|
ClrMameProReader cmpr = new ClrMameProReader(File.OpenRead(filename), enc)
|
||||||
{
|
{
|
||||||
DosCenter = false,
|
DosCenter = false,
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ namespace SabreTools.DatFiles.Formats
|
|||||||
public override void ParseFile(string filename, int indexId, bool keep, bool throwOnError = false)
|
public override void ParseFile(string filename, int indexId, bool keep, bool throwOnError = false)
|
||||||
{
|
{
|
||||||
// Open a file reader
|
// Open a file reader
|
||||||
Encoding enc = FileExtensions.GetEncoding(filename);
|
Encoding enc = filename.GetEncoding();
|
||||||
ClrMameProReader cmpr = new ClrMameProReader(File.OpenRead(filename), enc)
|
ClrMameProReader cmpr = new ClrMameProReader(File.OpenRead(filename), enc)
|
||||||
{
|
{
|
||||||
DosCenter = true
|
DosCenter = true
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ namespace SabreTools.DatFiles.Formats
|
|||||||
public override void ParseFile(string filename, int indexId, bool keep, bool throwOnError = false)
|
public override void ParseFile(string filename, int indexId, bool keep, bool throwOnError = false)
|
||||||
{
|
{
|
||||||
// Open a file reader
|
// Open a file reader
|
||||||
Encoding enc = FileExtensions.GetEncoding(filename);
|
Encoding enc = filename.GetEncoding();
|
||||||
SeparatedValueReader svr = new SeparatedValueReader(File.OpenRead(filename), enc)
|
SeparatedValueReader svr = new SeparatedValueReader(File.OpenRead(filename), enc)
|
||||||
{
|
{
|
||||||
Header = false,
|
Header = false,
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ namespace SabreTools.DatFiles.Formats
|
|||||||
public override void ParseFile(string filename, int indexId, bool keep, bool throwOnError = false)
|
public override void ParseFile(string filename, int indexId, bool keep, bool throwOnError = false)
|
||||||
{
|
{
|
||||||
// Open a file reader
|
// Open a file reader
|
||||||
Encoding enc = FileExtensions.GetEncoding(filename);
|
Encoding enc = filename.GetEncoding();
|
||||||
StreamReader sr = new StreamReader(File.OpenRead(filename), enc);
|
StreamReader sr = new StreamReader(File.OpenRead(filename), enc);
|
||||||
|
|
||||||
while (!sr.EndOfStream)
|
while (!sr.EndOfStream)
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ namespace SabreTools.DatFiles.Formats
|
|||||||
public override void ParseFile(string filename, int indexId, bool keep, bool throwOnError = false)
|
public override void ParseFile(string filename, int indexId, bool keep, bool throwOnError = false)
|
||||||
{
|
{
|
||||||
// Open a file reader
|
// Open a file reader
|
||||||
Encoding enc = FileExtensions.GetEncoding(filename);
|
Encoding enc = filename.GetEncoding();
|
||||||
StreamReader sr = new StreamReader(File.OpenRead(filename), enc);
|
StreamReader sr = new StreamReader(File.OpenRead(filename), enc);
|
||||||
|
|
||||||
string gamename = string.Empty;
|
string gamename = string.Empty;
|
||||||
|
|||||||
@@ -898,7 +898,7 @@ namespace SabreTools.DatFiles.Formats
|
|||||||
if (datItem.ItemType == ItemType.Rom)
|
if (datItem.ItemType == ItemType.Rom)
|
||||||
{
|
{
|
||||||
var rom = datItem as Rom;
|
var rom = datItem as Rom;
|
||||||
string tempext = "." + PathExtensions.GetNormalizedExtension(rom.Name);
|
string tempext = "." + rom.Name.GetNormalizedExtension();
|
||||||
|
|
||||||
xtw.WriteStartElement("files");
|
xtw.WriteStartElement("files");
|
||||||
if (!string.IsNullOrWhiteSpace(rom.CRC))
|
if (!string.IsNullOrWhiteSpace(rom.CRC))
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ namespace SabreTools.DatFiles.Formats
|
|||||||
public override void ParseFile(string filename, int indexId, bool keep, bool throwOnError = false)
|
public override void ParseFile(string filename, int indexId, bool keep, bool throwOnError = false)
|
||||||
{
|
{
|
||||||
// Open a file reader
|
// Open a file reader
|
||||||
Encoding enc = FileExtensions.GetEncoding(filename);
|
Encoding enc = filename.GetEncoding();
|
||||||
SeparatedValueReader svr = new SeparatedValueReader(File.OpenRead(filename), enc)
|
SeparatedValueReader svr = new SeparatedValueReader(File.OpenRead(filename), enc)
|
||||||
{
|
{
|
||||||
Header = true,
|
Header = true,
|
||||||
|
|||||||
@@ -1369,13 +1369,13 @@ namespace SabreTools.DatFiles
|
|||||||
reportName = "report";
|
reportName = "report";
|
||||||
|
|
||||||
// Get the proper output directory name
|
// Get the proper output directory name
|
||||||
outDir = DirectoryExtensions.Ensure(outDir);
|
outDir = outDir.Ensure();
|
||||||
|
|
||||||
// Get the dictionary of desired output report names
|
// Get the dictionary of desired output report names
|
||||||
Dictionary<StatReportFormat, string> outputs = CreateOutStatsNames(outDir, statDatFormat, reportName);
|
Dictionary<StatReportFormat, string> outputs = CreateOutStatsNames(outDir, statDatFormat, reportName);
|
||||||
|
|
||||||
// Make sure we have all files and then order them
|
// Make sure we have all files and then order them
|
||||||
List<ParentablePath> files = DirectoryExtensions.GetFilesOnly(inputs);
|
List<ParentablePath> files = PathTool.GetFilesOnly(inputs);
|
||||||
files = files
|
files = files
|
||||||
.OrderBy(i => Path.GetDirectoryName(i.CurrentPath))
|
.OrderBy(i => Path.GetDirectoryName(i.CurrentPath))
|
||||||
.ThenBy(i => Path.GetFileName(i.CurrentPath))
|
.ThenBy(i => Path.GetFileName(i.CurrentPath))
|
||||||
|
|||||||
@@ -78,7 +78,7 @@ namespace SabreTools.DatFiles
|
|||||||
string currentPath = input.CurrentPath;
|
string currentPath = input.CurrentPath;
|
||||||
|
|
||||||
// Check the file extension first as a safeguard
|
// Check the file extension first as a safeguard
|
||||||
if (!PathExtensions.HasValidDatExtension(currentPath))
|
if (!HasValidDatExtension(currentPath))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// If the output filename isn't set already, get the internal filename
|
// If the output filename isn't set already, get the internal filename
|
||||||
@@ -105,6 +105,39 @@ namespace SabreTools.DatFiles
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Get if the given path has a valid DAT extension
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="path">Path to check</param>
|
||||||
|
/// <returns>True if the extension is valid, false otherwise</returns>
|
||||||
|
public static bool HasValidDatExtension(string path)
|
||||||
|
{
|
||||||
|
// Get the extension from the path, if possible
|
||||||
|
string ext = path.GetNormalizedExtension();
|
||||||
|
|
||||||
|
// Check against the list of known DAT extensions
|
||||||
|
switch (ext)
|
||||||
|
{
|
||||||
|
case "csv":
|
||||||
|
case "dat":
|
||||||
|
case "json":
|
||||||
|
case "md5":
|
||||||
|
case "ripemd160":
|
||||||
|
case "sfv":
|
||||||
|
case "sha1":
|
||||||
|
case "sha256":
|
||||||
|
case "sha384":
|
||||||
|
case "sha512":
|
||||||
|
case "ssv":
|
||||||
|
case "tsv":
|
||||||
|
case "txt":
|
||||||
|
case "xml":
|
||||||
|
return true;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Get what type of DAT the input file is
|
/// Get what type of DAT the input file is
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -113,11 +146,11 @@ namespace SabreTools.DatFiles
|
|||||||
private static DatFormat GetDatFormat(string filename)
|
private static DatFormat GetDatFormat(string filename)
|
||||||
{
|
{
|
||||||
// Limit the output formats based on extension
|
// Limit the output formats based on extension
|
||||||
if (!PathExtensions.HasValidDatExtension(filename))
|
if (!HasValidDatExtension(filename))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
// Get the extension from the filename
|
// Get the extension from the filename
|
||||||
string ext = PathExtensions.GetNormalizedExtension(filename);
|
string ext = filename.GetNormalizedExtension();
|
||||||
|
|
||||||
// Check if file exists
|
// Check if file exists
|
||||||
if (!File.Exists(filename))
|
if (!File.Exists(filename))
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ using System.Linq;
|
|||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
using SabreTools.Core;
|
using SabreTools.Core;
|
||||||
|
using SabreTools.Core.Tools;
|
||||||
using SabreTools.DatItems;
|
using SabreTools.DatItems;
|
||||||
using SabreTools.FileTypes;
|
using SabreTools.FileTypes;
|
||||||
using SabreTools.IO;
|
using SabreTools.IO;
|
||||||
@@ -54,7 +55,7 @@ namespace SabreTools.DatFiles
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Check that the output directory exists
|
// Check that the output directory exists
|
||||||
outDir = DirectoryExtensions.Ensure(outDir, create: true);
|
outDir = outDir.Ensure(create: true);
|
||||||
|
|
||||||
// Now we want to get forcepack flag if it's not overridden
|
// Now we want to get forcepack flag if it's not overridden
|
||||||
if (outputFormat == OutputFormat.Folder && datFile.Header.ForcePacking != PackingFlag.None)
|
if (outputFormat == OutputFormat.Folder && datFile.Header.ForcePacking != PackingFlag.None)
|
||||||
@@ -102,7 +103,7 @@ namespace SabreTools.DatFiles
|
|||||||
logger.User($"Checking hash '{hash}'");
|
logger.User($"Checking hash '{hash}'");
|
||||||
|
|
||||||
// Get the extension path for the hash
|
// Get the extension path for the hash
|
||||||
string subpath = PathExtensions.GetDepotPath(hash, datFile.Header.InputDepot.Depth);
|
string subpath = Utilities.GetDepotPath(hash, datFile.Header.InputDepot.Depth);
|
||||||
|
|
||||||
// Find the first depot that includes the hash
|
// Find the first depot that includes the hash
|
||||||
string foundpath = null;
|
string foundpath = null;
|
||||||
@@ -542,7 +543,7 @@ namespace SabreTools.DatFiles
|
|||||||
// Get the proper output path
|
// Get the proper output path
|
||||||
string sha1 = (datItem as Rom).SHA1 ?? string.Empty;
|
string sha1 = (datItem as Rom).SHA1 ?? string.Empty;
|
||||||
if (outputFormat == OutputFormat.TorrentGzipRomba)
|
if (outputFormat == OutputFormat.TorrentGzipRomba)
|
||||||
outDir = Path.Combine(outDir, PathExtensions.GetDepotPath(sha1, datFile.Header.OutputDepot.Depth));
|
outDir = Path.Combine(outDir, Utilities.GetDepotPath(sha1, datFile.Header.OutputDepot.Depth));
|
||||||
else
|
else
|
||||||
outDir = Path.Combine(outDir, sha1 + ".gz");
|
outDir = Path.Combine(outDir, sha1 + ".gz");
|
||||||
|
|
||||||
@@ -586,7 +587,7 @@ namespace SabreTools.DatFiles
|
|||||||
// Get the proper output path
|
// Get the proper output path
|
||||||
string sha1 = (datItem as Rom).SHA1 ?? string.Empty;
|
string sha1 = (datItem as Rom).SHA1 ?? string.Empty;
|
||||||
if (outputFormat == OutputFormat.TorrentXZRomba)
|
if (outputFormat == OutputFormat.TorrentXZRomba)
|
||||||
outDir = Path.Combine(outDir, PathExtensions.GetDepotPath(sha1, datFile.Header.OutputDepot.Depth)).Replace(".gz", ".xz");
|
outDir = Path.Combine(outDir, Utilities.GetDepotPath(sha1, datFile.Header.OutputDepot.Depth)).Replace(".gz", ".xz");
|
||||||
else
|
else
|
||||||
outDir = Path.Combine(outDir, sha1 + ".xz");
|
outDir = Path.Combine(outDir, sha1 + ".xz");
|
||||||
|
|
||||||
|
|||||||
@@ -63,11 +63,11 @@ namespace SabreTools.DatFiles
|
|||||||
List<DatItem> items = datFile.Items[key];
|
List<DatItem> items = datFile.Items[key];
|
||||||
foreach (DatItem item in items)
|
foreach (DatItem item in items)
|
||||||
{
|
{
|
||||||
if (newExtA.Contains(PathExtensions.GetNormalizedExtension(item.GetName() ?? string.Empty)))
|
if (newExtA.Contains((item.GetName() ?? string.Empty).GetNormalizedExtension()))
|
||||||
{
|
{
|
||||||
extADat.Items.Add(key, item);
|
extADat.Items.Add(key, item);
|
||||||
}
|
}
|
||||||
else if (newExtB.Contains(PathExtensions.GetNormalizedExtension(item.GetName() ?? string.Empty)))
|
else if (newExtB.Contains((item.GetName() ?? string.Empty).GetNormalizedExtension()))
|
||||||
{
|
{
|
||||||
extBDat.Items.Add(key, item);
|
extBDat.Items.Add(key, item);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,9 +3,9 @@ using System.IO;
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
|
||||||
using SabreTools.Core;
|
using SabreTools.Core;
|
||||||
|
using SabreTools.Core.Tools;
|
||||||
using SabreTools.DatItems;
|
using SabreTools.DatItems;
|
||||||
using SabreTools.FileTypes;
|
using SabreTools.FileTypes;
|
||||||
using SabreTools.IO;
|
|
||||||
using SabreTools.Logging;
|
using SabreTools.Logging;
|
||||||
|
|
||||||
// This file represents all methods related to verifying with a DatFile
|
// This file represents all methods related to verifying with a DatFile
|
||||||
@@ -64,7 +64,7 @@ namespace SabreTools.DatFiles
|
|||||||
logger.User($"Checking hash '{hash}'");
|
logger.User($"Checking hash '{hash}'");
|
||||||
|
|
||||||
// Get the extension path for the hash
|
// Get the extension path for the hash
|
||||||
string subpath = PathExtensions.GetDepotPath(hash, datFile.Header.InputDepot.Depth);
|
string subpath = Utilities.GetDepotPath(hash, datFile.Header.InputDepot.Depth);
|
||||||
|
|
||||||
// Find the first depot that includes the hash
|
// Find the first depot that includes the hash
|
||||||
string foundpath = null;
|
string foundpath = null;
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ namespace SabreTools.DatFiles
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Ensure the output directory is set and created
|
// Ensure the output directory is set and created
|
||||||
outDir = DirectoryExtensions.Ensure(outDir, create: true);
|
outDir = outDir.Ensure(create: true);
|
||||||
|
|
||||||
// If the DAT has no output format, default to XML
|
// If the DAT has no output format, default to XML
|
||||||
if (datFile.Header.DatFormat == 0)
|
if (datFile.Header.DatFormat == 0)
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
|
||||||
|
using SabreTools.Core.Tools;
|
||||||
using SabreTools.IO;
|
using SabreTools.IO;
|
||||||
using SabreTools.FileTypes.Aaru;
|
using SabreTools.FileTypes.Aaru;
|
||||||
|
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ using System.Linq;
|
|||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
using SabreTools.Core;
|
using SabreTools.Core;
|
||||||
|
using SabreTools.Core.Tools;
|
||||||
using SabreTools.IO;
|
using SabreTools.IO;
|
||||||
using SabreTools.Logging;
|
using SabreTools.Logging;
|
||||||
using SabreTools.Skippers;
|
using SabreTools.Skippers;
|
||||||
@@ -207,7 +208,7 @@ namespace SabreTools.FileTypes
|
|||||||
return outFileType;
|
return outFileType;
|
||||||
|
|
||||||
// First line of defense is going to be the extension, for better or worse
|
// First line of defense is going to be the extension, for better or worse
|
||||||
if (!PathExtensions.HasValidArchiveExtension(input))
|
if (!HasValidArchiveExtension(input))
|
||||||
return outFileType;
|
return outFileType;
|
||||||
|
|
||||||
// Read the first bytes of the file and get the magic number
|
// Read the first bytes of the file and get the magic number
|
||||||
@@ -451,6 +452,48 @@ namespace SabreTools.FileTypes
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Get if the given path has a valid DAT extension
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="path">Path to check</param>
|
||||||
|
/// <returns>True if the extension is valid, false otherwise</returns>
|
||||||
|
private static bool HasValidArchiveExtension(string path)
|
||||||
|
{
|
||||||
|
// Get the extension from the path, if possible
|
||||||
|
string ext = path.GetNormalizedExtension();
|
||||||
|
|
||||||
|
// Check against the list of known archive extensions
|
||||||
|
switch (ext)
|
||||||
|
{
|
||||||
|
// Aaruformat
|
||||||
|
case "aaru":
|
||||||
|
case "aaruf":
|
||||||
|
case "aaruformat":
|
||||||
|
case "aif":
|
||||||
|
case "dicf":
|
||||||
|
|
||||||
|
// Archives
|
||||||
|
case "7z":
|
||||||
|
case "gz":
|
||||||
|
case "lzma":
|
||||||
|
case "rar":
|
||||||
|
case "rev":
|
||||||
|
case "r00":
|
||||||
|
case "r01":
|
||||||
|
case "tar":
|
||||||
|
case "tgz":
|
||||||
|
case "tlz":
|
||||||
|
case "zip":
|
||||||
|
case "zipx":
|
||||||
|
|
||||||
|
// CHD
|
||||||
|
case "chd":
|
||||||
|
return true;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -201,7 +201,7 @@ namespace SabreTools.FileTypes
|
|||||||
Directory.CreateDirectory(outDir);
|
Directory.CreateDirectory(outDir);
|
||||||
|
|
||||||
// Get all files from the input directory
|
// Get all files from the input directory
|
||||||
List<string> files = DirectoryExtensions.GetFilesOrdered(this.Filename);
|
List<string> files = PathTool.GetFilesOrdered(this.Filename);
|
||||||
|
|
||||||
// Now sort through to find the first file that matches
|
// Now sort through to find the first file that matches
|
||||||
string match = files.Where(s => s.EndsWith(entryName)).FirstOrDefault();
|
string match = files.Where(s => s.EndsWith(entryName)).FirstOrDefault();
|
||||||
@@ -239,7 +239,7 @@ namespace SabreTools.FileTypes
|
|||||||
Directory.CreateDirectory(this.Filename);
|
Directory.CreateDirectory(this.Filename);
|
||||||
|
|
||||||
// Get all files from the input directory
|
// Get all files from the input directory
|
||||||
List<string> files = DirectoryExtensions.GetFilesOrdered(this.Filename);
|
List<string> files = PathTool.GetFilesOrdered(this.Filename);
|
||||||
|
|
||||||
// Now sort through to find the first file that matches
|
// Now sort through to find the first file that matches
|
||||||
string match = files.Where(s => s.EndsWith(entryName)).FirstOrDefault();
|
string match = files.Where(s => s.EndsWith(entryName)).FirstOrDefault();
|
||||||
@@ -296,7 +296,7 @@ namespace SabreTools.FileTypes
|
|||||||
/// <returns>List of empty folders in the folder</returns>
|
/// <returns>List of empty folders in the folder</returns>
|
||||||
public virtual List<string> GetEmptyFolders()
|
public virtual List<string> GetEmptyFolders()
|
||||||
{
|
{
|
||||||
return DirectoryExtensions.ListEmpty(this.Filename);
|
return this.Filename.ListEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|||||||
@@ -445,7 +445,7 @@ namespace SabreTools.FileTypes
|
|||||||
baseFile = GetInfo(inputStream, keepReadOpen: true);
|
baseFile = GetInfo(inputStream, keepReadOpen: true);
|
||||||
|
|
||||||
// Get the output file name
|
// Get the output file name
|
||||||
string outfile = Path.Combine(outDir, PathExtensions.GetDepotPath(Utilities.ByteArrayToString(baseFile.SHA1), Depth));
|
string outfile = Path.Combine(outDir, Utilities.GetDepotPath(Utilities.ByteArrayToString(baseFile.SHA1), Depth));
|
||||||
|
|
||||||
// Check to see if the folder needs to be created
|
// Check to see if the folder needs to be created
|
||||||
if (!Directory.Exists(Path.GetDirectoryName(outfile)))
|
if (!Directory.Exists(Path.GetDirectoryName(outfile)))
|
||||||
|
|||||||
@@ -337,7 +337,7 @@ namespace SabreTools.FileTypes
|
|||||||
baseFile = GetInfo(inputStream, keepReadOpen: true);
|
baseFile = GetInfo(inputStream, keepReadOpen: true);
|
||||||
|
|
||||||
// Get the output file name
|
// Get the output file name
|
||||||
string outfile = Path.Combine(outDir, PathExtensions.GetDepotPath(Utilities.ByteArrayToString(baseFile.SHA1), Depth));
|
string outfile = Path.Combine(outDir, Utilities.GetDepotPath(Utilities.ByteArrayToString(baseFile.SHA1), Depth));
|
||||||
outfile = outfile.Replace(".gz", ".xz");
|
outfile = outfile.Replace(".gz", ".xz");
|
||||||
|
|
||||||
// Check to see if the folder needs to be created
|
// Check to see if the folder needs to be created
|
||||||
|
|||||||
@@ -1,77 +0,0 @@
|
|||||||
using System.IO;
|
|
||||||
using System.Text;
|
|
||||||
|
|
||||||
namespace SabreTools.IO
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Extensions to File functionality
|
|
||||||
/// </summary>
|
|
||||||
public static class FileExtensions
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Determines a text file's encoding by analyzing its byte order mark (BOM).
|
|
||||||
/// Defaults to ASCII when detection of the text file's endianness fails.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="filename">The text file to analyze.</param>
|
|
||||||
/// <returns>The detected encoding.</returns>
|
|
||||||
/// <link>http://stackoverflow.com/questions/3825390/effective-way-to-find-any-files-encoding</link>
|
|
||||||
public static Encoding GetEncoding(string filename)
|
|
||||||
{
|
|
||||||
if (!File.Exists(filename))
|
|
||||||
return Encoding.Default;
|
|
||||||
|
|
||||||
// Try to open the file
|
|
||||||
try
|
|
||||||
{
|
|
||||||
FileStream file = File.OpenRead(filename);
|
|
||||||
if (file == null)
|
|
||||||
return Encoding.Default;
|
|
||||||
|
|
||||||
// Read the BOM
|
|
||||||
var bom = new byte[4];
|
|
||||||
file.Read(bom, 0, 4);
|
|
||||||
file.Dispose();
|
|
||||||
|
|
||||||
// Analyze the BOM
|
|
||||||
if (bom[0] == 0x2b && bom[1] == 0x2f && bom[2] == 0x76) return Encoding.UTF7;
|
|
||||||
if (bom[0] == 0xef && bom[1] == 0xbb && bom[2] == 0xbf) return Encoding.UTF8;
|
|
||||||
if (bom[0] == 0xff && bom[1] == 0xfe) return Encoding.Unicode; //UTF-16LE
|
|
||||||
if (bom[0] == 0xfe && bom[1] == 0xff) return Encoding.BigEndianUnicode; //UTF-16BE
|
|
||||||
if (bom[0] == 0 && bom[1] == 0 && bom[2] == 0xfe && bom[3] == 0xff) return Encoding.UTF32;
|
|
||||||
return Encoding.Default;
|
|
||||||
}
|
|
||||||
catch
|
|
||||||
{
|
|
||||||
return Encoding.Default;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Returns if the first byte array starts with the second array
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="arr1">First byte array to compare</param>
|
|
||||||
/// <param name="arr2">Second byte array to compare</param>
|
|
||||||
/// <param name="exact">True if the input arrays should match exactly, false otherwise (default)</param>
|
|
||||||
/// <returns>True if the first byte array starts with the second, false otherwise</returns>
|
|
||||||
public static bool StartsWith(this byte[] arr1, byte[] arr2, bool exact = false)
|
|
||||||
{
|
|
||||||
// If we have any invalid inputs, we return false
|
|
||||||
if (arr1 == null || arr2 == null
|
|
||||||
|| arr1.Length == 0 || arr2.Length == 0
|
|
||||||
|| arr2.Length > arr1.Length
|
|
||||||
|| (exact && arr1.Length != arr2.Length))
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Otherwise, loop through and see
|
|
||||||
for (int i = 0; i < arr2.Length; i++)
|
|
||||||
{
|
|
||||||
if (arr1[i] != arr2[i])
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
132
SabreTools.IO/IOExtensions.cs
Normal file
132
SabreTools.IO/IOExtensions.cs
Normal file
@@ -0,0 +1,132 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace SabreTools.IO
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Methods around path operations
|
||||||
|
/// </summary>
|
||||||
|
public static class IOExtensions
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Ensure the output directory is a proper format and can be created
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="dir">Directory to check</param>
|
||||||
|
/// <param name="create">True if the directory should be created, false otherwise (default)</param>
|
||||||
|
/// <param name="temp">True if this is a temp directory, false otherwise</param>
|
||||||
|
/// <returns>Full path to the directory</returns>
|
||||||
|
public static string Ensure(this string dir, bool create = false, bool temp = false)
|
||||||
|
{
|
||||||
|
// If the output directory is invalid
|
||||||
|
if (string.IsNullOrWhiteSpace(dir))
|
||||||
|
{
|
||||||
|
if (temp)
|
||||||
|
dir = Path.GetTempPath();
|
||||||
|
else
|
||||||
|
dir = Environment.CurrentDirectory;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the full path for the output directory
|
||||||
|
dir = Path.GetFullPath(dir);
|
||||||
|
|
||||||
|
// If we're creating the output folder, do so
|
||||||
|
if (create)
|
||||||
|
Directory.CreateDirectory(dir);
|
||||||
|
|
||||||
|
return dir;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Determines a text file's encoding by analyzing its byte order mark (BOM).
|
||||||
|
/// Defaults to ASCII when detection of the text file's endianness fails.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="filename">The text file to analyze.</param>
|
||||||
|
/// <returns>The detected encoding.</returns>
|
||||||
|
/// <link>http://stackoverflow.com/questions/3825390/effective-way-to-find-any-files-encoding</link>
|
||||||
|
public static Encoding GetEncoding(this string filename)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrEmpty(filename))
|
||||||
|
return Encoding.Default;
|
||||||
|
|
||||||
|
if (!File.Exists(filename))
|
||||||
|
return Encoding.Default;
|
||||||
|
|
||||||
|
// Try to open the file
|
||||||
|
try
|
||||||
|
{
|
||||||
|
FileStream file = File.OpenRead(filename);
|
||||||
|
if (file == null)
|
||||||
|
return Encoding.Default;
|
||||||
|
|
||||||
|
// Read the BOM
|
||||||
|
var bom = new byte[4];
|
||||||
|
file.Read(bom, 0, 4);
|
||||||
|
file.Dispose();
|
||||||
|
|
||||||
|
// Analyze the BOM
|
||||||
|
if (bom[0] == 0x2b && bom[1] == 0x2f && bom[2] == 0x76) return Encoding.UTF7;
|
||||||
|
if (bom[0] == 0xef && bom[1] == 0xbb && bom[2] == 0xbf) return Encoding.UTF8;
|
||||||
|
if (bom[0] == 0xff && bom[1] == 0xfe) return Encoding.Unicode; //UTF-16LE
|
||||||
|
if (bom[0] == 0xfe && bom[1] == 0xff) return Encoding.BigEndianUnicode; //UTF-16BE
|
||||||
|
if (bom[0] == 0 && bom[1] == 0 && bom[2] == 0xfe && bom[3] == 0xff) return Encoding.UTF32;
|
||||||
|
return Encoding.Default;
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
return Encoding.Default;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Get the extension from the path, if possible
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="path">Path to get extension from</param>
|
||||||
|
/// <returns>Extension, if possible</returns>
|
||||||
|
public static string GetNormalizedExtension(this string path)
|
||||||
|
{
|
||||||
|
// Check null or empty first
|
||||||
|
if (string.IsNullOrWhiteSpace(path))
|
||||||
|
return null;
|
||||||
|
|
||||||
|
// Get the extension from the path, if possible
|
||||||
|
string ext = Path.GetExtension(path)?.ToLowerInvariant();
|
||||||
|
|
||||||
|
// Check if the extension is null or empty
|
||||||
|
if (string.IsNullOrWhiteSpace(ext))
|
||||||
|
return null;
|
||||||
|
|
||||||
|
// Make sure that extensions are valid
|
||||||
|
ext = ext.TrimStart('.');
|
||||||
|
|
||||||
|
return ext;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Get all empty folders within a root folder
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="root">Root directory to parse</param>
|
||||||
|
/// <returns>IEumerable containing all directories that are empty, an empty enumerable if the root is empty, null otherwise</returns>
|
||||||
|
public static List<string> ListEmpty(this string root)
|
||||||
|
{
|
||||||
|
// Check null or empty first
|
||||||
|
if (string.IsNullOrEmpty(root))
|
||||||
|
return null;
|
||||||
|
|
||||||
|
// Then, check if the root exists
|
||||||
|
if (!Directory.Exists(root))
|
||||||
|
return null;
|
||||||
|
|
||||||
|
// If it does and it is empty, return a blank enumerable
|
||||||
|
if (Directory.EnumerateFileSystemEntries(root, "*", SearchOption.AllDirectories).Count() == 0)
|
||||||
|
return new List<string>();
|
||||||
|
|
||||||
|
// Otherwise, get the complete list
|
||||||
|
return Directory.EnumerateDirectories(root, "*", SearchOption.AllDirectories)
|
||||||
|
.Where(dir => Directory.EnumerateFileSystemEntries(dir, "*", SearchOption.AllDirectories).Count() == 0)
|
||||||
|
.ToList();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -71,7 +71,7 @@ namespace SabreTools.IO
|
|||||||
public string GetOutputPath(string outDir, bool inplace)
|
public string GetOutputPath(string outDir, bool inplace)
|
||||||
{
|
{
|
||||||
// First, we need to ensure the output directory
|
// First, we need to ensure the output directory
|
||||||
outDir = DirectoryExtensions.Ensure(outDir);
|
outDir = outDir.Ensure();
|
||||||
|
|
||||||
// Check if we have a split path or not
|
// Check if we have a split path or not
|
||||||
bool splitpath = !string.IsNullOrWhiteSpace(ParentPath);
|
bool splitpath = !string.IsNullOrWhiteSpace(ParentPath);
|
||||||
|
|||||||
@@ -1,141 +0,0 @@
|
|||||||
using System.IO;
|
|
||||||
|
|
||||||
using SabreTools.Core;
|
|
||||||
|
|
||||||
namespace SabreTools.IO
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Extensions to Path functionality
|
|
||||||
/// </summary>
|
|
||||||
public static class PathExtensions
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Get the extension from the path, if possible
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="path">Path to get extension from</param>
|
|
||||||
/// <returns>Extension, if possible</returns>
|
|
||||||
public static string GetNormalizedExtension(string path)
|
|
||||||
{
|
|
||||||
// Check null or empty first
|
|
||||||
if (string.IsNullOrWhiteSpace(path))
|
|
||||||
return null;
|
|
||||||
|
|
||||||
// Get the extension from the path, if possible
|
|
||||||
string ext = Path.GetExtension(path)?.ToLowerInvariant();
|
|
||||||
|
|
||||||
// Check if the extension is null or empty
|
|
||||||
if (string.IsNullOrWhiteSpace(ext))
|
|
||||||
return null;
|
|
||||||
|
|
||||||
// Make sure that extensions are valid
|
|
||||||
ext = ext.TrimStart('.');
|
|
||||||
|
|
||||||
return ext;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Get a proper romba sub path
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="hash">SHA-1 hash to get the path for</param>
|
|
||||||
/// <param name="depth">Positive value representing the depth of the depot</param>
|
|
||||||
/// <returns>Subfolder path for the given hash</returns>
|
|
||||||
public static string GetDepotPath(string hash, int depth)
|
|
||||||
{
|
|
||||||
// If the hash isn't the right size, then we return null
|
|
||||||
if (hash.Length != Constants.SHA1Length)
|
|
||||||
return null;
|
|
||||||
|
|
||||||
// Cap the depth between 0 and 20, for now
|
|
||||||
if (depth < 0)
|
|
||||||
depth = 0;
|
|
||||||
else if (depth > Constants.SHA1ZeroBytes.Length)
|
|
||||||
depth = Constants.SHA1ZeroBytes.Length;
|
|
||||||
|
|
||||||
// Loop through and generate the subdirectory
|
|
||||||
string path = string.Empty;
|
|
||||||
for (int i = 0; i < depth; i++)
|
|
||||||
{
|
|
||||||
path += hash.Substring(i * 2, 2) + Path.DirectorySeparatorChar;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Now append the filename
|
|
||||||
path += $"{hash}.gz";
|
|
||||||
return path;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Get if the given path has a valid DAT extension
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="path">Path to check</param>
|
|
||||||
/// <returns>True if the extension is valid, false otherwise</returns>
|
|
||||||
public static bool HasValidArchiveExtension(string path)
|
|
||||||
{
|
|
||||||
// Get the extension from the path, if possible
|
|
||||||
string ext = GetNormalizedExtension(path);
|
|
||||||
|
|
||||||
// Check against the list of known archive extensions
|
|
||||||
switch (ext)
|
|
||||||
{
|
|
||||||
// Aaruformat
|
|
||||||
case "aaru":
|
|
||||||
case "aaruf":
|
|
||||||
case "aaruformat":
|
|
||||||
case "aif":
|
|
||||||
case "dicf":
|
|
||||||
|
|
||||||
// Archives
|
|
||||||
case "7z":
|
|
||||||
case "gz":
|
|
||||||
case "lzma":
|
|
||||||
case "rar":
|
|
||||||
case "rev":
|
|
||||||
case "r00":
|
|
||||||
case "r01":
|
|
||||||
case "tar":
|
|
||||||
case "tgz":
|
|
||||||
case "tlz":
|
|
||||||
case "zip":
|
|
||||||
case "zipx":
|
|
||||||
|
|
||||||
// CHD
|
|
||||||
case "chd":
|
|
||||||
return true;
|
|
||||||
default:
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Get if the given path has a valid DAT extension
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="path">Path to check</param>
|
|
||||||
/// <returns>True if the extension is valid, false otherwise</returns>
|
|
||||||
public static bool HasValidDatExtension(string path)
|
|
||||||
{
|
|
||||||
// Get the extension from the path, if possible
|
|
||||||
string ext = GetNormalizedExtension(path);
|
|
||||||
|
|
||||||
// Check against the list of known DAT extensions
|
|
||||||
switch (ext)
|
|
||||||
{
|
|
||||||
case "csv":
|
|
||||||
case "dat":
|
|
||||||
case "json":
|
|
||||||
case "md5":
|
|
||||||
case "ripemd160":
|
|
||||||
case "sfv":
|
|
||||||
case "sha1":
|
|
||||||
case "sha256":
|
|
||||||
case "sha384":
|
|
||||||
case "sha512":
|
|
||||||
case "ssv":
|
|
||||||
case "tsv":
|
|
||||||
case "txt":
|
|
||||||
case "xml":
|
|
||||||
return true;
|
|
||||||
default:
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,4 +1,3 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
@@ -8,65 +7,10 @@ using NaturalSort;
|
|||||||
namespace SabreTools.IO
|
namespace SabreTools.IO
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Extensions to Directory functionality
|
/// Methods around path operations
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static class DirectoryExtensions
|
public static class PathTool
|
||||||
{
|
{
|
||||||
/// <summary>
|
|
||||||
/// Cleans out the temporary directory
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="dir">Name of the directory to clean out</param>
|
|
||||||
public static void Clean(string dir)
|
|
||||||
{
|
|
||||||
foreach (string file in Directory.EnumerateFiles(dir, "*", SearchOption.TopDirectoryOnly))
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
if (File.Exists(file))
|
|
||||||
File.Delete(file);
|
|
||||||
}
|
|
||||||
catch { }
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (string subdir in Directory.EnumerateDirectories(dir, "*", SearchOption.TopDirectoryOnly))
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
if (Directory.Exists(subdir))
|
|
||||||
Directory.Delete(subdir);
|
|
||||||
}
|
|
||||||
catch { }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Ensure the output directory is a proper format and can be created
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="dir">Directory to check</param>
|
|
||||||
/// <param name="create">True if the directory should be created, false otherwise (default)</param>
|
|
||||||
/// <param name="temp">True if this is a temp directory, false otherwise</param>
|
|
||||||
/// <returns>Full path to the directory</returns>
|
|
||||||
public static string Ensure(string dir, bool create = false, bool temp = false)
|
|
||||||
{
|
|
||||||
// If the output directory is invalid
|
|
||||||
if (string.IsNullOrWhiteSpace(dir))
|
|
||||||
{
|
|
||||||
if (temp)
|
|
||||||
dir = Path.GetTempPath();
|
|
||||||
else
|
|
||||||
dir = Environment.CurrentDirectory;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get the full path for the output directory
|
|
||||||
dir = Path.GetFullPath(dir);
|
|
||||||
|
|
||||||
// If we're creating the output folder, do so
|
|
||||||
if (create)
|
|
||||||
Directory.CreateDirectory(dir);
|
|
||||||
|
|
||||||
return dir;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Retrieve a list of just directories from inputs
|
/// Retrieve a list of just directories from inputs
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -222,26 +166,5 @@ namespace SabreTools.IO
|
|||||||
// Return the new list
|
// Return the new list
|
||||||
return infiles;
|
return infiles;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Get all empty folders within a root folder
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="root">Root directory to parse</param>
|
|
||||||
/// <returns>IEumerable containing all directories that are empty, an empty enumerable if the root is empty, null otherwise</returns>
|
|
||||||
public static List<string> ListEmpty(string root)
|
|
||||||
{
|
|
||||||
// Check if the root exists first
|
|
||||||
if (!Directory.Exists(root))
|
|
||||||
return null;
|
|
||||||
|
|
||||||
// If it does and it is empty, return a blank enumerable
|
|
||||||
if (Directory.EnumerateFileSystemEntries(root, "*", SearchOption.AllDirectories).Count() == 0)
|
|
||||||
return new List<string>();
|
|
||||||
|
|
||||||
// Otherwise, get the complete list
|
|
||||||
return Directory.EnumerateDirectories(root, "*", SearchOption.AllDirectories)
|
|
||||||
.Where(dir => Directory.EnumerateFileSystemEntries(dir, "*", SearchOption.AllDirectories).Count() == 0)
|
|
||||||
.ToList();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -87,7 +87,7 @@ namespace SabreTools.Logging
|
|||||||
{
|
{
|
||||||
// Set and create the output
|
// Set and create the output
|
||||||
if (addDate)
|
if (addDate)
|
||||||
Filename = $"{Path.GetFileNameWithoutExtension(filename)} ({DateTime.Now:yyyy-MM-dd HH-mm-ss}).{PathExtensions.GetNormalizedExtension(filename)}";
|
Filename = $"{Path.GetFileNameWithoutExtension(filename)} ({DateTime.Now:yyyy-MM-dd HH-mm-ss}).{filename.GetNormalizedExtension()}";
|
||||||
else
|
else
|
||||||
Filename = filename;
|
Filename = filename;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -128,7 +128,7 @@ Reset the internal state: reset();";
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Get only files from inputs
|
// Get only files from inputs
|
||||||
List<ParentablePath> datFilePaths = DirectoryExtensions.GetFilesOnly(command.Arguments);
|
List<ParentablePath> datFilePaths = PathTool.GetFilesOnly(command.Arguments);
|
||||||
|
|
||||||
// Assume there could be multiple
|
// Assume there could be multiple
|
||||||
foreach (ParentablePath datFilePath in datFilePaths)
|
foreach (ParentablePath datFilePath in datFilePaths)
|
||||||
|
|||||||
@@ -46,7 +46,7 @@ The following systems have headers that this program can work with:
|
|||||||
bool nostore = GetBoolean(features, NoStoreHeaderValue);
|
bool nostore = GetBoolean(features, NoStoreHeaderValue);
|
||||||
|
|
||||||
// Get only files from the inputs
|
// Get only files from the inputs
|
||||||
List<ParentablePath> files = DirectoryExtensions.GetFilesOnly(Inputs);
|
List<ParentablePath> files = PathTool.GetFilesOnly(Inputs);
|
||||||
foreach (ParentablePath file in files)
|
foreach (ParentablePath file in files)
|
||||||
{
|
{
|
||||||
DetectTransformStore(file.CurrentPath, OutputDir, nostore);
|
DetectTransformStore(file.CurrentPath, OutputDir, nostore);
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ The following systems have headers that this program can work with:
|
|||||||
base.ProcessFeatures(features);
|
base.ProcessFeatures(features);
|
||||||
|
|
||||||
// Get only files from the inputs
|
// Get only files from the inputs
|
||||||
List<ParentablePath> files = DirectoryExtensions.GetFilesOnly(Inputs);
|
List<ParentablePath> files = PathTool.GetFilesOnly(Inputs);
|
||||||
foreach (ParentablePath file in files)
|
foreach (ParentablePath file in files)
|
||||||
{
|
{
|
||||||
RestoreHeader(file.CurrentPath, OutputDir);
|
RestoreHeader(file.CurrentPath, OutputDir);
|
||||||
|
|||||||
@@ -82,7 +82,7 @@ namespace SabreTools.Features
|
|||||||
|
|
||||||
// Get a list of files from the input datfiles
|
// Get a list of files from the input datfiles
|
||||||
var datfiles = GetList(features, DatListValue);
|
var datfiles = GetList(features, DatListValue);
|
||||||
var datfilePaths = DirectoryExtensions.GetFilesOnly(datfiles);
|
var datfilePaths = PathTool.GetFilesOnly(datfiles);
|
||||||
|
|
||||||
// If we are in individual mode, process each DAT on their own, appending the DAT name to the output dir
|
// If we are in individual mode, process each DAT on their own, appending the DAT name to the output dir
|
||||||
if (GetBoolean(features, IndividualValue))
|
if (GetBoolean(features, IndividualValue))
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ namespace SabreTools.Features
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
// Get only files from the inputs
|
// Get only files from the inputs
|
||||||
List<ParentablePath> files = DirectoryExtensions.GetFilesOnly(Inputs, appendparent: true);
|
List<ParentablePath> files = PathTool.GetFilesOnly(Inputs, appendparent: true);
|
||||||
|
|
||||||
// Loop over the input files
|
// Loop over the input files
|
||||||
foreach (ParentablePath file in files)
|
foreach (ParentablePath file in files)
|
||||||
|
|||||||
@@ -149,8 +149,8 @@ namespace SabreTools.Features
|
|||||||
updateFields = new List<Field>() { Field.DatItem_Name };
|
updateFields = new List<Field>() { Field.DatItem_Name };
|
||||||
|
|
||||||
// Ensure we only have files in the inputs
|
// Ensure we only have files in the inputs
|
||||||
List<ParentablePath> inputPaths = DirectoryExtensions.GetFilesOnly(Inputs, appendparent: true);
|
List<ParentablePath> inputPaths = PathTool.GetFilesOnly(Inputs, appendparent: true);
|
||||||
List<ParentablePath> basePaths = DirectoryExtensions.GetFilesOnly(GetList(features, BaseDatListValue));
|
List<ParentablePath> basePaths = PathTool.GetFilesOnly(GetList(features, BaseDatListValue));
|
||||||
|
|
||||||
// If we're in standard update mode, run through all of the inputs
|
// If we're in standard update mode, run through all of the inputs
|
||||||
if (updateMode == UpdateMode.None)
|
if (updateMode == UpdateMode.None)
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ namespace SabreTools.Features
|
|||||||
|
|
||||||
// Get a list of files from the input datfiles
|
// Get a list of files from the input datfiles
|
||||||
var datfiles = GetList(features, DatListValue);
|
var datfiles = GetList(features, DatListValue);
|
||||||
var datfilePaths = DirectoryExtensions.GetFilesOnly(datfiles);
|
var datfilePaths = PathTool.GetFilesOnly(datfiles);
|
||||||
|
|
||||||
// Get feature flags
|
// Get feature flags
|
||||||
TreatAsFile asFiles = GetTreatAsFiles(features);
|
TreatAsFile asFiles = GetTreatAsFiles(features);
|
||||||
|
|||||||
Reference in New Issue
Block a user