diff --git a/SabreTools.Helper/Objects/Headerer.cs b/SabreTools.Helper/Objects/Headerer.cs deleted file mode 100644 index 5dc38641..00000000 --- a/SabreTools.Helper/Objects/Headerer.cs +++ /dev/null @@ -1,229 +0,0 @@ -using Mono.Data.Sqlite; -using SabreTools.Helper; -using System; -using System.Collections.Generic; -using System.IO; - -namespace SabreTools -{ - /// - /// Entry class for the Deheader application - /// - public class Headerer - { - // Private instance variables - private List _inputs; - private bool _restore; - private string _outDir; - private Logger _logger; - - /// - /// Create a new Headerer object - /// - /// Input file or folder names - /// False if we're extracting headers (default), true if we're restoring them - /// Output directory to write new files to, blank defaults to rom folder - /// Logger object for file and console output - public Headerer(List inputs, bool restore, string outDir, Logger logger) - { - _inputs = inputs; - _restore = restore; - _outDir = outDir; - _logger = logger; - } - - /// - /// Extract and remove or replace headers - /// - /// True if it succeeded, false otherwise - public bool Process() - { - if (_outDir != "" && !Directory.Exists(_outDir)) - { - Directory.CreateDirectory(_outDir); - } - - bool success = true; - - foreach (string input in _inputs) - { - if (File.Exists(input)) - { - success &= ProcessHelper(input); - } - else if (Directory.Exists(input)) - { - foreach (string sub in Directory.EnumerateFiles(input, "*", SearchOption.AllDirectories)) - { - success &= ProcessHelper(sub); - } - } - } - - return success; - } - - /// - /// Intermediary to route the input file to the correct method(s) - /// - /// Input file name - /// True on success, false otherwise - private bool ProcessHelper(string input) - { - if (_restore) - { - return RestoreHeader(input); - } - else - { - return DetectSkipperAndTransform(input); - } - } - - /// - /// Detect header skipper compliance and create an output file - /// - /// Name of the file to be parsed - /// True if the output file was created, false otherwise - private bool DetectSkipperAndTransform(string file) - { - _logger.User("\nGetting skipper information for '" + file + "'"); - - // Then, if the file was headered, store it to the database - int headerSize = -1; - HeaderType type = Skippers.GetFileHeaderType(file, out headerSize, _logger); - - // If we have a valid HeaderType, remove the correct byte count - _logger.User("File has header: " + (type != HeaderType.None)); - if (type != HeaderType.None) - { - _logger.Log("Deteched header type: " + type); - - // Now take care of the header and new output file - string hstr = string.Empty; - BinaryReader br = new BinaryReader(File.OpenRead(file)); - - // Extract the header as a string for the database - byte[] hbin = br.ReadBytes(headerSize); - for (int i = 0; i < headerSize; i++) - { - hstr += BitConverter.ToString(new byte[] { hbin[i] }); - } - - br.Dispose(); - - // Then find an apply the exact rule to the file - SkipperRule rule = Skippers.MatchesSkipper(file, "", _logger); - - // If we have an empty rule, return false - if (rule.Tests == null || rule.Tests.Count == 0) - { - return false; - } - - // Otherwise, apply the rule to the file - string newfile = (_outDir == "" ? Path.GetFullPath(file) + ".new" : Path.Combine(_outDir, Path.GetFileName(file))); - Skippers.TransformFile(file, newfile, rule, _logger); - - // If the output file doesn't exist, return false - if (!File.Exists(newfile)) - { - return false; - } - - // Now add the information to the database if it's not already there - Rom rom = FileTools.GetSingleFileInfo(newfile); - AddHeaderToDatabase(hstr, rom.SHA1, type); - } - - return true; - } - - /// - /// Add a header to the database - /// - /// String representing the header bytes - /// SHA-1 of the deheadered file - /// HeaderType representing the detected header - private void AddHeaderToDatabase(string header, string SHA1, HeaderType type) - { - bool exists = false; - - // Open the database connection - SqliteConnection dbc = new SqliteConnection(Constants.HeadererConnectionString); - dbc.Open(); - - string query = @"SELECT * FROM data WHERE sha1='" + SHA1 + "' AND header='" + header + "'"; - SqliteCommand slc = new SqliteCommand(query, dbc); - SqliteDataReader sldr = slc.ExecuteReader(); - exists = sldr.HasRows; - - if (!exists) - { - query = @"INSERT INTO data (sha1, header, type) VALUES ('" + - SHA1 + "', " + - "'" + header + "', " + - "'" + type.ToString() + "')"; - slc = new SqliteCommand(query, dbc); - _logger.Log("Result of inserting header: " + slc.ExecuteNonQuery()); - } - - // Dispose of database objects - slc.Dispose(); - sldr.Dispose(); - dbc.Dispose(); - } - - /// - /// Detect and replace header(s) to the given file - /// - /// Name of the file to be parsed - /// True if a header was found and appended, false otherwise - private bool RestoreHeader(string file) - { - bool success = true; - - // First, get the SHA-1 hash of the file - Rom rom = FileTools.GetSingleFileInfo(file); - - // Then try to pull the corresponding headers from the database - string header = ""; - - // Open the database connection - SqliteConnection dbc = new SqliteConnection(Constants.HeadererConnectionString); - dbc.Open(); - - string query = @"SELECT header, type FROM data WHERE sha1='" + rom.SHA1 + "'"; - SqliteCommand slc = new SqliteCommand(query, dbc); - SqliteDataReader sldr = slc.ExecuteReader(); - - if (sldr.HasRows) - { - int sub = 0; - while (sldr.Read()) - { - _logger.Log("Found match with rom type " + sldr.GetString(1)); - header = sldr.GetString(0); - - _logger.User("Creating reheadered file: " + - (_outDir == "" ? Path.GetFullPath(file) + ".new" : Path.Combine(_outDir, Path.GetFileName(file))) + sub); - FileTools.AppendBytesToFile(file, - (_outDir == "" ? Path.GetFullPath(file) + ".new" : Path.Combine(_outDir, Path.GetFileName(file))) + sub, header, string.Empty); - _logger.User("Reheadered file created!"); - } - } - else - { - _logger.Warning("No matching header could be found!"); - success = false; - } - - // Dispose of database objects - slc.Dispose(); - sldr.Dispose(); - dbc.Dispose(); - - return success; - } - } -} diff --git a/SabreTools.Helper/SabreTools.Helper.csproj b/SabreTools.Helper/SabreTools.Helper.csproj index 6ef2fb38..d127ff53 100644 --- a/SabreTools.Helper/SabreTools.Helper.csproj +++ b/SabreTools.Helper/SabreTools.Helper.csproj @@ -107,7 +107,6 @@ - diff --git a/SabreTools.Helper/Tools/FileTools.cs b/SabreTools.Helper/Tools/FileTools.cs index 86da0a87..8da3b7e1 100644 --- a/SabreTools.Helper/Tools/FileTools.cs +++ b/SabreTools.Helper/Tools/FileTools.cs @@ -1,4 +1,5 @@ -using OCRC; +using Mono.Data.Sqlite; +using OCRC; using SharpCompress.Archive; using SharpCompress.Archive.SevenZip; using SharpCompress.Common; @@ -1227,6 +1228,169 @@ namespace SabreTools.Helper fsw.Dispose(); } + /// + /// Detect header skipper compliance and create an output file + /// + /// Name of the file to be parsed + /// Output directory to write the file to, empty means the same directory as the input file + /// Logger object for console and file output + /// True if the output file was created, false otherwise + public static bool DetectSkipperAndTransform(string file, string outDir, Logger logger) + { + // Create the output directory if it doesn't exist + if (outDir != "" && !Directory.Exists(outDir)) + { + Directory.CreateDirectory(outDir); + } + + logger.User("\nGetting skipper information for '" + file + "'"); + + // Then, if the file was headered, store it to the database + int headerSize = -1; + HeaderType type = Skippers.GetFileHeaderType(file, out headerSize, logger); + + // If we have a valid HeaderType, remove the correct byte count + logger.User("File has header: " + (type != HeaderType.None)); + if (type != HeaderType.None) + { + logger.Log("Deteched header type: " + type); + + // Now take care of the header and new output file + string hstr = string.Empty; + BinaryReader br = new BinaryReader(File.OpenRead(file)); + + // Extract the header as a string for the database + byte[] hbin = br.ReadBytes(headerSize); + for (int i = 0; i < headerSize; i++) + { + hstr += BitConverter.ToString(new byte[] { hbin[i] }); + } + + br.Dispose(); + + // Then find an apply the exact rule to the file + SkipperRule rule = Skippers.MatchesSkipper(file, "", logger); + + // If we have an empty rule, return false + if (rule.Tests == null || rule.Tests.Count == 0) + { + return false; + } + + // Otherwise, apply the rule to the file + string newfile = (outDir == "" ? Path.GetFullPath(file) + ".new" : Path.Combine(outDir, Path.GetFileName(file))); + Skippers.TransformFile(file, newfile, rule, logger); + + // If the output file doesn't exist, return false + if (!File.Exists(newfile)) + { + return false; + } + + // Now add the information to the database if it's not already there + Rom rom = GetSingleFileInfo(newfile); + AddHeaderToDatabase(hstr, rom.SHA1, type, logger); + } + + return true; + } + + /// + /// Add a header to the database + /// + /// String representing the header bytes + /// SHA-1 of the deheadered file + /// HeaderType representing the detected header + /// Logger object for console and file output + private static void AddHeaderToDatabase(string header, string SHA1, HeaderType type, Logger logger) + { + bool exists = false; + + // Open the database connection + SqliteConnection dbc = new SqliteConnection(Constants.HeadererConnectionString); + dbc.Open(); + + string query = @"SELECT * FROM data WHERE sha1='" + SHA1 + "' AND header='" + header + "'"; + SqliteCommand slc = new SqliteCommand(query, dbc); + SqliteDataReader sldr = slc.ExecuteReader(); + exists = sldr.HasRows; + + if (!exists) + { + query = @"INSERT INTO data (sha1, header, type) VALUES ('" + + SHA1 + "', " + + "'" + header + "', " + + "'" + type.ToString() + "')"; + slc = new SqliteCommand(query, dbc); + logger.Log("Result of inserting header: " + slc.ExecuteNonQuery()); + } + + // Dispose of database objects + slc.Dispose(); + sldr.Dispose(); + dbc.Dispose(); + } + + /// + /// Detect and replace header(s) to the given file + /// + /// Name of the file to be parsed + /// Output directory to write the file to, empty means the same directory as the input file + /// Logger object for console and file output + /// True if a header was found and appended, false otherwise + public static bool RestoreHeader(string file, string outDir, Logger logger) + { + // Create the output directory if it doesn't exist + if (outDir != "" && !Directory.Exists(outDir)) + { + Directory.CreateDirectory(outDir); + } + + bool success = true; + + // First, get the SHA-1 hash of the file + Rom rom = GetSingleFileInfo(file); + + // Then try to pull the corresponding headers from the database + string header = ""; + + // Open the database connection + SqliteConnection dbc = new SqliteConnection(Constants.HeadererConnectionString); + dbc.Open(); + + string query = @"SELECT header, type FROM data WHERE sha1='" + rom.SHA1 + "'"; + SqliteCommand slc = new SqliteCommand(query, dbc); + SqliteDataReader sldr = slc.ExecuteReader(); + + if (sldr.HasRows) + { + int sub = 0; + while (sldr.Read()) + { + logger.Log("Found match with rom type " + sldr.GetString(1)); + header = sldr.GetString(0); + + logger.User("Creating reheadered file: " + + (outDir == "" ? Path.GetFullPath(file) + ".new" : Path.Combine(outDir, Path.GetFileName(file))) + sub); + FileTools.AppendBytesToFile(file, + (outDir == "" ? Path.GetFullPath(file) + ".new" : Path.Combine(outDir, Path.GetFileName(file))) + sub, header, string.Empty); + logger.User("Reheadered file created!"); + } + } + else + { + logger.Warning("No matching header could be found!"); + success = false; + } + + // Dispose of database objects + slc.Dispose(); + sldr.Dispose(); + dbc.Dispose(); + + return success; + } + /// /// Copy a file to a new location, creating directories as needed /// diff --git a/SabreTools/Partials/SabreTools_Inits.cs b/SabreTools/Partials/SabreTools_Inits.cs index 7d1266c0..b0b99bcd 100644 --- a/SabreTools/Partials/SabreTools_Inits.cs +++ b/SabreTools/Partials/SabreTools_Inits.cs @@ -216,8 +216,34 @@ namespace SabreTools /// Logger object for file and console output private static void InitHeaderer(List inputs, bool restore, string outDir, Logger logger) { - Headerer headerer = new Headerer(inputs, restore, outDir, logger); - headerer.Process(); + foreach (string input in inputs) + { + if (File.Exists(input)) + { + if (restore) + { + FileTools.RestoreHeader(input, outDir, logger); + } + else + { + FileTools.DetectSkipperAndTransform(input, outDir, logger); + } + } + else if (Directory.Exists(input)) + { + foreach (string sub in Directory.EnumerateFiles(input, "*", SearchOption.AllDirectories)) + { + if (restore) + { + FileTools.RestoreHeader(sub, outDir, logger); + } + else + { + FileTools.DetectSkipperAndTransform(sub, outDir, logger); + } + } + } + } } ///