diff --git a/.gitignore b/.gitignore
index a67add3f..7e6382fc 100644
--- a/.gitignore
+++ b/.gitignore
@@ -12,4 +12,6 @@
/SabreTools.Data/obj/
/SabreTools.Library/bin/
/SabreTools.Library/obj/
+/SabreTools.Skippers/bin/
+/SabreTools.Skippers/obj/
/SabreTools.userprefs
diff --git a/SabreTools.Library/IO/FileExtensions.cs b/SabreTools.Library/IO/FileExtensions.cs
index 52c3c355..41af4627 100644
--- a/SabreTools.Library/IO/FileExtensions.cs
+++ b/SabreTools.Library/IO/FileExtensions.cs
@@ -9,7 +9,7 @@ using SabreTools.Data;
using SabreTools.Library.DatFiles;
using SabreTools.Library.FileTypes;
using SabreTools.Library.Logging;
-using SabreTools.Library.Skippers;
+using SabreTools.Library.Tools;
namespace SabreTools.Library.IO
{
@@ -370,7 +370,7 @@ namespace SabreTools.Library.IO
// Try to match the supplied header skipper
if (header != null)
{
- SkipperRule rule = Transform.GetMatchingRule(input, Path.GetFileNameWithoutExtension(header));
+ var rule = Transform.GetMatchingRule(input, Path.GetFileNameWithoutExtension(header));
// If there's a match, transform the stream before getting info
if (rule.Tests != null && rule.Tests.Count != 0)
diff --git a/SabreTools.Library/Skippers/Transform.cs b/SabreTools.Library/IO/Transform.cs
similarity index 98%
rename from SabreTools.Library/Skippers/Transform.cs
rename to SabreTools.Library/IO/Transform.cs
index c98ff3d2..8115cdcc 100644
--- a/SabreTools.Library/Skippers/Transform.cs
+++ b/SabreTools.Library/IO/Transform.cs
@@ -4,11 +4,11 @@ using System.IO;
using SabreTools.Data;
using SabreTools.Library.DatFiles;
using SabreTools.Library.FileTypes;
-using SabreTools.Library.IO;
using SabreTools.Library.Logging;
+using SabreTools.Library.Skippers;
using SabreTools.Library.Tools;
-namespace SabreTools.Library.Skippers
+namespace SabreTools.Library.IO
{
///
/// Class for wrapping general file transformations
@@ -32,6 +32,11 @@ namespace SabreTools.Library.Skippers
///
private static List List;
+ ///
+ /// Local paths
+ ///
+ private static string LocalPath = Path.Combine(Globals.ExeDir, "Skippers") + Path.DirectorySeparatorChar;
+
#region Logging
///
@@ -41,11 +46,6 @@ namespace SabreTools.Library.Skippers
#endregion
- ///
- /// Local paths
- ///
- public static string LocalPath = Path.Combine(Globals.ExeDir, "Skippers") + Path.DirectorySeparatorChar;
-
///
/// Initialize static fields
///
diff --git a/SabreTools.Library/SabreTools.Library.csproj b/SabreTools.Library/SabreTools.Library.csproj
index f8617ca5..d27e5b52 100644
--- a/SabreTools.Library/SabreTools.Library.csproj
+++ b/SabreTools.Library/SabreTools.Library.csproj
@@ -13,48 +13,7 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Always
-
-
- Always
-
-
- Always
-
-
- Always
-
-
- Always
-
-
- Always
-
-
- Always
-
-
- Always
-
-
- Always
-
+
diff --git a/SabreTools.Library/Skippers/Enums.cs b/SabreTools.Skippers/Enums.cs
similarity index 100%
rename from SabreTools.Library/Skippers/Enums.cs
rename to SabreTools.Skippers/Enums.cs
diff --git a/SabreTools.Skippers/SabreTools.Skippers.csproj b/SabreTools.Skippers/SabreTools.Skippers.csproj
new file mode 100644
index 00000000..752c6fee
--- /dev/null
+++ b/SabreTools.Skippers/SabreTools.Skippers.csproj
@@ -0,0 +1,56 @@
+
+
+
+ net48;netcoreapp3.1;net5.0
+ win10-x64;win7-x86
+ Debug;Release
+ AnyCPU;x64
+
+
+
+ NET_FRAMEWORK
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Always
+
+
+ Always
+
+
+ Always
+
+
+ Always
+
+
+ Always
+
+
+ Always
+
+
+ Always
+
+
+ Always
+
+
+ Always
+
+
+
+
diff --git a/SabreTools.Library/Skippers/SkipperFile.cs b/SabreTools.Skippers/SkipperFile.cs
similarity index 90%
rename from SabreTools.Library/Skippers/SkipperFile.cs
rename to SabreTools.Skippers/SkipperFile.cs
index b2eb5af8..7ffff087 100644
--- a/SabreTools.Library/Skippers/SkipperFile.cs
+++ b/SabreTools.Skippers/SkipperFile.cs
@@ -4,10 +4,14 @@ using System.Globalization;
using System.IO;
using System.Xml;
-using SabreTools.Library.IO;
-
namespace SabreTools.Library.Skippers
{
+ ///
+ /// It is well worth considering just moving the XML files to code, similar to how RV does it
+ /// if only because nobody really has any skippers outside of this. It would also make the
+ /// output directory cleaner and less prone to user error in case something didn't get copied
+ /// correctly. The contents of these files should still be added to the wiki, in that case.
+ ///
public class SkipperFile
{
#region Fields
@@ -55,7 +59,7 @@ namespace SabreTools.Library.Skippers
Rules = new List();
SourceFile = Path.GetFileNameWithoutExtension(filename);
- XmlReader xtr = filename.GetXmlTextReader();
+ XmlReader xtr = GetXmlTextReader(filename);
bool valid = Parse(xtr);
// If we somehow have an invalid file, zero out the fields
@@ -406,5 +410,34 @@ namespace SabreTools.Library.Skippers
}
#endregion
+
+ // TODO: Remove this region once IO namespace is separated out properly
+ #region TEMPORARY - REMOVEME
+
+ ///
+ /// Get the XmlTextReader associated with a file, if possible
+ ///
+ /// Name of the file to be parsed
+ /// The XmlTextReader representing the (possibly converted) file, null otherwise
+ private static XmlReader GetXmlTextReader(string filename)
+ {
+ // Check if file exists
+ if (!File.Exists(filename))
+ return null;
+
+ XmlReader xtr = XmlReader.Create(filename, new XmlReaderSettings
+ {
+ CheckCharacters = false,
+ DtdProcessing = DtdProcessing.Ignore,
+ IgnoreComments = true,
+ IgnoreWhitespace = true,
+ ValidationFlags = System.Xml.Schema.XmlSchemaValidationFlags.None,
+ ValidationType = ValidationType.None,
+ });
+
+ return xtr;
+ }
+
+ #endregion
}
}
diff --git a/SabreTools.Library/Skippers/SkipperRule.cs b/SabreTools.Skippers/SkipperRule.cs
similarity index 62%
rename from SabreTools.Library/Skippers/SkipperRule.cs
rename to SabreTools.Skippers/SkipperRule.cs
index 4a2897cf..2fa0b79b 100644
--- a/SabreTools.Library/Skippers/SkipperRule.cs
+++ b/SabreTools.Skippers/SkipperRule.cs
@@ -2,9 +2,6 @@
using System.Collections.Generic;
using System.IO;
-using SabreTools.Library.IO;
-using SabreTools.Library.Logging;
-
namespace SabreTools.Library.Skippers
{
public class SkipperRule
@@ -43,7 +40,7 @@ namespace SabreTools.Library.Skippers
///
/// Logging object
///
- private readonly Logger logger;
+ //private readonly Logger logger; // TODO: Re-enable all logging once Logging namespace separated out
#endregion
@@ -54,7 +51,7 @@ namespace SabreTools.Library.Skippers
///
public SkipperRule()
{
- logger = new Logger(this);
+ //logger = new Logger(this);
}
#endregion
@@ -87,20 +84,20 @@ namespace SabreTools.Library.Skippers
// If the input file doesn't exist, fail
if (!File.Exists(input))
{
- logger.Error($"I'm sorry but '{input}' doesn't exist!");
+ //logger.Error($"I'm sorry but '{input}' doesn't exist!");
return false;
}
// Create the output directory if it doesn't already
- DirectoryExtensions.Ensure(Path.GetDirectoryName(output));
+ Ensure(Path.GetDirectoryName(output));
- logger.User($"Attempting to apply rule to '{input}'");
- bool success = TransformStream(FileExtensions.TryOpenRead(input), FileExtensions.TryCreate(output));
+ //logger.User($"Attempting to apply rule to '{input}'");
+ bool success = TransformStream(TryOpenRead(input), TryCreate(output));
// If the output file has size 0, delete it
if (new FileInfo(output).Length == 0)
{
- FileExtensions.TryDelete(output);
+ TryDelete(output);
success = false;
}
@@ -125,7 +122,7 @@ namespace SabreTools.Library.Skippers
|| (Operation > HeaderSkipOperation.Byteswap && (extsize % 4) != 0)
|| (Operation > HeaderSkipOperation.Bitswap && (StartOffset == null || StartOffset % 2 == 0)))
{
- logger.Error("The stream did not have the correct size to be transformed!");
+ //logger.Error("The stream did not have the correct size to be transformed!");
return false;
}
@@ -134,7 +131,7 @@ namespace SabreTools.Library.Skippers
BinaryReader br = null;
try
{
- logger.User("Applying found rule to input stream");
+ //logger.User("Applying found rule to input stream");
bw = new BinaryWriter(output);
br = new BinaryReader(input);
@@ -222,7 +219,7 @@ namespace SabreTools.Library.Skippers
}
catch (Exception ex)
{
- logger.Error(ex);
+ //logger.Error(ex);
return false;
}
finally
@@ -238,5 +235,113 @@ namespace SabreTools.Library.Skippers
return success;
}
+
+ // TODO: Remove this region once IO namespace is separated out properly
+ #region TEMPORARY - REMOVEME
+
+ ///
+ /// Ensure the output directory is a proper format and can be created
+ ///
+ /// Directory to check
+ /// True if the directory should be created, false otherwise (default)
+ /// True if this is a temp directory, false otherwise
+ /// Full path to the directory
+ 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;
+ }
+
+ ///
+ /// Try to create a file for write, optionally throwing the error
+ ///
+ /// Name of the file to create
+ /// True if the error that is thrown should be thrown back to the caller, false otherwise
+ /// An opened stream representing the file on success, null otherwise
+ public static FileStream TryCreate(string file, bool throwOnError = false)
+ {
+ // Now wrap opening the file
+ try
+ {
+ return File.Open(file, FileMode.Create, FileAccess.Write, FileShare.ReadWrite);
+ }
+ catch (Exception ex)
+ {
+ if (throwOnError)
+ throw ex;
+ else
+ return null;
+ }
+ }
+
+ ///
+ /// Try to safely delete a file, optionally throwing the error
+ ///
+ /// Name of the file to delete
+ /// True if the error that is thrown should be thrown back to the caller, false otherwise
+ /// True if the file didn't exist or could be deleted, false otherwise
+ public static bool TryDelete(string file, bool throwOnError = false)
+ {
+ // Check if the file exists first
+ if (!File.Exists(file))
+ return true;
+
+ // Now wrap deleting the file
+ try
+ {
+ File.Delete(file);
+ return true;
+ }
+ catch (Exception ex)
+ {
+ if (throwOnError)
+ throw ex;
+ else
+ return false;
+ }
+ }
+
+ ///
+ /// Try to open a file for read, optionally throwing the error
+ ///
+ /// Name of the file to open
+ /// True if the error that is thrown should be thrown back to the caller, false otherwise
+ /// An opened stream representing the file on success, null otherwise
+ public static FileStream TryOpenRead(string file, bool throwOnError = false)
+ {
+ // Check if the file exists first
+ if (!File.Exists(file))
+ return null;
+
+ // Now wrap opening the file
+ try
+ {
+ return File.Open(file, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
+ }
+ catch (Exception ex)
+ {
+ if (throwOnError)
+ throw ex;
+ else
+ return null;
+ }
+ }
+
+ #endregion
}
}
diff --git a/SabreTools.Library/Skippers/SkipperTest.cs b/SabreTools.Skippers/SkipperTest.cs
similarity index 100%
rename from SabreTools.Library/Skippers/SkipperTest.cs
rename to SabreTools.Skippers/SkipperTest.cs
diff --git a/SabreTools.Library/Skippers/a7800.xml b/SabreTools.Skippers/a7800.xml
similarity index 100%
rename from SabreTools.Library/Skippers/a7800.xml
rename to SabreTools.Skippers/a7800.xml
diff --git a/SabreTools.Library/Skippers/fds.xml b/SabreTools.Skippers/fds.xml
similarity index 100%
rename from SabreTools.Library/Skippers/fds.xml
rename to SabreTools.Skippers/fds.xml
diff --git a/SabreTools.Library/Skippers/lynx.xml b/SabreTools.Skippers/lynx.xml
similarity index 100%
rename from SabreTools.Library/Skippers/lynx.xml
rename to SabreTools.Skippers/lynx.xml
diff --git a/SabreTools.Library/Skippers/n64.xml b/SabreTools.Skippers/n64.xml
similarity index 100%
rename from SabreTools.Library/Skippers/n64.xml
rename to SabreTools.Skippers/n64.xml
diff --git a/SabreTools.Library/Skippers/nes.xml b/SabreTools.Skippers/nes.xml
similarity index 100%
rename from SabreTools.Library/Skippers/nes.xml
rename to SabreTools.Skippers/nes.xml
diff --git a/SabreTools.Library/Skippers/pce.xml b/SabreTools.Skippers/pce.xml
similarity index 100%
rename from SabreTools.Library/Skippers/pce.xml
rename to SabreTools.Skippers/pce.xml
diff --git a/SabreTools.Library/Skippers/psid.xml b/SabreTools.Skippers/psid.xml
similarity index 100%
rename from SabreTools.Library/Skippers/psid.xml
rename to SabreTools.Skippers/psid.xml
diff --git a/SabreTools.Library/Skippers/snes.xml b/SabreTools.Skippers/snes.xml
similarity index 100%
rename from SabreTools.Library/Skippers/snes.xml
rename to SabreTools.Skippers/snes.xml
diff --git a/SabreTools.Library/Skippers/spc.xml b/SabreTools.Skippers/spc.xml
similarity index 100%
rename from SabreTools.Library/Skippers/spc.xml
rename to SabreTools.Skippers/spc.xml
diff --git a/SabreTools.sln b/SabreTools.sln
index 0df32d4a..85719aaa 100644
--- a/SabreTools.sln
+++ b/SabreTools.sln
@@ -16,7 +16,9 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
README.MD = README.MD
EndProjectSection
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SabreTools.Data", "SabreTools.Data\SabreTools.Data.csproj", "{66E2FB10-77C0-4589-9DCD-3CA48702C18A}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SabreTools.Data", "SabreTools.Data\SabreTools.Data.csproj", "{66E2FB10-77C0-4589-9DCD-3CA48702C18A}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SabreTools.Skippers", "SabreTools.Skippers\SabreTools.Skippers.csproj", "{D8665F27-75E6-4E3F-9F0A-286433831C69}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@@ -58,6 +60,14 @@ Global
{66E2FB10-77C0-4589-9DCD-3CA48702C18A}.Release|Any CPU.Build.0 = Release|Any CPU
{66E2FB10-77C0-4589-9DCD-3CA48702C18A}.Release|x64.ActiveCfg = Release|Any CPU
{66E2FB10-77C0-4589-9DCD-3CA48702C18A}.Release|x64.Build.0 = Release|Any CPU
+ {D8665F27-75E6-4E3F-9F0A-286433831C69}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {D8665F27-75E6-4E3F-9F0A-286433831C69}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {D8665F27-75E6-4E3F-9F0A-286433831C69}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {D8665F27-75E6-4E3F-9F0A-286433831C69}.Debug|x64.Build.0 = Debug|Any CPU
+ {D8665F27-75E6-4E3F-9F0A-286433831C69}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {D8665F27-75E6-4E3F-9F0A-286433831C69}.Release|Any CPU.Build.0 = Release|Any CPU
+ {D8665F27-75E6-4E3F-9F0A-286433831C69}.Release|x64.ActiveCfg = Release|Any CPU
+ {D8665F27-75E6-4E3F-9F0A-286433831C69}.Release|x64.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
diff --git a/SabreTools/Features/Extract.cs b/SabreTools/Features/Extract.cs
index a25c716c..bebafe55 100644
--- a/SabreTools/Features/Extract.cs
+++ b/SabreTools/Features/Extract.cs
@@ -2,7 +2,7 @@
using SabreTools.Library.Help;
using SabreTools.Library.IO;
-using SabreTools.Library.Skippers;
+using SabreTools.Library.Tools;
namespace SabreTools.Features
{
diff --git a/SabreTools/Features/Restore.cs b/SabreTools/Features/Restore.cs
index 8c4e3542..d06feef2 100644
--- a/SabreTools/Features/Restore.cs
+++ b/SabreTools/Features/Restore.cs
@@ -2,7 +2,6 @@
using SabreTools.Library.Help;
using SabreTools.Library.IO;
-using SabreTools.Library.Skippers;
namespace SabreTools.Features
{