mirror of
https://github.com/SabreTools/SabreTools.Serialization.git
synced 2026-02-04 05:36:12 +00:00
Compare commits
362 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d15b4d7d23 | ||
|
|
60e6a75d5e | ||
|
|
484415d0e5 | ||
|
|
0ef9b447c4 | ||
|
|
8f64e2defd | ||
|
|
fbdadce129 | ||
|
|
d3e7abfaa3 | ||
|
|
b2279e97b2 | ||
|
|
7cf969336f | ||
|
|
f73d48166a | ||
|
|
53af618fe4 | ||
|
|
5d2cf58477 | ||
|
|
664e7dce28 | ||
|
|
14a8f00864 | ||
|
|
0b889fdc06 | ||
|
|
e336efc149 | ||
|
|
4cd52162eb | ||
|
|
eab9fff711 | ||
|
|
d4f3511060 | ||
|
|
ed12bbb35c | ||
|
|
aa4629fe99 | ||
|
|
1950f23cf4 | ||
|
|
ca7c88cef6 | ||
|
|
10848e6c51 | ||
|
|
f5d0f065c1 | ||
|
|
17b0573b0b | ||
|
|
7f1d843d96 | ||
|
|
cc4837c1d1 | ||
|
|
588ee5bfe4 | ||
|
|
e9b1b2750f | ||
|
|
1d6fa06e97 | ||
|
|
2c22924239 | ||
|
|
eb01dd1e25 | ||
|
|
0a3cb79b1c | ||
|
|
da9eace8cc | ||
|
|
526a02b8b6 | ||
|
|
658c7a1c3b | ||
|
|
af84474795 | ||
|
|
42913c6732 | ||
|
|
2cdf544518 | ||
|
|
652ec58238 | ||
|
|
f8531daa5c | ||
|
|
e9e89b0b43 | ||
|
|
55e788a894 | ||
|
|
b28bb93ccb | ||
|
|
367aab0f83 | ||
|
|
9dcf3b9e0a | ||
|
|
3c514110ce | ||
|
|
c9b0c2dace | ||
|
|
d575b6977e | ||
|
|
a00e6a5e2d | ||
|
|
1b9ae83e8c | ||
|
|
8b91eb1caf | ||
|
|
2a6a7b5e9a | ||
|
|
a85943866e | ||
|
|
797fb519c1 | ||
|
|
3ba9d56363 | ||
|
|
04cd4e4056 | ||
|
|
348e170654 | ||
|
|
f5a4ca6276 | ||
|
|
672c010aa7 | ||
|
|
2459d88951 | ||
|
|
350d1c8d31 | ||
|
|
98a3842a3e | ||
|
|
b52a4469ee | ||
|
|
e3143e21ba | ||
|
|
1bf2181fd3 | ||
|
|
1460635aab | ||
|
|
935ec00c86 | ||
|
|
473b6de09b | ||
|
|
ba75f2ac2c | ||
|
|
a230b39fbc | ||
|
|
8e963ac62a | ||
|
|
eaaa89847d | ||
|
|
ef76166978 | ||
|
|
72912586a1 | ||
|
|
fb241a4036 | ||
|
|
368c8b0533 | ||
|
|
4010325e65 | ||
|
|
11dd75ad95 | ||
|
|
d0480a1311 | ||
|
|
2be33b845d | ||
|
|
2ad42e3a0f | ||
|
|
5d1f83800b | ||
|
|
30e89a7943 | ||
|
|
61f5dc4cf2 | ||
|
|
d056c179ed | ||
|
|
b9c4bfc67e | ||
|
|
6ab5ee0ae0 | ||
|
|
94c1a86702 | ||
|
|
af6dd6a7fc | ||
|
|
45d4926d4c | ||
|
|
ce016c5eb0 | ||
|
|
2225c1f2d8 | ||
|
|
2d0c0d5845 | ||
|
|
60f1756cbb | ||
|
|
738a1d250a | ||
|
|
c8e65e1e30 | ||
|
|
ecb09ce6f2 | ||
|
|
72a1484a71 | ||
|
|
de31c10c7c | ||
|
|
84483c229c | ||
|
|
b7e35a8fa8 | ||
|
|
8c190a26a5 | ||
|
|
2e5705125b | ||
|
|
daaa92def0 | ||
|
|
86ec97678e | ||
|
|
d74b82dc55 | ||
|
|
821ade2006 | ||
|
|
3ee999dccd | ||
|
|
f91bda51e1 | ||
|
|
47255fc331 | ||
|
|
f7488bed04 | ||
|
|
a94b3a82c4 | ||
|
|
1c8f64f5e6 | ||
|
|
a015e4df3f | ||
|
|
2489a49924 | ||
|
|
d418fbd60d | ||
|
|
cc2e7704e6 | ||
|
|
a980a56dfa | ||
|
|
da588e3bc0 | ||
|
|
8b6f45d9b7 | ||
|
|
9bdfe33baf | ||
|
|
13d338f615 | ||
|
|
36a8641c8d | ||
|
|
7bde6f99fc | ||
|
|
45428ce991 | ||
|
|
8eb5898ef6 | ||
|
|
556e1c972c | ||
|
|
df8f3e7122 | ||
|
|
da1d575806 | ||
|
|
c4d40a1dde | ||
|
|
912de926d0 | ||
|
|
c60fc1e31f | ||
|
|
386e607887 | ||
|
|
94c9b8d057 | ||
|
|
5f81275b10 | ||
|
|
37c484411b | ||
|
|
ad1f890742 | ||
|
|
2924529fa7 | ||
|
|
ebe675cae1 | ||
|
|
a40c666775 | ||
|
|
2ea060d3b3 | ||
|
|
f8a67839dd | ||
|
|
2773b12c9b | ||
|
|
929e12f976 | ||
|
|
8fbc6c4662 | ||
|
|
797378e9c8 | ||
|
|
113464a7d1 | ||
|
|
a13c837202 | ||
|
|
48765f1ae5 | ||
|
|
091ee56368 | ||
|
|
015a971147 | ||
|
|
7575a01a28 | ||
|
|
7aa14cafea | ||
|
|
db10721386 | ||
|
|
6112cf8d60 | ||
|
|
50caeba322 | ||
|
|
b3499984b3 | ||
|
|
a5609a7a82 | ||
|
|
8626a87860 | ||
|
|
fa31cd0e98 | ||
|
|
6b6b7c6289 | ||
|
|
baa3b272ab | ||
|
|
d7c4f244cc | ||
|
|
e21d226564 | ||
|
|
6ff6a7d4a4 | ||
|
|
daf19a561c | ||
|
|
26226a75ff | ||
|
|
4473edf476 | ||
|
|
54cf0a6470 | ||
|
|
0eb8f7e538 | ||
|
|
23b72c65ba | ||
|
|
db7d89600c | ||
|
|
67d51ad1d6 | ||
|
|
56b71cf7fe | ||
|
|
e0ec2a521f | ||
|
|
e8589ac7b5 | ||
|
|
21e425acee | ||
|
|
ee316052ae | ||
|
|
3463936ae0 | ||
|
|
5ff947b279 | ||
|
|
fdf2ea84ec | ||
|
|
ad9b001b6a | ||
|
|
1308571c10 | ||
|
|
b8cb3419c1 | ||
|
|
02533cf947 | ||
|
|
bf8bd04dc7 | ||
|
|
1894376ab6 | ||
|
|
c789e4df44 | ||
|
|
884685de4a | ||
|
|
7fda7be457 | ||
|
|
5daf759033 | ||
|
|
589ab0896a | ||
|
|
7645ab978f | ||
|
|
e6497289da | ||
|
|
95a9f4769d | ||
|
|
7917601f7a | ||
|
|
3400238fc5 | ||
|
|
cbd335c6aa | ||
|
|
9feaadd32a | ||
|
|
2ec008b3b7 | ||
|
|
c9a462a1c6 | ||
|
|
ab44aa7e68 | ||
|
|
9b9d3176ec | ||
|
|
5dda3e2c81 | ||
|
|
4b8dc12c98 | ||
|
|
044e4c4c75 | ||
|
|
2149630865 | ||
|
|
3d435a1d7e | ||
|
|
f2d993a958 | ||
|
|
7bf75b8dc5 | ||
|
|
dfbdce1dc8 | ||
|
|
63f5566e65 | ||
|
|
4b0f43f6c0 | ||
|
|
98e1ef7362 | ||
|
|
4e0ffcb3c8 | ||
|
|
a93a46d6c0 | ||
|
|
e163302522 | ||
|
|
838afc35c3 | ||
|
|
3a62bfab57 | ||
|
|
560b3a246c | ||
|
|
4360916750 | ||
|
|
3f31edc1c0 | ||
|
|
bd874d436b | ||
|
|
fbc47425f4 | ||
|
|
c9df6ff059 | ||
|
|
ef6ff85e96 | ||
|
|
bb93792f57 | ||
|
|
1f7ab4fccb | ||
|
|
2535e82618 | ||
|
|
66d80c8523 | ||
|
|
834a17fe82 | ||
|
|
ea85167e06 | ||
|
|
e007a06dda | ||
|
|
02f9e1e935 | ||
|
|
21b7d431a7 | ||
|
|
307b932f87 | ||
|
|
6983d1cd3c | ||
|
|
a193c9bb3c | ||
|
|
aa67c7ad6d | ||
|
|
70fc686249 | ||
|
|
c87a456a46 | ||
|
|
456bb1e95b | ||
|
|
b0b334103d | ||
|
|
78851e3b57 | ||
|
|
850a883e14 | ||
|
|
6e0ced5ffe | ||
|
|
64cd8febaa | ||
|
|
6fbe1cffaa | ||
|
|
601e781ef9 | ||
|
|
d26ad35573 | ||
|
|
b70c510734 | ||
|
|
29a7158488 | ||
|
|
1227ca020a | ||
|
|
cd7e6ff98d | ||
|
|
510a0f77f6 | ||
|
|
6d1dabb1db | ||
|
|
2e337891da | ||
|
|
d49e18a83e | ||
|
|
c14560ec18 | ||
|
|
e3e31cd9f2 | ||
|
|
adf9627045 | ||
|
|
c7b03c7765 | ||
|
|
b5f83215d5 | ||
|
|
96e3fc5533 | ||
|
|
828e7dda03 | ||
|
|
8ef50c30d5 | ||
|
|
cbe1d5b608 | ||
|
|
7123a9e986 | ||
|
|
af5996b972 | ||
|
|
15e947784b | ||
|
|
1b382c201e | ||
|
|
8deca4fb0c | ||
|
|
96c4372609 | ||
|
|
ca7a109037 | ||
|
|
c54f5b3c5d | ||
|
|
652942ab9f | ||
|
|
2cc19a9c36 | ||
|
|
6ffb3f4bbd | ||
|
|
bab4278318 | ||
|
|
013d18a426 | ||
|
|
e94e27910e | ||
|
|
34cea6e74a | ||
|
|
640e160863 | ||
|
|
3100963250 | ||
|
|
2086358762 | ||
|
|
ae273c589d | ||
|
|
a229015fcd | ||
|
|
b001680674 | ||
|
|
e684133f72 | ||
|
|
2b020eecc7 | ||
|
|
78f4d6faca | ||
|
|
f07b7a049e | ||
|
|
544637779c | ||
|
|
38b6427e4e | ||
|
|
e36822a19c | ||
|
|
e1a114976f | ||
|
|
5ba9ab3457 | ||
|
|
36edf9ed54 | ||
|
|
e788ffa851 | ||
|
|
e0d819b88d | ||
|
|
e3b216ad09 | ||
|
|
55d0fd452d | ||
|
|
089fd02b2e | ||
|
|
8cfd820dcd | ||
|
|
67ed9860fe | ||
|
|
ee924e3a34 | ||
|
|
9e5085ba79 | ||
|
|
dbfdbbff20 | ||
|
|
21dc72bf11 | ||
|
|
c8295c4724 | ||
|
|
44b4dd3d1b | ||
|
|
7e543c6acb | ||
|
|
63514d149f | ||
|
|
d7e559749d | ||
|
|
a2be40fcbc | ||
|
|
771df5c372 | ||
|
|
2d3d6348ad | ||
|
|
a2bf15f0bc | ||
|
|
0aa25df88f | ||
|
|
36afb1c0ee | ||
|
|
c9d61906fb | ||
|
|
d8440a01d3 | ||
|
|
74d92312ef | ||
|
|
0dc9823d2b | ||
|
|
9c69737073 | ||
|
|
66187dcf04 | ||
|
|
79943560bc | ||
|
|
b3321f9c9a | ||
|
|
428c269a49 | ||
|
|
e84964a321 | ||
|
|
0394ea5356 | ||
|
|
852b086920 | ||
|
|
b7fceee2b7 | ||
|
|
ecf6c957c9 | ||
|
|
5e0b0070ff | ||
|
|
9934bc31a3 | ||
|
|
7b4711f5cf | ||
|
|
844066815d | ||
|
|
3a6293e696 | ||
|
|
3210b8601d | ||
|
|
181788802d | ||
|
|
4b627ce776 | ||
|
|
8b799bb5c8 | ||
|
|
5bc8336fce | ||
|
|
4f9f8ddcec | ||
|
|
29f1f63ef8 | ||
|
|
48ecdff5f7 | ||
|
|
411acd2d5a | ||
|
|
e6742fe889 | ||
|
|
b6561719a7 | ||
|
|
2bf3d6f9a6 | ||
|
|
b2700b5975 | ||
|
|
95b28874da | ||
|
|
4934ee837c | ||
|
|
3cbfd5cd10 | ||
|
|
da28ce310b | ||
|
|
ac6d93a3b9 | ||
|
|
104028204d | ||
|
|
d3e61b42dd | ||
|
|
6351cabb62 |
3
.gitmodules
vendored
Normal file
3
.gitmodules
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
[submodule "SabreTools.Serialization/_EXTERNAL/stormlibsharp"]
|
||||
path = SabreTools.Serialization/_EXTERNAL/stormlibsharp
|
||||
url = https://github.com/robpaveza/stormlibsharp.git
|
||||
14
.vscode/launch.json
vendored
14
.vscode/launch.json
vendored
@@ -4,6 +4,20 @@
|
||||
// For further information visit https://github.com/OmniSharp/omnisharp-vscode/blob/master/debugger-launchjson.md
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
{
|
||||
"name": ".NET Core Launch (ExtractionTool)",
|
||||
"type": "coreclr",
|
||||
"request": "launch",
|
||||
"preLaunchTask": "build",
|
||||
// If you have changed target frameworks, make sure to update the program path.
|
||||
"program": "${workspaceFolder}/ExtractionTool/bin/Debug/net9.0/ExtractionTool.dll",
|
||||
"args": [],
|
||||
"cwd": "${workspaceFolder}",
|
||||
// For more information about the 'console' field, see https://aka.ms/VSCode-CS-LaunchJson-Console
|
||||
"console": "internalConsole",
|
||||
"stopAtEntry": false,
|
||||
"justMyCode": false
|
||||
},
|
||||
{
|
||||
"name": ".NET Core Launch (InfoPrint)",
|
||||
"type": "coreclr",
|
||||
|
||||
73
ExtractionTool/ExtractionTool.csproj
Normal file
73
ExtractionTool/ExtractionTool.csproj
Normal file
@@ -0,0 +1,73 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFrameworks>net20;net35;net40;net452;net462;net472;net48;netcoreapp3.1;net5.0;net6.0;net7.0;net8.0;net9.0</TargetFrameworks>
|
||||
<OutputType>Exe</OutputType>
|
||||
<CheckEolTargetFramework>false</CheckEolTargetFramework>
|
||||
<IncludeNativeLibrariesForSelfExtract>true</IncludeNativeLibrariesForSelfExtract>
|
||||
<IncludeSourceRevisionInInformationalVersion>false</IncludeSourceRevisionInInformationalVersion>
|
||||
<LangVersion>latest</LangVersion>
|
||||
<Nullable>enable</Nullable>
|
||||
<SuppressTfmSupportBuildWarnings>true</SuppressTfmSupportBuildWarnings>
|
||||
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
|
||||
<Version>1.9.2</Version>
|
||||
</PropertyGroup>
|
||||
|
||||
<!-- Support All Frameworks -->
|
||||
<PropertyGroup Condition="$(TargetFramework.StartsWith(`net2`)) OR $(TargetFramework.StartsWith(`net3`)) OR $(TargetFramework.StartsWith(`net4`))">
|
||||
<RuntimeIdentifiers>win-x86;win-x64</RuntimeIdentifiers>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="$(TargetFramework.StartsWith(`netcoreapp`)) OR $(TargetFramework.StartsWith(`net5`))">
|
||||
<RuntimeIdentifiers>win-x86;win-x64;win-arm64;linux-x64;linux-arm64;osx-x64</RuntimeIdentifiers>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="$(TargetFramework.StartsWith(`net6`)) OR $(TargetFramework.StartsWith(`net7`)) OR $(TargetFramework.StartsWith(`net8`)) OR $(TargetFramework.StartsWith(`net9`))">
|
||||
<RuntimeIdentifiers>win-x86;win-x64;win-arm64;linux-x64;linux-arm64;osx-x64;osx-arm64</RuntimeIdentifiers>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="$(RuntimeIdentifier.StartsWith(`osx-arm`))">
|
||||
<TargetFrameworks>net6.0;net7.0;net8.0;net9.0</TargetFrameworks>
|
||||
</PropertyGroup>
|
||||
|
||||
<!-- Set a build flag for Windows specifically -->
|
||||
<PropertyGroup Condition="'$(RuntimeIdentifier)'=='win-x86'">
|
||||
<DefineConstants>$(DefineConstants);WINX86</DefineConstants>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(RuntimeIdentifier)'=='win-x64'">
|
||||
<DefineConstants>$(DefineConstants);WINX64</DefineConstants>
|
||||
</PropertyGroup>
|
||||
|
||||
<!-- These are needed for dealing with native Windows DLLs -->
|
||||
<ItemGroup Condition="'$(RuntimeIdentifier)'=='win-x86'">
|
||||
<ContentWithTargetPath Include="..\SabreTools.Serialization\runtimes\win-x86\native\CascLib.dll">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
<CopyToPublishDirectory>Always</CopyToPublishDirectory>
|
||||
<TargetPath>CascLib.dll</TargetPath>
|
||||
</ContentWithTargetPath>
|
||||
<ContentWithTargetPath Include="..\SabreTools.Serialization\runtimes\win-x86\native\StormLib.dll">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
<CopyToPublishDirectory>Always</CopyToPublishDirectory>
|
||||
<TargetPath>StormLib.dll</TargetPath>
|
||||
</ContentWithTargetPath>
|
||||
</ItemGroup>
|
||||
<ItemGroup Condition="'$(RuntimeIdentifier)'=='win-x64'">
|
||||
<ContentWithTargetPath Include="..\SabreTools.Serialization\runtimes\win-x64\native\CascLib.dll">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
<CopyToPublishDirectory>Always</CopyToPublishDirectory>
|
||||
<TargetPath>CascLib.dll</TargetPath>
|
||||
</ContentWithTargetPath>
|
||||
<ContentWithTargetPath Include="..\SabreTools.Serialization\runtimes\win-x64\native\StormLib.dll">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
<CopyToPublishDirectory>Always</CopyToPublishDirectory>
|
||||
<TargetPath>StormLib.dll</TargetPath>
|
||||
</ContentWithTargetPath>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\SabreTools.Serialization\SabreTools.Serialization.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="SabreTools.IO" Version="1.7.2" />
|
||||
<PackageReference Include="System.Text.Encoding.CodePages" Version="9.0.8" Condition="!$(TargetFramework.StartsWith(`net2`)) AND !$(TargetFramework.StartsWith(`net3`)) AND !$(TargetFramework.StartsWith(`net40`)) AND !$(TargetFramework.StartsWith(`net452`))" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
129
ExtractionTool/Options.cs
Normal file
129
ExtractionTool/Options.cs
Normal file
@@ -0,0 +1,129 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
|
||||
namespace ExtractionTool
|
||||
{
|
||||
/// <summary>
|
||||
/// Set of options for the test executable
|
||||
/// </summary>
|
||||
internal sealed class Options
|
||||
{
|
||||
#region Properties
|
||||
|
||||
/// <summary>
|
||||
/// Enable debug output for relevant operations
|
||||
/// </summary>
|
||||
public bool Debug { get; private set; } = false;
|
||||
|
||||
/// <summary>
|
||||
/// Set of input paths to use for operations
|
||||
/// </summary>
|
||||
public List<string> InputPaths { get; private set; } = [];
|
||||
|
||||
/// <summary>
|
||||
/// Output path for archive extraction
|
||||
/// </summary>
|
||||
public string OutputPath { get; private set; } = string.Empty;
|
||||
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// Parse commandline arguments into an Options object
|
||||
/// </summary>
|
||||
public static Options? ParseOptions(string[] args)
|
||||
{
|
||||
// If we have invalid arguments
|
||||
if (args == null || args.Length == 0)
|
||||
return null;
|
||||
|
||||
// Create an Options object
|
||||
var options = new Options();
|
||||
|
||||
// Parse the options and paths
|
||||
for (int index = 0; index < args.Length; index++)
|
||||
{
|
||||
string arg = args[index];
|
||||
switch (arg)
|
||||
{
|
||||
case "-?":
|
||||
case "-h":
|
||||
case "--help":
|
||||
return null;
|
||||
|
||||
case "-d":
|
||||
case "--debug":
|
||||
options.Debug = true;
|
||||
break;
|
||||
|
||||
case "-o":
|
||||
case "--outdir":
|
||||
options.OutputPath = index + 1 < args.Length ? args[++index] : string.Empty;
|
||||
break;
|
||||
|
||||
default:
|
||||
options.InputPaths.Add(arg);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Validate we have any input paths to work on
|
||||
if (options.InputPaths.Count == 0)
|
||||
{
|
||||
Console.WriteLine("At least one path is required!");
|
||||
return null;
|
||||
}
|
||||
|
||||
// Validate the output path
|
||||
bool validPath = ValidateExtractionPath(options);
|
||||
if (!validPath)
|
||||
return null;
|
||||
|
||||
return options;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Display help text
|
||||
/// </summary>
|
||||
public static void DisplayHelp()
|
||||
{
|
||||
Console.WriteLine("Extraction Tool");
|
||||
Console.WriteLine();
|
||||
Console.WriteLine("ExtractionTool.exe <options> file|directory ...");
|
||||
Console.WriteLine();
|
||||
Console.WriteLine("Options:");
|
||||
Console.WriteLine("-?, -h, --help Display this help text and quit");
|
||||
Console.WriteLine("-d, --debug Enable debug mode");
|
||||
Console.WriteLine("-o, --outdir [PATH] Set output path for extraction (required)");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Validate the extraction path
|
||||
/// </summary>
|
||||
private static bool ValidateExtractionPath(Options options)
|
||||
{
|
||||
// Null or empty output path
|
||||
if (string.IsNullOrEmpty(options.OutputPath))
|
||||
{
|
||||
Console.WriteLine("Output directory required for extraction!");
|
||||
Console.WriteLine();
|
||||
return false;
|
||||
}
|
||||
|
||||
// Malformed output path or invalid location
|
||||
try
|
||||
{
|
||||
options.OutputPath = Path.GetFullPath(options.OutputPath);
|
||||
Directory.CreateDirectory(options.OutputPath);
|
||||
}
|
||||
catch
|
||||
{
|
||||
Console.WriteLine("Output directory could not be created!");
|
||||
Console.WriteLine();
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
249
ExtractionTool/Program.cs
Normal file
249
ExtractionTool/Program.cs
Normal file
@@ -0,0 +1,249 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using SabreTools.IO.Extensions;
|
||||
using SabreTools.Serialization.Wrappers;
|
||||
|
||||
namespace ExtractionTool
|
||||
{
|
||||
class Program
|
||||
{
|
||||
static void Main(string[] args)
|
||||
{
|
||||
#if NET462_OR_GREATER || NETCOREAPP
|
||||
// Register the codepages
|
||||
System.Text.Encoding.RegisterProvider(System.Text.CodePagesEncodingProvider.Instance);
|
||||
#endif
|
||||
|
||||
// Get the options from the arguments
|
||||
var options = Options.ParseOptions(args);
|
||||
|
||||
// If we have an invalid state
|
||||
if (options == null)
|
||||
{
|
||||
Options.DisplayHelp();
|
||||
return;
|
||||
}
|
||||
|
||||
// Loop through the input paths
|
||||
foreach (string inputPath in options.InputPaths)
|
||||
{
|
||||
ExtractPath(inputPath, options.OutputPath, options.Debug);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Wrapper to extract data for a single path
|
||||
/// </summary>
|
||||
/// <param name="path">File or directory path</param>
|
||||
/// <param name="outputDirectory">Output directory path</param>
|
||||
/// <param name="includeDebug">Enable including debug information</param>
|
||||
private static void ExtractPath(string path, string outputDirectory, bool includeDebug)
|
||||
{
|
||||
// Normalize by getting the full path
|
||||
path = Path.GetFullPath(path);
|
||||
Console.WriteLine($"Checking possible path: {path}");
|
||||
|
||||
// Check if the file or directory exists
|
||||
if (File.Exists(path))
|
||||
{
|
||||
ExtractFile(path, outputDirectory, includeDebug);
|
||||
}
|
||||
else if (Directory.Exists(path))
|
||||
{
|
||||
foreach (string file in IOExtensions.SafeEnumerateFiles(path, "*", SearchOption.AllDirectories))
|
||||
{
|
||||
ExtractFile(file, outputDirectory, includeDebug);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine($"{path} does not exist, skipping...");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Print information for a single file, if possible
|
||||
/// </summary>
|
||||
private static void ExtractFile(string file, string outputDirectory, bool includeDebug)
|
||||
{
|
||||
Console.WriteLine($"Attempting to extract all files from {file}");
|
||||
using Stream stream = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
|
||||
|
||||
// Get the extension for certain checks
|
||||
string extension = Path.GetExtension(file).ToLower().TrimStart('.');
|
||||
|
||||
// Get the first 16 bytes for matching
|
||||
byte[] magic = new byte[16];
|
||||
try
|
||||
{
|
||||
int read = stream.Read(magic, 0, 16);
|
||||
stream.Seek(0, SeekOrigin.Begin);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
if (includeDebug) Console.Error.WriteLine(ex);
|
||||
return;
|
||||
}
|
||||
|
||||
// Get the file type
|
||||
WrapperType ft = WrapperFactory.GetFileType(magic, extension);
|
||||
var wrapper = WrapperFactory.CreateWrapper(ft, stream);
|
||||
|
||||
// Create the output directory
|
||||
Directory.CreateDirectory(outputDirectory);
|
||||
|
||||
// Print the preamble
|
||||
Console.WriteLine($"Attempting to extract from '{wrapper?.Description() ?? "UNKNOWN"}'");
|
||||
Console.WriteLine();
|
||||
|
||||
switch (wrapper)
|
||||
{
|
||||
// 7-zip
|
||||
case SevenZip sz:
|
||||
sz.Extract(outputDirectory, includeDebug);
|
||||
break;
|
||||
|
||||
// BFPK archive
|
||||
case BFPK bfpk:
|
||||
bfpk.Extract(outputDirectory, includeDebug);
|
||||
break;
|
||||
|
||||
// BSP
|
||||
case BSP bsp:
|
||||
bsp.Extract(outputDirectory, includeDebug);
|
||||
break;
|
||||
|
||||
// bzip2
|
||||
case BZip2 bzip2:
|
||||
bzip2.Extract(outputDirectory, includeDebug);
|
||||
break;
|
||||
|
||||
// CFB
|
||||
case CFB cfb:
|
||||
cfb.Extract(outputDirectory, includeDebug);
|
||||
break;
|
||||
|
||||
// GCF
|
||||
case GCF gcf:
|
||||
gcf.Extract(outputDirectory, includeDebug);
|
||||
break;
|
||||
|
||||
// gzip
|
||||
case GZip gzip:
|
||||
gzip.Extract(outputDirectory, includeDebug);
|
||||
break;
|
||||
|
||||
// InstallShield Archive V3 (Z)
|
||||
case InstallShieldArchiveV3 isv3:
|
||||
isv3.Extract(outputDirectory, includeDebug);
|
||||
break;
|
||||
|
||||
// IS-CAB archive
|
||||
case InstallShieldCabinet iscab:
|
||||
iscab.Extract(outputDirectory, includeDebug);
|
||||
break;
|
||||
|
||||
// LZ-compressed file, KWAJ variant
|
||||
case LZKWAJ kwaj:
|
||||
kwaj.Extract(outputDirectory, includeDebug);
|
||||
break;
|
||||
|
||||
// LZ-compressed file, QBasic variant
|
||||
case LZQBasic qbasic:
|
||||
qbasic.Extract(outputDirectory, includeDebug);
|
||||
break;
|
||||
|
||||
// LZ-compressed file, SZDD variant
|
||||
case LZSZDD szdd:
|
||||
szdd.Extract(outputDirectory, includeDebug);
|
||||
break;
|
||||
|
||||
// Microsoft Cabinet archive
|
||||
case MicrosoftCabinet mscab:
|
||||
mscab.Extract(outputDirectory, includeDebug);
|
||||
break;
|
||||
|
||||
// MoPaQ (MPQ) archive
|
||||
case MoPaQ mpq:
|
||||
mpq.Extract(outputDirectory, includeDebug);
|
||||
break;
|
||||
|
||||
// New Executable
|
||||
case NewExecutable nex:
|
||||
nex.Extract(outputDirectory, includeDebug);
|
||||
break;
|
||||
|
||||
// PAK
|
||||
case PAK pak:
|
||||
pak.Extract(outputDirectory, includeDebug);
|
||||
break;
|
||||
|
||||
// PFF
|
||||
case PFF pff:
|
||||
pff.Extract(outputDirectory, includeDebug);
|
||||
break;
|
||||
|
||||
// PKZIP
|
||||
case PKZIP pkzip:
|
||||
pkzip.Extract(outputDirectory, includeDebug);
|
||||
break;
|
||||
|
||||
// Portable Executable
|
||||
case PortableExecutable pex:
|
||||
pex.Extract(outputDirectory, includeDebug);
|
||||
break;
|
||||
|
||||
// Quantum
|
||||
case Quantum quantum:
|
||||
quantum.Extract(outputDirectory, includeDebug);
|
||||
break;
|
||||
|
||||
// RAR
|
||||
case RAR rar:
|
||||
rar.Extract(outputDirectory, includeDebug);
|
||||
break;
|
||||
|
||||
// SGA
|
||||
case SGA sga:
|
||||
sga.Extract(outputDirectory, includeDebug);
|
||||
break;
|
||||
|
||||
// Tape Archive
|
||||
case TapeArchive tar:
|
||||
tar.Extract(outputDirectory, includeDebug);
|
||||
break;
|
||||
|
||||
// VBSP
|
||||
case VBSP vbsp:
|
||||
vbsp.Extract(outputDirectory, includeDebug);
|
||||
break;
|
||||
|
||||
// VPK
|
||||
case VPK vpk:
|
||||
vpk.Extract(outputDirectory, includeDebug);
|
||||
break;
|
||||
|
||||
// WAD3
|
||||
case WAD3 wad:
|
||||
wad.Extract(outputDirectory, includeDebug);
|
||||
break;
|
||||
|
||||
// xz
|
||||
case XZ xz:
|
||||
xz.Extract(outputDirectory, includeDebug);
|
||||
break;
|
||||
|
||||
// XZP
|
||||
case XZP xzp:
|
||||
xzp.Extract(outputDirectory, includeDebug);
|
||||
break;
|
||||
|
||||
// Everything else
|
||||
default:
|
||||
Console.WriteLine("Not a supported extractable file format, skipping...");
|
||||
Console.WriteLine();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4,12 +4,13 @@
|
||||
<TargetFrameworks>net20;net35;net40;net452;net462;net472;net48;netcoreapp3.1;net5.0;net6.0;net7.0;net8.0;net9.0</TargetFrameworks>
|
||||
<OutputType>Exe</OutputType>
|
||||
<CheckEolTargetFramework>false</CheckEolTargetFramework>
|
||||
<IncludeNativeLibrariesForSelfExtract>true</IncludeNativeLibrariesForSelfExtract>
|
||||
<IncludeSourceRevisionInInformationalVersion>false</IncludeSourceRevisionInInformationalVersion>
|
||||
<LangVersion>latest</LangVersion>
|
||||
<Nullable>enable</Nullable>
|
||||
<SuppressTfmSupportBuildWarnings>true</SuppressTfmSupportBuildWarnings>
|
||||
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
|
||||
<Version>1.8.7</Version>
|
||||
<Version>1.9.2</Version>
|
||||
</PropertyGroup>
|
||||
|
||||
<!-- Support All Frameworks -->
|
||||
@@ -31,7 +32,8 @@
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="SabreTools.IO" Version="1.6.3" />
|
||||
<PackageReference Include="SabreTools.IO" Version="1.7.2" />
|
||||
<PackageReference Include="SabreTools.Hashing" Version="1.5.0" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
@@ -15,6 +15,16 @@ namespace InfoPrint
|
||||
/// </summary>
|
||||
public bool Debug { get; private set; } = false;
|
||||
|
||||
/// <summary>
|
||||
/// Output information to file only, skip printing to console
|
||||
/// </summary>
|
||||
public bool FileOnly { get; private set; } = false;
|
||||
|
||||
/// <summary>
|
||||
/// Print external file hashes
|
||||
/// </summary>
|
||||
public bool Hash { get; private set; } = false;
|
||||
|
||||
/// <summary>
|
||||
/// Set of input paths to use for operations
|
||||
/// </summary>
|
||||
@@ -74,6 +84,16 @@ namespace InfoPrint
|
||||
options.Debug = true;
|
||||
break;
|
||||
|
||||
case "-c":
|
||||
case "--hash":
|
||||
options.Hash = true;
|
||||
break;
|
||||
|
||||
case "-f":
|
||||
case "--file":
|
||||
options.FileOnly = true;
|
||||
break;
|
||||
|
||||
case "-j":
|
||||
case "--json":
|
||||
#if NETCOREAPP
|
||||
@@ -106,14 +126,16 @@ namespace InfoPrint
|
||||
{
|
||||
Console.WriteLine("Information Printing Program");
|
||||
Console.WriteLine();
|
||||
Console.WriteLine("infoprint.exe <options> file|directory ...");
|
||||
Console.WriteLine("InfoPrint <options> file|directory ...");
|
||||
Console.WriteLine();
|
||||
Console.WriteLine("Options:");
|
||||
Console.WriteLine("-?, -h, --help Display this help text and quit");
|
||||
Console.WriteLine("-d, --debug Enable debug mode");
|
||||
Console.WriteLine("-c, --hash Output file hashes");
|
||||
Console.WriteLine("-f, --file Print to file only");
|
||||
#if NETCOREAPP
|
||||
Console.WriteLine("-j, --json Print info as JSON");
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using SabreTools.Hashing;
|
||||
using SabreTools.IO.Extensions;
|
||||
using SabreTools.Serialization;
|
||||
using SabreTools.Serialization.Wrappers;
|
||||
@@ -23,11 +25,7 @@ namespace InfoPrint
|
||||
// Loop through the input paths
|
||||
foreach (string inputPath in options.InputPaths)
|
||||
{
|
||||
#if NETFRAMEWORK
|
||||
PrintPathInfo(inputPath, false, options.Debug);
|
||||
#else
|
||||
PrintPathInfo(inputPath, options.Json, options.Debug);
|
||||
#endif
|
||||
PrintPathInfo(inputPath, options);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -35,22 +33,21 @@ namespace InfoPrint
|
||||
/// Wrapper to print information for a single path
|
||||
/// </summary>
|
||||
/// <param name="path">File or directory path</param>
|
||||
/// <param name="json">Enable JSON output, if supported</param>
|
||||
/// <param name="debug">Enable debug output</param>
|
||||
private static void PrintPathInfo(string path, bool json, bool debug)
|
||||
/// <param name="options">User-defined options</param>
|
||||
private static void PrintPathInfo(string path, Options options)
|
||||
{
|
||||
Console.WriteLine($"Checking possible path: {path}");
|
||||
|
||||
// Check if the file or directory exists
|
||||
if (File.Exists(path))
|
||||
{
|
||||
PrintFileInfo(path, json, debug);
|
||||
PrintFileInfo(path, options);
|
||||
}
|
||||
else if (Directory.Exists(path))
|
||||
{
|
||||
foreach (string file in IOExtensions.SafeEnumerateFiles(path, "*", SearchOption.AllDirectories))
|
||||
{
|
||||
PrintFileInfo(file, json, debug);
|
||||
PrintFileInfo(file, options);
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -62,10 +59,31 @@ namespace InfoPrint
|
||||
/// <summary>
|
||||
/// Print information for a single file, if possible
|
||||
/// </summary>
|
||||
private static void PrintFileInfo(string file, bool json, bool debug)
|
||||
/// <param name="file">File path</param>
|
||||
/// <param name="options">User-defined options</param>
|
||||
private static void PrintFileInfo(string file, Options options)
|
||||
{
|
||||
Console.WriteLine($"Attempting to print info for {file}");
|
||||
|
||||
// Get the base info output name
|
||||
string filenameBase = $"info-{DateTime.Now:yyyy-MM-dd_HHmmss.ffff}";
|
||||
|
||||
// If we have the hash flag
|
||||
if (options.Hash)
|
||||
{
|
||||
var hashBuilder = PrintHashInfo(file, options.Debug);
|
||||
if (hashBuilder != null)
|
||||
{
|
||||
// Create the output data
|
||||
string hashData = hashBuilder.ToString();
|
||||
|
||||
// Write the output data
|
||||
using var hsw = new StreamWriter(File.OpenWrite($"{filenameBase}.hashes"));
|
||||
hsw.WriteLine(hashData);
|
||||
hsw.Flush();
|
||||
}
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
using Stream stream = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
|
||||
@@ -92,20 +110,17 @@ namespace InfoPrint
|
||||
return;
|
||||
}
|
||||
|
||||
// Get the base info output name
|
||||
string filenameBase = $"info-{DateTime.Now:yyyy-MM-dd_HHmmss.ffff}";
|
||||
|
||||
#if NETCOREAPP
|
||||
// If we have the JSON flag
|
||||
if (json)
|
||||
if (options.Json)
|
||||
{
|
||||
// Create the output data
|
||||
string serializedData = wrapper.ExportJSON();
|
||||
Console.WriteLine(serializedData);
|
||||
|
||||
// Write the output data
|
||||
using var jsw = new StreamWriter(File.OpenWrite($"{filenameBase}.json"));
|
||||
jsw.WriteLine(serializedData);
|
||||
jsw.Flush();
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -117,16 +132,79 @@ namespace InfoPrint
|
||||
return;
|
||||
}
|
||||
|
||||
// Write the output data
|
||||
Console.WriteLine(builder);
|
||||
// Only print to console if enabled
|
||||
if (!options.FileOnly)
|
||||
Console.WriteLine(builder);
|
||||
|
||||
using var sw = new StreamWriter(File.OpenWrite($"{filenameBase}.txt"));
|
||||
sw.WriteLine(file);
|
||||
sw.WriteLine();
|
||||
sw.WriteLine(builder.ToString());
|
||||
sw.Flush();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine(options.Debug ? ex : "[Exception opening file, please try again]");
|
||||
Console.WriteLine();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Print hash information for a single file, if possible
|
||||
/// </summary>
|
||||
/// <param name="file">File path</param>
|
||||
/// <param name="debug">Enable debug output</param>
|
||||
/// <returns>StringBuilder representing the hash information, if possible</returns>
|
||||
private static StringBuilder? PrintHashInfo(string file, bool debug)
|
||||
{
|
||||
// Ignore missing files
|
||||
if (!File.Exists(file))
|
||||
return null;
|
||||
|
||||
Console.WriteLine($"Attempting to hash {file}, this may take a while...");
|
||||
|
||||
try
|
||||
{
|
||||
// Get all file hashes for flexibility
|
||||
var hashes = HashTool.GetFileHashes(file);
|
||||
if (hashes == null)
|
||||
{
|
||||
if (debug) Console.WriteLine($"Hashes for {file} could not be retrieved");
|
||||
return null;
|
||||
}
|
||||
|
||||
// Output subset of available hashes
|
||||
var builder = new StringBuilder();
|
||||
if (hashes.TryGetValue(HashType.CRC16, out string? crc16) && crc16 != null)
|
||||
builder.AppendLine($"CRC-16 checksum: {crc16}");
|
||||
if (hashes.TryGetValue(HashType.CRC32, out string? crc32) && crc32 != null)
|
||||
builder.AppendLine($"CRC-32 checksum: {crc32}");
|
||||
if (hashes.TryGetValue(HashType.MD2, out string? md2) && md2 != null)
|
||||
builder.AppendLine($"MD2 hash: {md2}");
|
||||
if (hashes.TryGetValue(HashType.MD4, out string? md4) && md4 != null)
|
||||
builder.AppendLine($"MD4 hash: {md4}");
|
||||
if (hashes.TryGetValue(HashType.MD5, out string? md5) && md5 != null)
|
||||
builder.AppendLine($"MD5 hash: {md5}");
|
||||
if (hashes.TryGetValue(HashType.RIPEMD128, out string? ripemd128) && ripemd128 != null)
|
||||
builder.AppendLine($"RIPEMD-128 hash: {ripemd128}");
|
||||
if (hashes.TryGetValue(HashType.RIPEMD160, out string? ripemd160) && ripemd160 != null)
|
||||
builder.AppendLine($"RIPEMD-160 hash: {ripemd160}");
|
||||
if (hashes.TryGetValue(HashType.SHA1, out string? sha1) && sha1 != null)
|
||||
builder.AppendLine($"SHA-1 hash: {sha1}");
|
||||
if (hashes.TryGetValue(HashType.SHA256, out string? sha256) && sha256 != null)
|
||||
builder.AppendLine($"SHA-256 hash: {sha256}");
|
||||
if (hashes.TryGetValue(HashType.SHA384, out string? sha384) && sha384 != null)
|
||||
builder.AppendLine($"SHA-384 hash: {sha384}");
|
||||
if (hashes.TryGetValue(HashType.SHA512, out string? sha512) && sha512 != null)
|
||||
builder.AppendLine($"SHA-512 hash: {sha512}");
|
||||
|
||||
return builder;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine(debug ? ex : "[Exception opening file, please try again]");
|
||||
Console.WriteLine();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
7
LICENSE
Normal file
7
LICENSE
Normal file
@@ -0,0 +1,7 @@
|
||||
Copyright (c) 2018-2025 Matt Nadareski
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice (including the next paragraph) shall be included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
67
README.MD
67
README.MD
@@ -6,12 +6,78 @@ This library comprises of serializers that both read and write from files and st
|
||||
|
||||
Find the link to the Nuget package [here](https://www.nuget.org/packages/SabreTools.Serialization).
|
||||
|
||||
The following non-project libraries (or ports thereof) are used for file handling:
|
||||
|
||||
- [SharpCompress](https://github.com/adamhathcock/sharpcompress) - Common archive format extraction
|
||||
- [StormLibSharp](https://github.com/robpaveza/stormlibsharp) - MoPaQ extraction [Unused in .NET Framework 2.0/3.5/4.0, non-Windows, and non-x86 builds due to Windows-specific libraries]
|
||||
|
||||
The following projects have influenced this library:
|
||||
|
||||
- [libmspack](https://github.com/kyz/libmspack) - Documentation around the MS-CAB format and associated compression methods.
|
||||
- [Unshield](https://github.com/twogood/unshield/) - InstallShield CAB extraction tool that influenced internal handling
|
||||
|
||||
## Releases
|
||||
|
||||
For the most recent stable build, download the latest release here: [Releases Page](https://github.com/SabreTools/SabreTools.Serialization/releases)
|
||||
|
||||
For the latest WIP build here: [Rolling Release](https://github.com/SabreTools/SabreTools.Serialization/releases/tag/rolling)
|
||||
|
||||
## InfoPrint
|
||||
|
||||
**InfoPrint** is a reference implementation for the deserialization and printing features of the library, packaged as a standalone executable for all supported platforms. It will attempt to detect and display information about many supported file types, optionally both hashing the file and outputting the information to a JSON file (.NET Core 3.1 and above only).
|
||||
|
||||
```
|
||||
InfoPrint <options> file|directory ...
|
||||
|
||||
Options:
|
||||
-?, -h, --help Display this help text and quit
|
||||
-d, --debug Enable debug mode
|
||||
-c, --hash Output file hashes
|
||||
-j, --json Print info as JSON
|
||||
```
|
||||
|
||||
## ExtractionTool
|
||||
|
||||
**ExtractionTool** is a reference implementation for the extraction features of the library, packaged as a standalone executable for all supported platforms. It will attempt to detect and extract many supported file types. See the table below for supported extraction functionality.
|
||||
|
||||
```
|
||||
ExtractionTool.exe <options> file|directory ...
|
||||
|
||||
Options:
|
||||
-?, -h, --help Display this help text and quit
|
||||
-d, --debug Enable debug mode
|
||||
-o, --outdir [PATH] Set output path for extraction (required)
|
||||
```
|
||||
|
||||
| Format Name | Notes |
|
||||
| --- | --- |
|
||||
| 7-zip archive | .NET Framework 4.6.2 and greater |
|
||||
| BFPK custom archive format | |
|
||||
| bzip2 archive | .NET Framework 4.6.2 and greater |
|
||||
| Compound File Binary (CFB) | Only CFB common pieces extractable. .NET Framework 4.0 and greater |
|
||||
| gzip archive | |
|
||||
| Half-Life Game Cache File (GCF) | |
|
||||
| Half-Life Level (BSP) | |
|
||||
| Half-Life Package File (PAK) | |
|
||||
| Half-Life Texture Package File (WAD3) | |
|
||||
| Half-Life 2 Level (VBSP) | |
|
||||
| InstallShield Archive V3 (Z) | |
|
||||
| InstallShield CAB | |
|
||||
| Microsoft cabinet file | Does not support LZX or Quantum compression |
|
||||
| Microsoft LZ-compressed files | KWAJ, QBasic, and SZDD variants |
|
||||
| MoPaQ game data archive (MPQ) | Currently not working. Windows only. .NET Framework 4.5.2 and above |
|
||||
| New Exectuable | Embedded archives and executables in the overlay and Wise installer |
|
||||
| NovaLogic Game Archive Format (PFF) | |
|
||||
| PKZIP and derived files (ZIP, etc.) | .NET Framework 4.6.2 and greater |
|
||||
| Portable Executable | Embedded archives and executables in the resources and overlay, CExe-packed data, SFX archives (7-zip, PKZIP, and RAR), and Wise installer |
|
||||
| Quantum archive (Q) | Currently not working |
|
||||
| RAR archive (RAR) | .NET Framework 4.6.2 and greater |
|
||||
| SGA game archive | |
|
||||
| Tape archive (TAR) | |
|
||||
| Valve Package File (VPK) | |
|
||||
| XBox Package File (XZP) | |
|
||||
| xz archive (XZ) | .NET Framework 4.6.2 and greater |
|
||||
|
||||
## Interfaces
|
||||
|
||||
Below is a table representing the various conversion interfaces that are implemented within this library.
|
||||
@@ -32,6 +98,7 @@ Below is a table representing the various non-conversion interfaces that are imp
|
||||
|
||||
| Interface Name | Purpose |
|
||||
| --- | --- |
|
||||
| `IExtractable` | Marks a wrapper as able to be extracted |
|
||||
| `IPrinter` | Provides a formatted output for a model |
|
||||
| `IWrapper` / `IWrapper<T>` | Wraps a model or set of models to provide additional functionality |
|
||||
|
||||
|
||||
@@ -28,10 +28,11 @@ namespace SabreTools.Serialization.Test.CrossModel
|
||||
Validate(newDf.Header);
|
||||
|
||||
Assert.NotNull(newDf.Game);
|
||||
var newGame = Assert.Single(newDf.Game);
|
||||
Validate(newGame);
|
||||
Assert.Equal(2, newDf.Game.Length);
|
||||
Validate(newDf.Game[0], nested: false);
|
||||
Validate(newDf.Game[1], nested: true);
|
||||
|
||||
// TODO: Unsupported
|
||||
// TODO: Unsupported for round-trip
|
||||
Assert.Null(newDf.Dir);
|
||||
}
|
||||
|
||||
@@ -59,10 +60,11 @@ namespace SabreTools.Serialization.Test.CrossModel
|
||||
Validate(newDf.Header);
|
||||
|
||||
Assert.NotNull(newDf.Game);
|
||||
var newGame = Assert.Single(newDf.Game);
|
||||
Validate(newGame);
|
||||
Assert.Equal(2, newDf.Game.Length);
|
||||
Validate(newDf.Game[0], nested: false);
|
||||
Validate(newDf.Game[1], nested: true);
|
||||
|
||||
// TODO: Unsupported
|
||||
// TODO: Unsupported for round-trip
|
||||
Assert.Null(newDf.Dir);
|
||||
}
|
||||
|
||||
@@ -253,6 +255,18 @@ namespace SabreTools.Serialization.Test.CrossModel
|
||||
gameBase.Driver = driver;
|
||||
gameBase.SoftwareList = [softwarelist];
|
||||
|
||||
var subdir = new Models.Logiqx.Dir
|
||||
{
|
||||
Name = "XXXXXX",
|
||||
Game = [gameBase],
|
||||
};
|
||||
|
||||
var dir = new Models.Logiqx.Dir
|
||||
{
|
||||
Name = "XXXXXX",
|
||||
Subdir = [subdir],
|
||||
};
|
||||
|
||||
return new Models.Logiqx.Datafile
|
||||
{
|
||||
Build = "XXXXXX",
|
||||
@@ -260,7 +274,7 @@ namespace SabreTools.Serialization.Test.CrossModel
|
||||
SchemaLocation = "XXXXXX",
|
||||
Header = header,
|
||||
Game = [gameBase],
|
||||
// Dir = [dir], // TODO: Unsupported
|
||||
Dir = [dir],
|
||||
};
|
||||
}
|
||||
|
||||
@@ -317,10 +331,13 @@ namespace SabreTools.Serialization.Test.CrossModel
|
||||
/// <summary>
|
||||
/// Validate a GameBase
|
||||
/// </summary>
|
||||
private static void Validate(Models.Logiqx.GameBase? gb)
|
||||
private static void Validate(Models.Logiqx.GameBase? gb, bool nested)
|
||||
{
|
||||
Assert.NotNull(gb);
|
||||
Assert.Equal("XXXXXX", gb.Name);
|
||||
if (nested)
|
||||
Assert.Equal("XXXXXX\\XXXXXX\\XXXXXX", gb.Name);
|
||||
else
|
||||
Assert.Equal("XXXXXX", gb.Name);
|
||||
Assert.Equal("XXXXXX", gb.SourceFile);
|
||||
Assert.Equal("XXXXXX", gb.IsBios);
|
||||
Assert.Equal("XXXXXX", gb.IsDevice);
|
||||
|
||||
872
SabreTools.Serialization.Test/CrossModel/MessTests.cs
Normal file
872
SabreTools.Serialization.Test/CrossModel/MessTests.cs
Normal file
@@ -0,0 +1,872 @@
|
||||
using Xunit;
|
||||
|
||||
namespace SabreTools.Serialization.Test.CrossModel
|
||||
{
|
||||
public class MessTests
|
||||
{
|
||||
[Fact]
|
||||
public void RoundTripGameTest()
|
||||
{
|
||||
// Get the cross-model serializer
|
||||
var serializer = new Serialization.CrossModel.Mess();
|
||||
|
||||
// Build the data
|
||||
Models.Listxml.Mess m1 = Build(game: true);
|
||||
|
||||
// Serialize to generic model
|
||||
Models.Metadata.MetadataFile? metadata = serializer.Serialize(m1);
|
||||
Assert.NotNull(metadata);
|
||||
|
||||
// Serialize back to original model
|
||||
Models.Listxml.Mess? newMess = serializer.Deserialize(metadata);
|
||||
|
||||
// Validate the data
|
||||
Assert.NotNull(newMess);
|
||||
Assert.Equal("XXXXXX", newMess.Version);
|
||||
|
||||
Assert.NotNull(newMess.Game);
|
||||
var newGame = Assert.Single(newMess.Game);
|
||||
Validate(newGame);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void RoundTripMachineTest()
|
||||
{
|
||||
// Get the cross-model serializer
|
||||
var serializer = new Serialization.CrossModel.Mess();
|
||||
|
||||
// Build the data
|
||||
Models.Listxml.Mess m1 = Build(game: false);
|
||||
|
||||
// Serialize to generic model
|
||||
Models.Metadata.MetadataFile? metadata = serializer.Serialize(m1);
|
||||
Assert.NotNull(metadata);
|
||||
|
||||
// Serialize back to original model
|
||||
Models.Listxml.Mess? newMess = serializer.Deserialize(metadata);
|
||||
|
||||
// Validate the data
|
||||
Assert.NotNull(newMess);
|
||||
Assert.Equal("XXXXXX", newMess.Version);
|
||||
|
||||
Assert.NotNull(newMess.Game);
|
||||
var newGame = Assert.Single(newMess.Game);
|
||||
Validate(newGame);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Build model for serialization and deserialization
|
||||
/// </summary>
|
||||
private static Models.Listxml.Mess Build(bool game)
|
||||
{
|
||||
var biosset = new Models.Listxml.BiosSet
|
||||
{
|
||||
Name = "XXXXXX",
|
||||
Description = "XXXXXX",
|
||||
Default = "XXXXXX",
|
||||
};
|
||||
|
||||
var rom = new Models.Listxml.Rom
|
||||
{
|
||||
Name = "XXXXXX",
|
||||
Bios = "XXXXXX",
|
||||
Size = "XXXXXX",
|
||||
CRC = "XXXXXX",
|
||||
SHA1 = "XXXXXX",
|
||||
Merge = "XXXXXX",
|
||||
Region = "XXXXXX",
|
||||
Offset = "XXXXXX",
|
||||
Status = "XXXXXX",
|
||||
Optional = "XXXXXX",
|
||||
Dispose = "XXXXXX",
|
||||
SoundOnly = "XXXXXX",
|
||||
};
|
||||
|
||||
var disk = new Models.Listxml.Disk
|
||||
{
|
||||
Name = "XXXXXX",
|
||||
MD5 = "XXXXXX",
|
||||
SHA1 = "XXXXXX",
|
||||
Merge = "XXXXXX",
|
||||
Region = "XXXXXX",
|
||||
Index = "XXXXXX",
|
||||
Writable = "XXXXXX",
|
||||
Status = "XXXXXX",
|
||||
Optional = "XXXXXX",
|
||||
};
|
||||
|
||||
var deviceref = new Models.Listxml.DeviceRef
|
||||
{
|
||||
Name = "XXXXXX",
|
||||
};
|
||||
|
||||
var sample = new Models.Listxml.Sample
|
||||
{
|
||||
Name = "XXXXXX",
|
||||
};
|
||||
|
||||
var chip = new Models.Listxml.Chip
|
||||
{
|
||||
Name = "XXXXXX",
|
||||
Tag = "XXXXXX",
|
||||
Type = "XXXXXX",
|
||||
SoundOnly = "XXXXXX",
|
||||
Clock = "XXXXXX",
|
||||
};
|
||||
|
||||
var display = new Models.Listxml.Display
|
||||
{
|
||||
Tag = "XXXXXX",
|
||||
Type = "XXXXXX",
|
||||
Rotate = "XXXXXX",
|
||||
FlipX = "XXXXXX",
|
||||
Width = "XXXXXX",
|
||||
Height = "XXXXXX",
|
||||
Refresh = "XXXXXX",
|
||||
PixClock = "XXXXXX",
|
||||
HTotal = "XXXXXX",
|
||||
HBEnd = "XXXXXX",
|
||||
HBStart = "XXXXXX",
|
||||
VTotal = "XXXXXX",
|
||||
VBEnd = "XXXXXX",
|
||||
VBStart = "XXXXXX",
|
||||
};
|
||||
|
||||
var video = new Models.Listxml.Video
|
||||
{
|
||||
Screen = "XXXXXX",
|
||||
Orientation = "XXXXXX",
|
||||
Width = "XXXXXX",
|
||||
Height = "XXXXXX",
|
||||
AspectX = "XXXXXX",
|
||||
AspectY = "XXXXXX",
|
||||
Refresh = "XXXXXX",
|
||||
};
|
||||
|
||||
var sound = new Models.Listxml.Sound
|
||||
{
|
||||
Channels = "XXXXXX",
|
||||
};
|
||||
|
||||
var control = new Models.Listxml.Control
|
||||
{
|
||||
Type = "XXXXXX",
|
||||
Player = "XXXXXX",
|
||||
Buttons = "XXXXXX",
|
||||
ReqButtons = "XXXXXX",
|
||||
Minimum = "XXXXXX",
|
||||
Maximum = "XXXXXX",
|
||||
Sensitivity = "XXXXXX",
|
||||
KeyDelta = "XXXXXX",
|
||||
Reverse = "XXXXXX",
|
||||
Ways = "XXXXXX",
|
||||
Ways2 = "XXXXXX",
|
||||
Ways3 = "XXXXXX",
|
||||
};
|
||||
|
||||
var input = new Models.Listxml.Input
|
||||
{
|
||||
Service = "XXXXXX",
|
||||
Tilt = "XXXXXX",
|
||||
Players = "XXXXXX",
|
||||
//ControlAttr = "XXXXXX", // Mututally exclusive with input.Control
|
||||
Buttons = "XXXXXX",
|
||||
Coins = "XXXXXX",
|
||||
Control = [control],
|
||||
};
|
||||
|
||||
var condition = new Models.Listxml.Condition
|
||||
{
|
||||
Tag = "XXXXXX",
|
||||
Mask = "XXXXXX",
|
||||
Relation = "XXXXXX",
|
||||
Value = "XXXXXX",
|
||||
};
|
||||
|
||||
var diplocation = new Models.Listxml.DipLocation
|
||||
{
|
||||
Name = "XXXXXX",
|
||||
Number = "XXXXXX",
|
||||
Inverted = "XXXXXX",
|
||||
};
|
||||
|
||||
var dipvalue = new Models.Listxml.DipValue
|
||||
{
|
||||
Name = "XXXXXX",
|
||||
Value = "XXXXXX",
|
||||
Default = "XXXXXX",
|
||||
Condition = condition,
|
||||
};
|
||||
|
||||
var dipswitch = new Models.Listxml.DipSwitch
|
||||
{
|
||||
Name = "XXXXXX",
|
||||
Tag = "XXXXXX",
|
||||
Mask = "XXXXXX",
|
||||
Condition = condition,
|
||||
DipLocation = [diplocation],
|
||||
DipValue = [dipvalue],
|
||||
};
|
||||
|
||||
var conflocation = new Models.Listxml.ConfLocation
|
||||
{
|
||||
Name = "XXXXXX",
|
||||
Number = "XXXXXX",
|
||||
Inverted = "XXXXXX",
|
||||
};
|
||||
|
||||
var confsetting = new Models.Listxml.ConfSetting
|
||||
{
|
||||
Name = "XXXXXX",
|
||||
Value = "XXXXXX",
|
||||
Default = "XXXXXX",
|
||||
Condition = condition,
|
||||
};
|
||||
|
||||
var configuration = new Models.Listxml.Configuration
|
||||
{
|
||||
Name = "XXXXXX",
|
||||
Tag = "XXXXXX",
|
||||
Mask = "XXXXXX",
|
||||
Condition = condition,
|
||||
ConfLocation = [conflocation],
|
||||
ConfSetting = [confsetting],
|
||||
};
|
||||
|
||||
var analog = new Models.Listxml.Analog
|
||||
{
|
||||
Mask = "XXXXXX",
|
||||
};
|
||||
|
||||
var port = new Models.Listxml.Port
|
||||
{
|
||||
Tag = "XXXXXX",
|
||||
Analog = [analog],
|
||||
};
|
||||
|
||||
var adjuster = new Models.Listxml.Adjuster
|
||||
{
|
||||
Name = "XXXXXX",
|
||||
Default = "XXXXXX",
|
||||
Condition = condition,
|
||||
};
|
||||
|
||||
var driver = new Models.Listxml.Driver
|
||||
{
|
||||
Status = "XXXXXX",
|
||||
Color = "XXXXXX",
|
||||
Sound = "XXXXXX",
|
||||
PaletteSize = "XXXXXX",
|
||||
Emulation = "XXXXXX",
|
||||
Cocktail = "XXXXXX",
|
||||
SaveState = "XXXXXX",
|
||||
RequiresArtwork = "XXXXXX",
|
||||
Unofficial = "XXXXXX",
|
||||
NoSoundHardware = "XXXXXX",
|
||||
Incomplete = "XXXXXX",
|
||||
};
|
||||
|
||||
var feature = new Models.Listxml.Feature
|
||||
{
|
||||
Type = "XXXXXX",
|
||||
Status = "XXXXXX",
|
||||
Overall = "XXXXXX",
|
||||
};
|
||||
|
||||
var instance = new Models.Listxml.Instance
|
||||
{
|
||||
Name = "XXXXXX",
|
||||
BriefName = "XXXXXX",
|
||||
};
|
||||
|
||||
var extension = new Models.Listxml.Extension
|
||||
{
|
||||
Name = "XXXXXX",
|
||||
};
|
||||
|
||||
var device = new Models.Listxml.Device
|
||||
{
|
||||
Type = "XXXXXX",
|
||||
Tag = "XXXXXX",
|
||||
FixedImage = "XXXXXX",
|
||||
Mandatory = "XXXXXX",
|
||||
Interface = "XXXXXX",
|
||||
Instance = instance,
|
||||
Extension = [extension],
|
||||
};
|
||||
|
||||
var slotOption = new Models.Listxml.SlotOption
|
||||
{
|
||||
Name = "XXXXXX",
|
||||
DevName = "XXXXXX",
|
||||
Default = "XXXXXX",
|
||||
};
|
||||
|
||||
var slot = new Models.Listxml.Slot
|
||||
{
|
||||
Name = "XXXXXX",
|
||||
SlotOption = [slotOption],
|
||||
};
|
||||
|
||||
var softwarelist = new Models.Listxml.SoftwareList
|
||||
{
|
||||
Tag = "XXXXXX",
|
||||
Name = "XXXXXX",
|
||||
Status = "XXXXXX",
|
||||
Filter = "XXXXXX",
|
||||
};
|
||||
|
||||
var ramoption = new Models.Listxml.RamOption
|
||||
{
|
||||
Name = "XXXXXX",
|
||||
Default = "XXXXXX",
|
||||
Content = "XXXXXX",
|
||||
};
|
||||
|
||||
Models.Listxml.GameBase gameBase = game
|
||||
? new Models.Listxml.Game()
|
||||
: new Models.Listxml.Machine();
|
||||
gameBase.Name = "XXXXXX";
|
||||
gameBase.SourceFile = "XXXXXX";
|
||||
gameBase.IsBios = "XXXXXX";
|
||||
gameBase.IsDevice = "XXXXXX";
|
||||
gameBase.IsMechanical = "XXXXXX";
|
||||
gameBase.Runnable = "XXXXXX";
|
||||
gameBase.CloneOf = "XXXXXX";
|
||||
gameBase.RomOf = "XXXXXX";
|
||||
gameBase.SampleOf = "XXXXXX";
|
||||
gameBase.Description = "XXXXXX";
|
||||
gameBase.Year = "XXXXXX";
|
||||
gameBase.Manufacturer = "XXXXXX";
|
||||
gameBase.History = "XXXXXX";
|
||||
gameBase.BiosSet = [biosset];
|
||||
gameBase.Rom = [rom];
|
||||
gameBase.Disk = [disk];
|
||||
gameBase.DeviceRef = [deviceref];
|
||||
gameBase.Sample = [sample];
|
||||
gameBase.Chip = [chip];
|
||||
gameBase.Display = [display];
|
||||
gameBase.Video = [video];
|
||||
gameBase.Sound = sound;
|
||||
gameBase.Input = input;
|
||||
gameBase.DipSwitch = [dipswitch];
|
||||
gameBase.Configuration = [configuration];
|
||||
gameBase.Port = [port];
|
||||
gameBase.Adjuster = [adjuster];
|
||||
gameBase.Driver = driver;
|
||||
gameBase.Feature = [feature];
|
||||
gameBase.Device = [device];
|
||||
gameBase.Slot = [slot];
|
||||
gameBase.SoftwareList = [softwarelist];
|
||||
gameBase.RamOption = [ramoption];
|
||||
|
||||
return new Models.Listxml.Mess
|
||||
{
|
||||
Version = "XXXXXX",
|
||||
Game = [gameBase],
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Validate a GameBase
|
||||
/// </summary>
|
||||
private static void Validate(Models.Listxml.GameBase? gb)
|
||||
{
|
||||
Assert.NotNull(gb);
|
||||
Assert.Equal("XXXXXX", gb.Name);
|
||||
Assert.Equal("XXXXXX", gb.SourceFile);
|
||||
Assert.Equal("XXXXXX", gb.IsBios);
|
||||
Assert.Equal("XXXXXX", gb.IsDevice);
|
||||
Assert.Equal("XXXXXX", gb.IsMechanical);
|
||||
Assert.Equal("XXXXXX", gb.Runnable);
|
||||
Assert.Equal("XXXXXX", gb.CloneOf);
|
||||
Assert.Equal("XXXXXX", gb.RomOf);
|
||||
Assert.Equal("XXXXXX", gb.SampleOf);
|
||||
Assert.Equal("XXXXXX", gb.Description);
|
||||
Assert.Equal("XXXXXX", gb.Year);
|
||||
Assert.Equal("XXXXXX", gb.Manufacturer);
|
||||
Assert.Equal("XXXXXX", gb.History);
|
||||
|
||||
Assert.NotNull(gb.BiosSet);
|
||||
var biosset = Assert.Single(gb.BiosSet);
|
||||
Validate(biosset);
|
||||
|
||||
Assert.NotNull(gb.Rom);
|
||||
var rom = Assert.Single(gb.Rom);
|
||||
Validate(rom);
|
||||
|
||||
Assert.NotNull(gb.Disk);
|
||||
var disk = Assert.Single(gb.Disk);
|
||||
Validate(disk);
|
||||
|
||||
Assert.NotNull(gb.DeviceRef);
|
||||
var deviceref = Assert.Single(gb.DeviceRef);
|
||||
Validate(deviceref);
|
||||
|
||||
Assert.NotNull(gb.Sample);
|
||||
var sample = Assert.Single(gb.Sample);
|
||||
Validate(sample);
|
||||
|
||||
Assert.NotNull(gb.Chip);
|
||||
var chip = Assert.Single(gb.Chip);
|
||||
Validate(chip);
|
||||
|
||||
Assert.NotNull(gb.Display);
|
||||
var display = Assert.Single(gb.Display);
|
||||
Validate(display);
|
||||
|
||||
Assert.NotNull(gb.Video);
|
||||
var video = Assert.Single(gb.Video);
|
||||
Validate(video);
|
||||
|
||||
Validate(gb.Sound);
|
||||
Validate(gb.Input);
|
||||
|
||||
Assert.NotNull(gb.DipSwitch);
|
||||
var dipswitch = Assert.Single(gb.DipSwitch);
|
||||
Validate(dipswitch);
|
||||
|
||||
Assert.NotNull(gb.Configuration);
|
||||
var configuration = Assert.Single(gb.Configuration);
|
||||
Validate(configuration);
|
||||
|
||||
Assert.NotNull(gb.Port);
|
||||
var port = Assert.Single(gb.Port);
|
||||
Validate(port);
|
||||
|
||||
Assert.NotNull(gb.Adjuster);
|
||||
var adjuster = Assert.Single(gb.Adjuster);
|
||||
Validate(adjuster);
|
||||
|
||||
Validate(gb.Driver);
|
||||
|
||||
Assert.NotNull(gb.Feature);
|
||||
var feature = Assert.Single(gb.Feature);
|
||||
Validate(feature);
|
||||
|
||||
Assert.NotNull(gb.Device);
|
||||
var device = Assert.Single(gb.Device);
|
||||
Validate(device);
|
||||
|
||||
Assert.NotNull(gb.Slot);
|
||||
var slot = Assert.Single(gb.Slot);
|
||||
Validate(slot);
|
||||
|
||||
Assert.NotNull(gb.SoftwareList);
|
||||
var softwarelist = Assert.Single(gb.SoftwareList);
|
||||
Validate(softwarelist);
|
||||
|
||||
Assert.NotNull(gb.RamOption);
|
||||
var ramoption = Assert.Single(gb.RamOption);
|
||||
Validate(ramoption);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Validate a BiosSet
|
||||
/// </summary>
|
||||
private static void Validate(Models.Listxml.BiosSet? biosset)
|
||||
{
|
||||
Assert.NotNull(biosset);
|
||||
Assert.Equal("XXXXXX", biosset.Name);
|
||||
Assert.Equal("XXXXXX", biosset.Description);
|
||||
Assert.Equal("XXXXXX", biosset.Default);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Validate a Rom
|
||||
/// </summary>
|
||||
private static void Validate(Models.Listxml.Rom? rom)
|
||||
{
|
||||
Assert.NotNull(rom);
|
||||
Assert.Equal("XXXXXX", rom.Name);
|
||||
Assert.Equal("XXXXXX", rom.Bios);
|
||||
Assert.Equal("XXXXXX", rom.Size);
|
||||
Assert.Equal("XXXXXX", rom.CRC);
|
||||
Assert.Equal("XXXXXX", rom.SHA1);
|
||||
Assert.Equal("XXXXXX", rom.Merge);
|
||||
Assert.Equal("XXXXXX", rom.Region);
|
||||
Assert.Equal("XXXXXX", rom.Offset);
|
||||
Assert.Equal("XXXXXX", rom.Status);
|
||||
Assert.Equal("XXXXXX", rom.Optional);
|
||||
Assert.Equal("XXXXXX", rom.Dispose);
|
||||
Assert.Equal("XXXXXX", rom.SoundOnly);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Validate a Disk
|
||||
/// </summary>
|
||||
private static void Validate(Models.Listxml.Disk? disk)
|
||||
{
|
||||
Assert.NotNull(disk);
|
||||
Assert.Equal("XXXXXX", disk.Name);
|
||||
Assert.Equal("XXXXXX", disk.MD5);
|
||||
Assert.Equal("XXXXXX", disk.SHA1);
|
||||
Assert.Equal("XXXXXX", disk.Merge);
|
||||
Assert.Equal("XXXXXX", disk.Region);
|
||||
Assert.Equal("XXXXXX", disk.Index);
|
||||
Assert.Equal("XXXXXX", disk.Writable);
|
||||
Assert.Equal("XXXXXX", disk.Status);
|
||||
Assert.Equal("XXXXXX", disk.Optional);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Validate a DeviceRef
|
||||
/// </summary>
|
||||
private static void Validate(Models.Listxml.DeviceRef? deviceref)
|
||||
{
|
||||
Assert.NotNull(deviceref);
|
||||
Assert.Equal("XXXXXX", deviceref.Name);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Validate a Sample
|
||||
/// </summary>
|
||||
private static void Validate(Models.Listxml.Sample? sample)
|
||||
{
|
||||
Assert.NotNull(sample);
|
||||
Assert.Equal("XXXXXX", sample.Name);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Validate a Chip
|
||||
/// </summary>
|
||||
private static void Validate(Models.Listxml.Chip? chip)
|
||||
{
|
||||
Assert.NotNull(chip);
|
||||
Assert.Equal("XXXXXX", chip.Name);
|
||||
Assert.Equal("XXXXXX", chip.Tag);
|
||||
Assert.Equal("XXXXXX", chip.Type);
|
||||
Assert.Equal("XXXXXX", chip.SoundOnly);
|
||||
Assert.Equal("XXXXXX", chip.Clock);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Validate a Display
|
||||
/// </summary>
|
||||
private static void Validate(Models.Listxml.Display? display)
|
||||
{
|
||||
Assert.NotNull(display);
|
||||
Assert.Equal("XXXXXX", display.Tag);
|
||||
Assert.Equal("XXXXXX", display.Type);
|
||||
Assert.Equal("XXXXXX", display.Rotate);
|
||||
Assert.Equal("XXXXXX", display.FlipX);
|
||||
Assert.Equal("XXXXXX", display.Width);
|
||||
Assert.Equal("XXXXXX", display.Height);
|
||||
Assert.Equal("XXXXXX", display.Refresh);
|
||||
Assert.Equal("XXXXXX", display.PixClock);
|
||||
Assert.Equal("XXXXXX", display.HTotal);
|
||||
Assert.Equal("XXXXXX", display.HBEnd);
|
||||
Assert.Equal("XXXXXX", display.HBStart);
|
||||
Assert.Equal("XXXXXX", display.VTotal);
|
||||
Assert.Equal("XXXXXX", display.VBEnd);
|
||||
Assert.Equal("XXXXXX", display.VBStart);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Validate a Video
|
||||
/// </summary>
|
||||
private static void Validate(Models.Listxml.Video? video)
|
||||
{
|
||||
Assert.NotNull(video);
|
||||
Assert.Equal("XXXXXX", video.Screen);
|
||||
Assert.Equal("XXXXXX", video.Orientation);
|
||||
Assert.Equal("XXXXXX", video.Width);
|
||||
Assert.Equal("XXXXXX", video.Height);
|
||||
Assert.Equal("XXXXXX", video.AspectX);
|
||||
Assert.Equal("XXXXXX", video.AspectY);
|
||||
Assert.Equal("XXXXXX", video.Refresh);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Validate a Sound
|
||||
/// </summary>
|
||||
private static void Validate(Models.Listxml.Sound? sound)
|
||||
{
|
||||
Assert.NotNull(sound);
|
||||
Assert.Equal("XXXXXX", sound.Channels);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Validate a Input
|
||||
/// </summary>
|
||||
private static void Validate(Models.Listxml.Input? input)
|
||||
{
|
||||
Assert.NotNull(input);
|
||||
Assert.Equal("XXXXXX", input.Service);
|
||||
Assert.Equal("XXXXXX", input.Tilt);
|
||||
Assert.Equal("XXXXXX", input.Players);
|
||||
//Assert.Equal("XXXXXX", input.ControlAttr); // Mututally exclusive with input.Control
|
||||
Assert.Equal("XXXXXX", input.Buttons);
|
||||
Assert.Equal("XXXXXX", input.Coins);
|
||||
|
||||
Assert.NotNull(input.Control);
|
||||
var control = Assert.Single(input.Control);
|
||||
Validate(control);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Validate a Control
|
||||
/// </summary>
|
||||
private static void Validate(Models.Listxml.Control? control)
|
||||
{
|
||||
Assert.NotNull(control);
|
||||
Assert.Equal("XXXXXX", control.Type);
|
||||
Assert.Equal("XXXXXX", control.Player);
|
||||
Assert.Equal("XXXXXX", control.Buttons);
|
||||
Assert.Equal("XXXXXX", control.ReqButtons);
|
||||
Assert.Equal("XXXXXX", control.Minimum);
|
||||
Assert.Equal("XXXXXX", control.Maximum);
|
||||
Assert.Equal("XXXXXX", control.Sensitivity);
|
||||
Assert.Equal("XXXXXX", control.KeyDelta);
|
||||
Assert.Equal("XXXXXX", control.Reverse);
|
||||
Assert.Equal("XXXXXX", control.Ways);
|
||||
Assert.Equal("XXXXXX", control.Ways2);
|
||||
Assert.Equal("XXXXXX", control.Ways3);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Validate a DipSwitch
|
||||
/// </summary>
|
||||
private static void Validate(Models.Listxml.DipSwitch? dipswitch)
|
||||
{
|
||||
Assert.NotNull(dipswitch);
|
||||
Assert.Equal("XXXXXX", dipswitch.Name);
|
||||
Assert.Equal("XXXXXX", dipswitch.Tag);
|
||||
Assert.Equal("XXXXXX", dipswitch.Mask);
|
||||
Validate(dipswitch.Condition);
|
||||
|
||||
Assert.NotNull(dipswitch.DipLocation);
|
||||
var diplocation = Assert.Single(dipswitch.DipLocation);
|
||||
Validate(diplocation);
|
||||
|
||||
Assert.NotNull(dipswitch.DipValue);
|
||||
var dipvalue = Assert.Single(dipswitch.DipValue);
|
||||
Validate(dipvalue);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Validate a Condition
|
||||
/// </summary>
|
||||
private static void Validate(Models.Listxml.Condition? condition)
|
||||
{
|
||||
Assert.NotNull(condition);
|
||||
Assert.Equal("XXXXXX", condition.Tag);
|
||||
Assert.Equal("XXXXXX", condition.Mask);
|
||||
Assert.Equal("XXXXXX", condition.Relation);
|
||||
Assert.Equal("XXXXXX", condition.Value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Validate a DipLocation
|
||||
/// </summary>
|
||||
private static void Validate(Models.Listxml.DipLocation? diplocation)
|
||||
{
|
||||
Assert.NotNull(diplocation);
|
||||
Assert.Equal("XXXXXX", diplocation.Name);
|
||||
Assert.Equal("XXXXXX", diplocation.Number);
|
||||
Assert.Equal("XXXXXX", diplocation.Inverted);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Validate a DipValue
|
||||
/// </summary>
|
||||
private static void Validate(Models.Listxml.DipValue? dipvalue)
|
||||
{
|
||||
Assert.NotNull(dipvalue);
|
||||
Assert.Equal("XXXXXX", dipvalue.Name);
|
||||
Assert.Equal("XXXXXX", dipvalue.Value);
|
||||
Assert.Equal("XXXXXX", dipvalue.Default);
|
||||
Validate(dipvalue.Condition);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Validate a Configuration
|
||||
/// </summary>
|
||||
private static void Validate(Models.Listxml.Configuration? configuration)
|
||||
{
|
||||
Assert.NotNull(configuration);
|
||||
Assert.Equal("XXXXXX", configuration.Name);
|
||||
Assert.Equal("XXXXXX", configuration.Tag);
|
||||
Assert.Equal("XXXXXX", configuration.Mask);
|
||||
Validate(configuration.Condition);
|
||||
|
||||
Assert.NotNull(configuration.ConfLocation);
|
||||
var conflocation = Assert.Single(configuration.ConfLocation);
|
||||
Validate(conflocation);
|
||||
|
||||
Assert.NotNull(configuration.ConfSetting);
|
||||
var confsetting = Assert.Single(configuration.ConfSetting);
|
||||
Validate(confsetting);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Validate a ConfLocation
|
||||
/// </summary>
|
||||
private static void Validate(Models.Listxml.ConfLocation? conflocation)
|
||||
{
|
||||
Assert.NotNull(conflocation);
|
||||
Assert.Equal("XXXXXX", conflocation.Name);
|
||||
Assert.Equal("XXXXXX", conflocation.Number);
|
||||
Assert.Equal("XXXXXX", conflocation.Inverted);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Validate a ConfSetting
|
||||
/// </summary>
|
||||
private static void Validate(Models.Listxml.ConfSetting? confsetting)
|
||||
{
|
||||
Assert.NotNull(confsetting);
|
||||
Assert.Equal("XXXXXX", confsetting.Name);
|
||||
Assert.Equal("XXXXXX", confsetting.Value);
|
||||
Assert.Equal("XXXXXX", confsetting.Default);
|
||||
Validate(confsetting.Condition);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Validate a Port
|
||||
/// </summary>
|
||||
private static void Validate(Models.Listxml.Port? port)
|
||||
{
|
||||
Assert.NotNull(port);
|
||||
Assert.Equal("XXXXXX", port.Tag);
|
||||
|
||||
Assert.NotNull(port.Analog);
|
||||
var analog = Assert.Single(port.Analog);
|
||||
Validate(analog);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Validate a Analog
|
||||
/// </summary>
|
||||
private static void Validate(Models.Listxml.Analog? analog)
|
||||
{
|
||||
Assert.NotNull(analog);
|
||||
Assert.Equal("XXXXXX", analog.Mask);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Validate a Adjuster
|
||||
/// </summary>
|
||||
private static void Validate(Models.Listxml.Adjuster? adjuster)
|
||||
{
|
||||
Assert.NotNull(adjuster);
|
||||
Assert.Equal("XXXXXX", adjuster.Name);
|
||||
Assert.Equal("XXXXXX", adjuster.Default);
|
||||
Validate(adjuster.Condition);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Validate a Driver
|
||||
/// </summary>
|
||||
private static void Validate(Models.Listxml.Driver? driver)
|
||||
{
|
||||
Assert.NotNull(driver);
|
||||
Assert.Equal("XXXXXX", driver.Status);
|
||||
Assert.Equal("XXXXXX", driver.Color);
|
||||
Assert.Equal("XXXXXX", driver.Sound);
|
||||
Assert.Equal("XXXXXX", driver.PaletteSize);
|
||||
Assert.Equal("XXXXXX", driver.Emulation);
|
||||
Assert.Equal("XXXXXX", driver.Cocktail);
|
||||
Assert.Equal("XXXXXX", driver.SaveState);
|
||||
Assert.Equal("XXXXXX", driver.RequiresArtwork);
|
||||
Assert.Equal("XXXXXX", driver.Unofficial);
|
||||
Assert.Equal("XXXXXX", driver.NoSoundHardware);
|
||||
Assert.Equal("XXXXXX", driver.Incomplete);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Validate a Feature
|
||||
/// </summary>
|
||||
private static void Validate(Models.Listxml.Feature? feature)
|
||||
{
|
||||
Assert.NotNull(feature);
|
||||
Assert.Equal("XXXXXX", feature.Type);
|
||||
Assert.Equal("XXXXXX", feature.Status);
|
||||
Assert.Equal("XXXXXX", feature.Overall);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Validate a Device
|
||||
/// </summary>
|
||||
private static void Validate(Models.Listxml.Device? device)
|
||||
{
|
||||
Assert.NotNull(device);
|
||||
Assert.Equal("XXXXXX", device.Type);
|
||||
Assert.Equal("XXXXXX", device.Tag);
|
||||
Assert.Equal("XXXXXX", device.FixedImage);
|
||||
Assert.Equal("XXXXXX", device.Mandatory);
|
||||
Assert.Equal("XXXXXX", device.Interface);
|
||||
Validate(device.Instance);
|
||||
|
||||
Assert.NotNull(device.Extension);
|
||||
var extension = Assert.Single(device.Extension);
|
||||
Validate(extension);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Validate a Instance
|
||||
/// </summary>
|
||||
private static void Validate(Models.Listxml.Instance? instance)
|
||||
{
|
||||
Assert.NotNull(instance);
|
||||
Assert.Equal("XXXXXX", instance.Name);
|
||||
Assert.Equal("XXXXXX", instance.BriefName);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Validate a Extension
|
||||
/// </summary>
|
||||
private static void Validate(Models.Listxml.Extension? extension)
|
||||
{
|
||||
Assert.NotNull(extension);
|
||||
Assert.Equal("XXXXXX", extension.Name);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Validate a Slot
|
||||
/// </summary>
|
||||
private static void Validate(Models.Listxml.Slot? slot)
|
||||
{
|
||||
Assert.NotNull(slot);
|
||||
Assert.Equal("XXXXXX", slot.Name);
|
||||
|
||||
Assert.NotNull(slot.SlotOption);
|
||||
var slotoption = Assert.Single(slot.SlotOption);
|
||||
Validate(slotoption);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Validate a SlotOption
|
||||
/// </summary>
|
||||
private static void Validate(Models.Listxml.SlotOption? slotoption)
|
||||
{
|
||||
Assert.NotNull(slotoption);
|
||||
Assert.Equal("XXXXXX", slotoption.Name);
|
||||
Assert.Equal("XXXXXX", slotoption.DevName);
|
||||
Assert.Equal("XXXXXX", slotoption.Default);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Validate a SoftwareList
|
||||
/// </summary>
|
||||
private static void Validate(Models.Listxml.SoftwareList? softwarelist)
|
||||
{
|
||||
Assert.NotNull(softwarelist);
|
||||
Assert.Equal("XXXXXX", softwarelist.Tag);
|
||||
Assert.Equal("XXXXXX", softwarelist.Name);
|
||||
Assert.Equal("XXXXXX", softwarelist.Status);
|
||||
Assert.Equal("XXXXXX", softwarelist.Filter);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Validate a RamOption
|
||||
/// </summary>
|
||||
private static void Validate(Models.Listxml.RamOption? ramoption)
|
||||
{
|
||||
Assert.NotNull(ramoption);
|
||||
Assert.Equal("XXXXXX", ramoption.Name);
|
||||
Assert.Equal("XXXXXX", ramoption.Default);
|
||||
Assert.Equal("XXXXXX", ramoption.Content);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,3 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using SabreTools.Serialization.Deserializers;
|
||||
@@ -96,6 +95,31 @@ namespace SabreTools.Serialization.Test.Deserializers
|
||||
Validate(newGame);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void RoundTripGameWithoutQuotesTest()
|
||||
{
|
||||
// Get the serializer and deserializer
|
||||
var deserializer = new Serialization.Deserializers.ClrMamePro();
|
||||
var serializer = new Serialization.Serializers.ClrMamePro();
|
||||
|
||||
// Build the data
|
||||
Models.ClrMamePro.MetadataFile mf = Build(game: true);
|
||||
|
||||
// Serialize to stream
|
||||
Stream? actual = serializer.Serialize(mf, quotes: false);
|
||||
Assert.NotNull(actual);
|
||||
|
||||
// Serialize back to original model
|
||||
Models.ClrMamePro.MetadataFile? newMf = deserializer.Deserialize(actual);
|
||||
|
||||
// Validate the data
|
||||
Assert.NotNull(newMf);
|
||||
Validate(newMf.ClrMamePro);
|
||||
Assert.NotNull(newMf.Game);
|
||||
var newGame = Assert.Single(newMf.Game);
|
||||
Validate(newGame);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void RoundTripMachineTest()
|
||||
{
|
||||
@@ -121,6 +145,31 @@ namespace SabreTools.Serialization.Test.Deserializers
|
||||
Validate(newGame);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void RoundTripMachineWithoutQuotesTest()
|
||||
{
|
||||
// Get the serializer and deserializer
|
||||
var deserializer = new Serialization.Deserializers.ClrMamePro();
|
||||
var serializer = new Serialization.Serializers.ClrMamePro();
|
||||
|
||||
// Build the data
|
||||
Models.ClrMamePro.MetadataFile mf = Build(game: false);
|
||||
|
||||
// Serialize to stream
|
||||
Stream? actual = serializer.Serialize(mf, quotes: false);
|
||||
Assert.NotNull(actual);
|
||||
|
||||
// Serialize back to original model
|
||||
Models.ClrMamePro.MetadataFile? newMf = deserializer.Deserialize(actual);
|
||||
|
||||
// Validate the data
|
||||
Assert.NotNull(newMf);
|
||||
Validate(newMf.ClrMamePro);
|
||||
Assert.NotNull(newMf.Game);
|
||||
var newGame = Assert.Single(newMf.Game);
|
||||
Validate(newGame);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Build model for serialization and deserialization
|
||||
/// </summary>
|
||||
|
||||
73
SabreTools.Serialization.Test/Deserializers/GZipTests.cs
Normal file
73
SabreTools.Serialization.Test/Deserializers/GZipTests.cs
Normal file
@@ -0,0 +1,73 @@
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using SabreTools.Serialization.Deserializers;
|
||||
using Xunit;
|
||||
|
||||
namespace SabreTools.Serialization.Test.Deserializers
|
||||
{
|
||||
public class GZipTests
|
||||
{
|
||||
[Fact]
|
||||
public void NullArray_Null()
|
||||
{
|
||||
byte[]? data = null;
|
||||
int offset = 0;
|
||||
var deserializer = new GZip();
|
||||
|
||||
var actual = deserializer.Deserialize(data, offset);
|
||||
Assert.Null(actual);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void EmptyArray_Null()
|
||||
{
|
||||
byte[]? data = [];
|
||||
int offset = 0;
|
||||
var deserializer = new GZip();
|
||||
|
||||
var actual = deserializer.Deserialize(data, offset);
|
||||
Assert.Null(actual);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void InvalidArray_Null()
|
||||
{
|
||||
byte[]? data = [.. Enumerable.Repeat<byte>(0xFF, 1024)];
|
||||
int offset = 0;
|
||||
var deserializer = new GZip();
|
||||
|
||||
var actual = deserializer.Deserialize(data, offset);
|
||||
Assert.Null(actual);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void NullStream_Null()
|
||||
{
|
||||
Stream? data = null;
|
||||
var deserializer = new GZip();
|
||||
|
||||
var actual = deserializer.Deserialize(data);
|
||||
Assert.Null(actual);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void EmptyStream_Null()
|
||||
{
|
||||
Stream? data = new MemoryStream([]);
|
||||
var deserializer = new GZip();
|
||||
|
||||
var actual = deserializer.Deserialize(data);
|
||||
Assert.Null(actual);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void InvalidStream_Null()
|
||||
{
|
||||
Stream? data = new MemoryStream([.. Enumerable.Repeat<byte>(0xFF, 1024)]);
|
||||
var deserializer = new GZip();
|
||||
|
||||
var actual = deserializer.Deserialize(data);
|
||||
Assert.Null(actual);
|
||||
}
|
||||
}
|
||||
}
|
||||
940
SabreTools.Serialization.Test/Deserializers/MessTests.cs
Normal file
940
SabreTools.Serialization.Test/Deserializers/MessTests.cs
Normal file
@@ -0,0 +1,940 @@
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using SabreTools.Serialization.Deserializers;
|
||||
using Xunit;
|
||||
|
||||
namespace SabreTools.Serialization.Test.Deserializers
|
||||
{
|
||||
public class MessTests
|
||||
{
|
||||
[Fact]
|
||||
public void NullArray_Null()
|
||||
{
|
||||
byte[]? data = null;
|
||||
int offset = 0;
|
||||
var deserializer = new Mess();
|
||||
|
||||
var actual = deserializer.Deserialize(data, offset);
|
||||
Assert.Null(actual);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void EmptyArray_Null()
|
||||
{
|
||||
byte[]? data = [];
|
||||
int offset = 0;
|
||||
var deserializer = new Mess();
|
||||
|
||||
var actual = deserializer.Deserialize(data, offset);
|
||||
Assert.Null(actual);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void InvalidArray_Null()
|
||||
{
|
||||
byte[]? data = [.. Enumerable.Repeat<byte>(0xFF, 1024)];
|
||||
int offset = 0;
|
||||
var deserializer = new Mess();
|
||||
|
||||
var actual = deserializer.Deserialize(data, offset);
|
||||
Assert.Null(actual);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void NullStream_Null()
|
||||
{
|
||||
Stream? data = null;
|
||||
var deserializer = new Mess();
|
||||
|
||||
var actual = deserializer.Deserialize(data);
|
||||
Assert.Null(actual);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void EmptyStream_Null()
|
||||
{
|
||||
Stream? data = new MemoryStream([]);
|
||||
var deserializer = new Mess();
|
||||
|
||||
var actual = deserializer.Deserialize(data);
|
||||
Assert.Null(actual);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void InvalidStream_Null()
|
||||
{
|
||||
Stream? data = new MemoryStream([.. Enumerable.Repeat<byte>(0xFF, 1024)]);
|
||||
var deserializer = new Mess();
|
||||
|
||||
var actual = deserializer.Deserialize(data);
|
||||
Assert.Null(actual);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void RoundTripGameTest()
|
||||
{
|
||||
// Get the serializer and deserializer
|
||||
var deserializer = new Serialization.Deserializers.Mess();
|
||||
var serializer = new Serialization.Serializers.Mess();
|
||||
|
||||
// Build the data
|
||||
Models.Listxml.Mess m1 = Build(game: true);
|
||||
|
||||
// Serialize to generic model
|
||||
Stream? metadata = serializer.Serialize(m1);
|
||||
Assert.NotNull(metadata);
|
||||
|
||||
// Serialize to stream
|
||||
Models.Listxml.Mess? newMess = deserializer.Deserialize(metadata);
|
||||
|
||||
// Validate the data
|
||||
Assert.NotNull(newMess);
|
||||
Assert.Equal("XXXXXX", newMess.Version);
|
||||
|
||||
Assert.NotNull(newMess.Game);
|
||||
var newGame = Assert.Single(newMess.Game);
|
||||
Validate(newGame);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void RoundTripMachineTest()
|
||||
{
|
||||
// Get the serializer and deserializer
|
||||
var deserializer = new Serialization.Deserializers.Mess();
|
||||
var serializer = new Serialization.Serializers.Mess();
|
||||
|
||||
// Build the data
|
||||
Models.Listxml.Mess m1 = Build(game: false);
|
||||
|
||||
// Serialize to generic model
|
||||
Stream? metadata = serializer.Serialize(m1);
|
||||
Assert.NotNull(metadata);
|
||||
|
||||
// Serialize to stream
|
||||
Models.Listxml.Mess? newMess = deserializer.Deserialize(metadata);
|
||||
|
||||
// Validate the data
|
||||
Assert.NotNull(newMess);
|
||||
Assert.Equal("XXXXXX", newMess.Version);
|
||||
|
||||
Assert.NotNull(newMess.Game);
|
||||
var newGame = Assert.Single(newMess.Game);
|
||||
Validate(newGame);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Build model for serialization and deserialization
|
||||
/// </summary>
|
||||
private static Models.Listxml.Mess Build(bool game)
|
||||
{
|
||||
var biosset = new Models.Listxml.BiosSet
|
||||
{
|
||||
Name = "XXXXXX",
|
||||
Description = "XXXXXX",
|
||||
Default = "XXXXXX",
|
||||
};
|
||||
|
||||
var rom = new Models.Listxml.Rom
|
||||
{
|
||||
Name = "XXXXXX",
|
||||
Bios = "XXXXXX",
|
||||
Size = "XXXXXX",
|
||||
CRC = "XXXXXX",
|
||||
SHA1 = "XXXXXX",
|
||||
Merge = "XXXXXX",
|
||||
Region = "XXXXXX",
|
||||
Offset = "XXXXXX",
|
||||
Status = "XXXXXX",
|
||||
Optional = "XXXXXX",
|
||||
Dispose = "XXXXXX",
|
||||
SoundOnly = "XXXXXX",
|
||||
};
|
||||
|
||||
var disk = new Models.Listxml.Disk
|
||||
{
|
||||
Name = "XXXXXX",
|
||||
MD5 = "XXXXXX",
|
||||
SHA1 = "XXXXXX",
|
||||
Merge = "XXXXXX",
|
||||
Region = "XXXXXX",
|
||||
Index = "XXXXXX",
|
||||
Writable = "XXXXXX",
|
||||
Status = "XXXXXX",
|
||||
Optional = "XXXXXX",
|
||||
};
|
||||
|
||||
var deviceref = new Models.Listxml.DeviceRef
|
||||
{
|
||||
Name = "XXXXXX",
|
||||
};
|
||||
|
||||
var sample = new Models.Listxml.Sample
|
||||
{
|
||||
Name = "XXXXXX",
|
||||
};
|
||||
|
||||
var chip = new Models.Listxml.Chip
|
||||
{
|
||||
Name = "XXXXXX",
|
||||
Tag = "XXXXXX",
|
||||
Type = "XXXXXX",
|
||||
SoundOnly = "XXXXXX",
|
||||
Clock = "XXXXXX",
|
||||
};
|
||||
|
||||
var display = new Models.Listxml.Display
|
||||
{
|
||||
Tag = "XXXXXX",
|
||||
Type = "XXXXXX",
|
||||
Rotate = "XXXXXX",
|
||||
FlipX = "XXXXXX",
|
||||
Width = "XXXXXX",
|
||||
Height = "XXXXXX",
|
||||
Refresh = "XXXXXX",
|
||||
PixClock = "XXXXXX",
|
||||
HTotal = "XXXXXX",
|
||||
HBEnd = "XXXXXX",
|
||||
HBStart = "XXXXXX",
|
||||
VTotal = "XXXXXX",
|
||||
VBEnd = "XXXXXX",
|
||||
VBStart = "XXXXXX",
|
||||
};
|
||||
|
||||
var video = new Models.Listxml.Video
|
||||
{
|
||||
Screen = "XXXXXX",
|
||||
Orientation = "XXXXXX",
|
||||
Width = "XXXXXX",
|
||||
Height = "XXXXXX",
|
||||
AspectX = "XXXXXX",
|
||||
AspectY = "XXXXXX",
|
||||
Refresh = "XXXXXX",
|
||||
};
|
||||
|
||||
var sound = new Models.Listxml.Sound
|
||||
{
|
||||
Channels = "XXXXXX",
|
||||
};
|
||||
|
||||
var control = new Models.Listxml.Control
|
||||
{
|
||||
Type = "XXXXXX",
|
||||
Player = "XXXXXX",
|
||||
Buttons = "XXXXXX",
|
||||
ReqButtons = "XXXXXX",
|
||||
Minimum = "XXXXXX",
|
||||
Maximum = "XXXXXX",
|
||||
Sensitivity = "XXXXXX",
|
||||
KeyDelta = "XXXXXX",
|
||||
Reverse = "XXXXXX",
|
||||
Ways = "XXXXXX",
|
||||
Ways2 = "XXXXXX",
|
||||
Ways3 = "XXXXXX",
|
||||
};
|
||||
|
||||
var input = new Models.Listxml.Input
|
||||
{
|
||||
Service = "XXXXXX",
|
||||
Tilt = "XXXXXX",
|
||||
Players = "XXXXXX",
|
||||
//ControlAttr = "XXXXXX", // Mututally exclusive with input.Control
|
||||
Buttons = "XXXXXX",
|
||||
Coins = "XXXXXX",
|
||||
Control = [control],
|
||||
};
|
||||
|
||||
var condition = new Models.Listxml.Condition
|
||||
{
|
||||
Tag = "XXXXXX",
|
||||
Mask = "XXXXXX",
|
||||
Relation = "XXXXXX",
|
||||
Value = "XXXXXX",
|
||||
};
|
||||
|
||||
var diplocation = new Models.Listxml.DipLocation
|
||||
{
|
||||
Name = "XXXXXX",
|
||||
Number = "XXXXXX",
|
||||
Inverted = "XXXXXX",
|
||||
};
|
||||
|
||||
var dipvalue = new Models.Listxml.DipValue
|
||||
{
|
||||
Name = "XXXXXX",
|
||||
Value = "XXXXXX",
|
||||
Default = "XXXXXX",
|
||||
Condition = condition,
|
||||
};
|
||||
|
||||
var dipswitch = new Models.Listxml.DipSwitch
|
||||
{
|
||||
Name = "XXXXXX",
|
||||
Tag = "XXXXXX",
|
||||
Mask = "XXXXXX",
|
||||
Condition = condition,
|
||||
DipLocation = [diplocation],
|
||||
DipValue = [dipvalue],
|
||||
};
|
||||
|
||||
var conflocation = new Models.Listxml.ConfLocation
|
||||
{
|
||||
Name = "XXXXXX",
|
||||
Number = "XXXXXX",
|
||||
Inverted = "XXXXXX",
|
||||
};
|
||||
|
||||
var confsetting = new Models.Listxml.ConfSetting
|
||||
{
|
||||
Name = "XXXXXX",
|
||||
Value = "XXXXXX",
|
||||
Default = "XXXXXX",
|
||||
Condition = condition,
|
||||
};
|
||||
|
||||
var configuration = new Models.Listxml.Configuration
|
||||
{
|
||||
Name = "XXXXXX",
|
||||
Tag = "XXXXXX",
|
||||
Mask = "XXXXXX",
|
||||
Condition = condition,
|
||||
ConfLocation = [conflocation],
|
||||
ConfSetting = [confsetting],
|
||||
};
|
||||
|
||||
var analog = new Models.Listxml.Analog
|
||||
{
|
||||
Mask = "XXXXXX",
|
||||
};
|
||||
|
||||
var port = new Models.Listxml.Port
|
||||
{
|
||||
Tag = "XXXXXX",
|
||||
Analog = [analog],
|
||||
};
|
||||
|
||||
var adjuster = new Models.Listxml.Adjuster
|
||||
{
|
||||
Name = "XXXXXX",
|
||||
Default = "XXXXXX",
|
||||
Condition = condition,
|
||||
};
|
||||
|
||||
var driver = new Models.Listxml.Driver
|
||||
{
|
||||
Status = "XXXXXX",
|
||||
Color = "XXXXXX",
|
||||
Sound = "XXXXXX",
|
||||
PaletteSize = "XXXXXX",
|
||||
Emulation = "XXXXXX",
|
||||
Cocktail = "XXXXXX",
|
||||
SaveState = "XXXXXX",
|
||||
RequiresArtwork = "XXXXXX",
|
||||
Unofficial = "XXXXXX",
|
||||
NoSoundHardware = "XXXXXX",
|
||||
Incomplete = "XXXXXX",
|
||||
};
|
||||
|
||||
var feature = new Models.Listxml.Feature
|
||||
{
|
||||
Type = "XXXXXX",
|
||||
Status = "XXXXXX",
|
||||
Overall = "XXXXXX",
|
||||
};
|
||||
|
||||
var instance = new Models.Listxml.Instance
|
||||
{
|
||||
Name = "XXXXXX",
|
||||
BriefName = "XXXXXX",
|
||||
};
|
||||
|
||||
var extension = new Models.Listxml.Extension
|
||||
{
|
||||
Name = "XXXXXX",
|
||||
};
|
||||
|
||||
var device = new Models.Listxml.Device
|
||||
{
|
||||
Type = "XXXXXX",
|
||||
Tag = "XXXXXX",
|
||||
FixedImage = "XXXXXX",
|
||||
Mandatory = "XXXXXX",
|
||||
Interface = "XXXXXX",
|
||||
Instance = instance,
|
||||
Extension = [extension],
|
||||
};
|
||||
|
||||
var slotOption = new Models.Listxml.SlotOption
|
||||
{
|
||||
Name = "XXXXXX",
|
||||
DevName = "XXXXXX",
|
||||
Default = "XXXXXX",
|
||||
};
|
||||
|
||||
var slot = new Models.Listxml.Slot
|
||||
{
|
||||
Name = "XXXXXX",
|
||||
SlotOption = [slotOption],
|
||||
};
|
||||
|
||||
var softwarelist = new Models.Listxml.SoftwareList
|
||||
{
|
||||
Tag = "XXXXXX",
|
||||
Name = "XXXXXX",
|
||||
Status = "XXXXXX",
|
||||
Filter = "XXXXXX",
|
||||
};
|
||||
|
||||
var ramoption = new Models.Listxml.RamOption
|
||||
{
|
||||
Name = "XXXXXX",
|
||||
Default = "XXXXXX",
|
||||
Content = "XXXXXX",
|
||||
};
|
||||
|
||||
Models.Listxml.GameBase gameBase = game
|
||||
? new Models.Listxml.Game()
|
||||
: new Models.Listxml.Machine();
|
||||
gameBase.Name = "XXXXXX";
|
||||
gameBase.SourceFile = "XXXXXX";
|
||||
gameBase.IsBios = "XXXXXX";
|
||||
gameBase.IsDevice = "XXXXXX";
|
||||
gameBase.IsMechanical = "XXXXXX";
|
||||
gameBase.Runnable = "XXXXXX";
|
||||
gameBase.CloneOf = "XXXXXX";
|
||||
gameBase.RomOf = "XXXXXX";
|
||||
gameBase.SampleOf = "XXXXXX";
|
||||
gameBase.Description = "XXXXXX";
|
||||
gameBase.Year = "XXXXXX";
|
||||
gameBase.Manufacturer = "XXXXXX";
|
||||
gameBase.History = "XXXXXX";
|
||||
gameBase.BiosSet = [biosset];
|
||||
gameBase.Rom = [rom];
|
||||
gameBase.Disk = [disk];
|
||||
gameBase.DeviceRef = [deviceref];
|
||||
gameBase.Sample = [sample];
|
||||
gameBase.Chip = [chip];
|
||||
gameBase.Display = [display];
|
||||
gameBase.Video = [video];
|
||||
gameBase.Sound = sound;
|
||||
gameBase.Input = input;
|
||||
gameBase.DipSwitch = [dipswitch];
|
||||
gameBase.Configuration = [configuration];
|
||||
gameBase.Port = [port];
|
||||
gameBase.Adjuster = [adjuster];
|
||||
gameBase.Driver = driver;
|
||||
gameBase.Feature = [feature];
|
||||
gameBase.Device = [device];
|
||||
gameBase.Slot = [slot];
|
||||
gameBase.SoftwareList = [softwarelist];
|
||||
gameBase.RamOption = [ramoption];
|
||||
|
||||
return new Models.Listxml.Mess
|
||||
{
|
||||
Version = "XXXXXX",
|
||||
Game = [gameBase],
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Validate a GameBase
|
||||
/// </summary>
|
||||
private static void Validate(Models.Listxml.GameBase? gb)
|
||||
{
|
||||
Assert.NotNull(gb);
|
||||
Assert.Equal("XXXXXX", gb.Name);
|
||||
Assert.Equal("XXXXXX", gb.SourceFile);
|
||||
Assert.Equal("XXXXXX", gb.IsBios);
|
||||
Assert.Equal("XXXXXX", gb.IsDevice);
|
||||
Assert.Equal("XXXXXX", gb.IsMechanical);
|
||||
Assert.Equal("XXXXXX", gb.Runnable);
|
||||
Assert.Equal("XXXXXX", gb.CloneOf);
|
||||
Assert.Equal("XXXXXX", gb.RomOf);
|
||||
Assert.Equal("XXXXXX", gb.SampleOf);
|
||||
Assert.Equal("XXXXXX", gb.Description);
|
||||
Assert.Equal("XXXXXX", gb.Year);
|
||||
Assert.Equal("XXXXXX", gb.Manufacturer);
|
||||
Assert.Equal("XXXXXX", gb.History);
|
||||
|
||||
Assert.NotNull(gb.BiosSet);
|
||||
var biosset = Assert.Single(gb.BiosSet);
|
||||
Validate(biosset);
|
||||
|
||||
Assert.NotNull(gb.Rom);
|
||||
var rom = Assert.Single(gb.Rom);
|
||||
Validate(rom);
|
||||
|
||||
Assert.NotNull(gb.Disk);
|
||||
var disk = Assert.Single(gb.Disk);
|
||||
Validate(disk);
|
||||
|
||||
Assert.NotNull(gb.DeviceRef);
|
||||
var deviceref = Assert.Single(gb.DeviceRef);
|
||||
Validate(deviceref);
|
||||
|
||||
Assert.NotNull(gb.Sample);
|
||||
var sample = Assert.Single(gb.Sample);
|
||||
Validate(sample);
|
||||
|
||||
Assert.NotNull(gb.Chip);
|
||||
var chip = Assert.Single(gb.Chip);
|
||||
Validate(chip);
|
||||
|
||||
Assert.NotNull(gb.Display);
|
||||
var display = Assert.Single(gb.Display);
|
||||
Validate(display);
|
||||
|
||||
Assert.NotNull(gb.Video);
|
||||
var video = Assert.Single(gb.Video);
|
||||
Validate(video);
|
||||
|
||||
Validate(gb.Sound);
|
||||
Validate(gb.Input);
|
||||
|
||||
Assert.NotNull(gb.DipSwitch);
|
||||
var dipswitch = Assert.Single(gb.DipSwitch);
|
||||
Validate(dipswitch);
|
||||
|
||||
Assert.NotNull(gb.Configuration);
|
||||
var configuration = Assert.Single(gb.Configuration);
|
||||
Validate(configuration);
|
||||
|
||||
Assert.NotNull(gb.Port);
|
||||
var port = Assert.Single(gb.Port);
|
||||
Validate(port);
|
||||
|
||||
Assert.NotNull(gb.Adjuster);
|
||||
var adjuster = Assert.Single(gb.Adjuster);
|
||||
Validate(adjuster);
|
||||
|
||||
Validate(gb.Driver);
|
||||
|
||||
Assert.NotNull(gb.Feature);
|
||||
var feature = Assert.Single(gb.Feature);
|
||||
Validate(feature);
|
||||
|
||||
Assert.NotNull(gb.Device);
|
||||
var device = Assert.Single(gb.Device);
|
||||
Validate(device);
|
||||
|
||||
Assert.NotNull(gb.Slot);
|
||||
var slot = Assert.Single(gb.Slot);
|
||||
Validate(slot);
|
||||
|
||||
Assert.NotNull(gb.SoftwareList);
|
||||
var softwarelist = Assert.Single(gb.SoftwareList);
|
||||
Validate(softwarelist);
|
||||
|
||||
Assert.NotNull(gb.RamOption);
|
||||
var ramoption = Assert.Single(gb.RamOption);
|
||||
Validate(ramoption);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Validate a BiosSet
|
||||
/// </summary>
|
||||
private static void Validate(Models.Listxml.BiosSet? biosset)
|
||||
{
|
||||
Assert.NotNull(biosset);
|
||||
Assert.Equal("XXXXXX", biosset.Name);
|
||||
Assert.Equal("XXXXXX", biosset.Description);
|
||||
Assert.Equal("XXXXXX", biosset.Default);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Validate a Rom
|
||||
/// </summary>
|
||||
private static void Validate(Models.Listxml.Rom? rom)
|
||||
{
|
||||
Assert.NotNull(rom);
|
||||
Assert.Equal("XXXXXX", rom.Name);
|
||||
Assert.Equal("XXXXXX", rom.Bios);
|
||||
Assert.Equal("XXXXXX", rom.Size);
|
||||
Assert.Equal("XXXXXX", rom.CRC);
|
||||
Assert.Equal("XXXXXX", rom.SHA1);
|
||||
Assert.Equal("XXXXXX", rom.Merge);
|
||||
Assert.Equal("XXXXXX", rom.Region);
|
||||
Assert.Equal("XXXXXX", rom.Offset);
|
||||
Assert.Equal("XXXXXX", rom.Status);
|
||||
Assert.Equal("XXXXXX", rom.Optional);
|
||||
Assert.Equal("XXXXXX", rom.Dispose);
|
||||
Assert.Equal("XXXXXX", rom.SoundOnly);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Validate a Disk
|
||||
/// </summary>
|
||||
private static void Validate(Models.Listxml.Disk? disk)
|
||||
{
|
||||
Assert.NotNull(disk);
|
||||
Assert.Equal("XXXXXX", disk.Name);
|
||||
Assert.Equal("XXXXXX", disk.MD5);
|
||||
Assert.Equal("XXXXXX", disk.SHA1);
|
||||
Assert.Equal("XXXXXX", disk.Merge);
|
||||
Assert.Equal("XXXXXX", disk.Region);
|
||||
Assert.Equal("XXXXXX", disk.Index);
|
||||
Assert.Equal("XXXXXX", disk.Writable);
|
||||
Assert.Equal("XXXXXX", disk.Status);
|
||||
Assert.Equal("XXXXXX", disk.Optional);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Validate a DeviceRef
|
||||
/// </summary>
|
||||
private static void Validate(Models.Listxml.DeviceRef? deviceref)
|
||||
{
|
||||
Assert.NotNull(deviceref);
|
||||
Assert.Equal("XXXXXX", deviceref.Name);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Validate a Sample
|
||||
/// </summary>
|
||||
private static void Validate(Models.Listxml.Sample? sample)
|
||||
{
|
||||
Assert.NotNull(sample);
|
||||
Assert.Equal("XXXXXX", sample.Name);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Validate a Chip
|
||||
/// </summary>
|
||||
private static void Validate(Models.Listxml.Chip? chip)
|
||||
{
|
||||
Assert.NotNull(chip);
|
||||
Assert.Equal("XXXXXX", chip.Name);
|
||||
Assert.Equal("XXXXXX", chip.Tag);
|
||||
Assert.Equal("XXXXXX", chip.Type);
|
||||
Assert.Equal("XXXXXX", chip.SoundOnly);
|
||||
Assert.Equal("XXXXXX", chip.Clock);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Validate a Display
|
||||
/// </summary>
|
||||
private static void Validate(Models.Listxml.Display? display)
|
||||
{
|
||||
Assert.NotNull(display);
|
||||
Assert.Equal("XXXXXX", display.Tag);
|
||||
Assert.Equal("XXXXXX", display.Type);
|
||||
Assert.Equal("XXXXXX", display.Rotate);
|
||||
Assert.Equal("XXXXXX", display.FlipX);
|
||||
Assert.Equal("XXXXXX", display.Width);
|
||||
Assert.Equal("XXXXXX", display.Height);
|
||||
Assert.Equal("XXXXXX", display.Refresh);
|
||||
Assert.Equal("XXXXXX", display.PixClock);
|
||||
Assert.Equal("XXXXXX", display.HTotal);
|
||||
Assert.Equal("XXXXXX", display.HBEnd);
|
||||
Assert.Equal("XXXXXX", display.HBStart);
|
||||
Assert.Equal("XXXXXX", display.VTotal);
|
||||
Assert.Equal("XXXXXX", display.VBEnd);
|
||||
Assert.Equal("XXXXXX", display.VBStart);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Validate a Video
|
||||
/// </summary>
|
||||
private static void Validate(Models.Listxml.Video? video)
|
||||
{
|
||||
Assert.NotNull(video);
|
||||
Assert.Equal("XXXXXX", video.Screen);
|
||||
Assert.Equal("XXXXXX", video.Orientation);
|
||||
Assert.Equal("XXXXXX", video.Width);
|
||||
Assert.Equal("XXXXXX", video.Height);
|
||||
Assert.Equal("XXXXXX", video.AspectX);
|
||||
Assert.Equal("XXXXXX", video.AspectY);
|
||||
Assert.Equal("XXXXXX", video.Refresh);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Validate a Sound
|
||||
/// </summary>
|
||||
private static void Validate(Models.Listxml.Sound? sound)
|
||||
{
|
||||
Assert.NotNull(sound);
|
||||
Assert.Equal("XXXXXX", sound.Channels);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Validate a Input
|
||||
/// </summary>
|
||||
private static void Validate(Models.Listxml.Input? input)
|
||||
{
|
||||
Assert.NotNull(input);
|
||||
Assert.Equal("XXXXXX", input.Service);
|
||||
Assert.Equal("XXXXXX", input.Tilt);
|
||||
Assert.Equal("XXXXXX", input.Players);
|
||||
//Assert.Equal("XXXXXX", input.ControlAttr); // Mututally exclusive with input.Control
|
||||
Assert.Equal("XXXXXX", input.Buttons);
|
||||
Assert.Equal("XXXXXX", input.Coins);
|
||||
|
||||
Assert.NotNull(input.Control);
|
||||
var control = Assert.Single(input.Control);
|
||||
Validate(control);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Validate a Control
|
||||
/// </summary>
|
||||
private static void Validate(Models.Listxml.Control? control)
|
||||
{
|
||||
Assert.NotNull(control);
|
||||
Assert.Equal("XXXXXX", control.Type);
|
||||
Assert.Equal("XXXXXX", control.Player);
|
||||
Assert.Equal("XXXXXX", control.Buttons);
|
||||
Assert.Equal("XXXXXX", control.ReqButtons);
|
||||
Assert.Equal("XXXXXX", control.Minimum);
|
||||
Assert.Equal("XXXXXX", control.Maximum);
|
||||
Assert.Equal("XXXXXX", control.Sensitivity);
|
||||
Assert.Equal("XXXXXX", control.KeyDelta);
|
||||
Assert.Equal("XXXXXX", control.Reverse);
|
||||
Assert.Equal("XXXXXX", control.Ways);
|
||||
Assert.Equal("XXXXXX", control.Ways2);
|
||||
Assert.Equal("XXXXXX", control.Ways3);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Validate a DipSwitch
|
||||
/// </summary>
|
||||
private static void Validate(Models.Listxml.DipSwitch? dipswitch)
|
||||
{
|
||||
Assert.NotNull(dipswitch);
|
||||
Assert.Equal("XXXXXX", dipswitch.Name);
|
||||
Assert.Equal("XXXXXX", dipswitch.Tag);
|
||||
Assert.Equal("XXXXXX", dipswitch.Mask);
|
||||
Validate(dipswitch.Condition);
|
||||
|
||||
Assert.NotNull(dipswitch.DipLocation);
|
||||
var diplocation = Assert.Single(dipswitch.DipLocation);
|
||||
Validate(diplocation);
|
||||
|
||||
Assert.NotNull(dipswitch.DipValue);
|
||||
var dipvalue = Assert.Single(dipswitch.DipValue);
|
||||
Validate(dipvalue);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Validate a Condition
|
||||
/// </summary>
|
||||
private static void Validate(Models.Listxml.Condition? condition)
|
||||
{
|
||||
Assert.NotNull(condition);
|
||||
Assert.Equal("XXXXXX", condition.Tag);
|
||||
Assert.Equal("XXXXXX", condition.Mask);
|
||||
Assert.Equal("XXXXXX", condition.Relation);
|
||||
Assert.Equal("XXXXXX", condition.Value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Validate a DipLocation
|
||||
/// </summary>
|
||||
private static void Validate(Models.Listxml.DipLocation? diplocation)
|
||||
{
|
||||
Assert.NotNull(diplocation);
|
||||
Assert.Equal("XXXXXX", diplocation.Name);
|
||||
Assert.Equal("XXXXXX", diplocation.Number);
|
||||
Assert.Equal("XXXXXX", diplocation.Inverted);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Validate a DipValue
|
||||
/// </summary>
|
||||
private static void Validate(Models.Listxml.DipValue? dipvalue)
|
||||
{
|
||||
Assert.NotNull(dipvalue);
|
||||
Assert.Equal("XXXXXX", dipvalue.Name);
|
||||
Assert.Equal("XXXXXX", dipvalue.Value);
|
||||
Assert.Equal("XXXXXX", dipvalue.Default);
|
||||
Validate(dipvalue.Condition);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Validate a Configuration
|
||||
/// </summary>
|
||||
private static void Validate(Models.Listxml.Configuration? configuration)
|
||||
{
|
||||
Assert.NotNull(configuration);
|
||||
Assert.Equal("XXXXXX", configuration.Name);
|
||||
Assert.Equal("XXXXXX", configuration.Tag);
|
||||
Assert.Equal("XXXXXX", configuration.Mask);
|
||||
Validate(configuration.Condition);
|
||||
|
||||
Assert.NotNull(configuration.ConfLocation);
|
||||
var conflocation = Assert.Single(configuration.ConfLocation);
|
||||
Validate(conflocation);
|
||||
|
||||
Assert.NotNull(configuration.ConfSetting);
|
||||
var confsetting = Assert.Single(configuration.ConfSetting);
|
||||
Validate(confsetting);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Validate a ConfLocation
|
||||
/// </summary>
|
||||
private static void Validate(Models.Listxml.ConfLocation? conflocation)
|
||||
{
|
||||
Assert.NotNull(conflocation);
|
||||
Assert.Equal("XXXXXX", conflocation.Name);
|
||||
Assert.Equal("XXXXXX", conflocation.Number);
|
||||
Assert.Equal("XXXXXX", conflocation.Inverted);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Validate a ConfSetting
|
||||
/// </summary>
|
||||
private static void Validate(Models.Listxml.ConfSetting? confsetting)
|
||||
{
|
||||
Assert.NotNull(confsetting);
|
||||
Assert.Equal("XXXXXX", confsetting.Name);
|
||||
Assert.Equal("XXXXXX", confsetting.Value);
|
||||
Assert.Equal("XXXXXX", confsetting.Default);
|
||||
Validate(confsetting.Condition);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Validate a Port
|
||||
/// </summary>
|
||||
private static void Validate(Models.Listxml.Port? port)
|
||||
{
|
||||
Assert.NotNull(port);
|
||||
Assert.Equal("XXXXXX", port.Tag);
|
||||
|
||||
Assert.NotNull(port.Analog);
|
||||
var analog = Assert.Single(port.Analog);
|
||||
Validate(analog);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Validate a Analog
|
||||
/// </summary>
|
||||
private static void Validate(Models.Listxml.Analog? analog)
|
||||
{
|
||||
Assert.NotNull(analog);
|
||||
Assert.Equal("XXXXXX", analog.Mask);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Validate a Adjuster
|
||||
/// </summary>
|
||||
private static void Validate(Models.Listxml.Adjuster? adjuster)
|
||||
{
|
||||
Assert.NotNull(adjuster);
|
||||
Assert.Equal("XXXXXX", adjuster.Name);
|
||||
Assert.Equal("XXXXXX", adjuster.Default);
|
||||
Validate(adjuster.Condition);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Validate a Driver
|
||||
/// </summary>
|
||||
private static void Validate(Models.Listxml.Driver? driver)
|
||||
{
|
||||
Assert.NotNull(driver);
|
||||
Assert.Equal("XXXXXX", driver.Status);
|
||||
Assert.Equal("XXXXXX", driver.Color);
|
||||
Assert.Equal("XXXXXX", driver.Sound);
|
||||
Assert.Equal("XXXXXX", driver.PaletteSize);
|
||||
Assert.Equal("XXXXXX", driver.Emulation);
|
||||
Assert.Equal("XXXXXX", driver.Cocktail);
|
||||
Assert.Equal("XXXXXX", driver.SaveState);
|
||||
Assert.Equal("XXXXXX", driver.RequiresArtwork);
|
||||
Assert.Equal("XXXXXX", driver.Unofficial);
|
||||
Assert.Equal("XXXXXX", driver.NoSoundHardware);
|
||||
Assert.Equal("XXXXXX", driver.Incomplete);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Validate a Feature
|
||||
/// </summary>
|
||||
private static void Validate(Models.Listxml.Feature? feature)
|
||||
{
|
||||
Assert.NotNull(feature);
|
||||
Assert.Equal("XXXXXX", feature.Type);
|
||||
Assert.Equal("XXXXXX", feature.Status);
|
||||
Assert.Equal("XXXXXX", feature.Overall);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Validate a Device
|
||||
/// </summary>
|
||||
private static void Validate(Models.Listxml.Device? device)
|
||||
{
|
||||
Assert.NotNull(device);
|
||||
Assert.Equal("XXXXXX", device.Type);
|
||||
Assert.Equal("XXXXXX", device.Tag);
|
||||
Assert.Equal("XXXXXX", device.FixedImage);
|
||||
Assert.Equal("XXXXXX", device.Mandatory);
|
||||
Assert.Equal("XXXXXX", device.Interface);
|
||||
Validate(device.Instance);
|
||||
|
||||
Assert.NotNull(device.Extension);
|
||||
var extension = Assert.Single(device.Extension);
|
||||
Validate(extension);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Validate a Instance
|
||||
/// </summary>
|
||||
private static void Validate(Models.Listxml.Instance? instance)
|
||||
{
|
||||
Assert.NotNull(instance);
|
||||
Assert.Equal("XXXXXX", instance.Name);
|
||||
Assert.Equal("XXXXXX", instance.BriefName);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Validate a Extension
|
||||
/// </summary>
|
||||
private static void Validate(Models.Listxml.Extension? extension)
|
||||
{
|
||||
Assert.NotNull(extension);
|
||||
Assert.Equal("XXXXXX", extension.Name);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Validate a Slot
|
||||
/// </summary>
|
||||
private static void Validate(Models.Listxml.Slot? slot)
|
||||
{
|
||||
Assert.NotNull(slot);
|
||||
Assert.Equal("XXXXXX", slot.Name);
|
||||
|
||||
Assert.NotNull(slot.SlotOption);
|
||||
var slotoption = Assert.Single(slot.SlotOption);
|
||||
Validate(slotoption);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Validate a SlotOption
|
||||
/// </summary>
|
||||
private static void Validate(Models.Listxml.SlotOption? slotoption)
|
||||
{
|
||||
Assert.NotNull(slotoption);
|
||||
Assert.Equal("XXXXXX", slotoption.Name);
|
||||
Assert.Equal("XXXXXX", slotoption.DevName);
|
||||
Assert.Equal("XXXXXX", slotoption.Default);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Validate a SoftwareList
|
||||
/// </summary>
|
||||
private static void Validate(Models.Listxml.SoftwareList? softwarelist)
|
||||
{
|
||||
Assert.NotNull(softwarelist);
|
||||
Assert.Equal("XXXXXX", softwarelist.Tag);
|
||||
Assert.Equal("XXXXXX", softwarelist.Name);
|
||||
Assert.Equal("XXXXXX", softwarelist.Status);
|
||||
Assert.Equal("XXXXXX", softwarelist.Filter);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Validate a RamOption
|
||||
/// </summary>
|
||||
private static void Validate(Models.Listxml.RamOption? ramoption)
|
||||
{
|
||||
Assert.NotNull(ramoption);
|
||||
Assert.Equal("XXXXXX", ramoption.Name);
|
||||
Assert.Equal("XXXXXX", ramoption.Default);
|
||||
Assert.Equal("XXXXXX", ramoption.Content);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using SabreTools.Serialization.Deserializers;
|
||||
using Xunit;
|
||||
|
||||
namespace SabreTools.Serialization.Test.Deserializers
|
||||
{
|
||||
public class TapeArchiveTests
|
||||
{
|
||||
[Fact]
|
||||
public void NullArray_Null()
|
||||
{
|
||||
byte[]? data = null;
|
||||
int offset = 0;
|
||||
var deserializer = new TapeArchive();
|
||||
|
||||
var actual = deserializer.Deserialize(data, offset);
|
||||
Assert.Null(actual);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void EmptyArray_Null()
|
||||
{
|
||||
byte[]? data = [];
|
||||
int offset = 0;
|
||||
var deserializer = new TapeArchive();
|
||||
|
||||
var actual = deserializer.Deserialize(data, offset);
|
||||
Assert.Null(actual);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void InvalidArray_Null()
|
||||
{
|
||||
byte[]? data = [.. Enumerable.Repeat<byte>(0xFF, 1024)];
|
||||
int offset = 0;
|
||||
var deserializer = new TapeArchive();
|
||||
|
||||
var actual = deserializer.Deserialize(data, offset);
|
||||
Assert.Null(actual);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void NullStream_Null()
|
||||
{
|
||||
Stream? data = null;
|
||||
var deserializer = new TapeArchive();
|
||||
|
||||
var actual = deserializer.Deserialize(data);
|
||||
Assert.Null(actual);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void EmptyStream_Null()
|
||||
{
|
||||
Stream? data = new MemoryStream([]);
|
||||
var deserializer = new TapeArchive();
|
||||
|
||||
var actual = deserializer.Deserialize(data);
|
||||
Assert.Null(actual);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void InvalidStream_Null()
|
||||
{
|
||||
Stream? data = new MemoryStream([.. Enumerable.Repeat<byte>(0xFF, 1024)]);
|
||||
var deserializer = new TapeArchive();
|
||||
|
||||
var actual = deserializer.Deserialize(data);
|
||||
Assert.Null(actual);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using SabreTools.Serialization.Deserializers;
|
||||
using Xunit;
|
||||
|
||||
namespace SabreTools.Serialization.Test.Deserializers
|
||||
{
|
||||
public class WiseOverlayHeaderTests
|
||||
{
|
||||
[Fact]
|
||||
public void NullArray_Null()
|
||||
{
|
||||
byte[]? data = null;
|
||||
int offset = 0;
|
||||
var deserializer = new WiseOverlayHeader();
|
||||
|
||||
var actual = deserializer.Deserialize(data, offset);
|
||||
Assert.Null(actual);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void EmptyArray_Null()
|
||||
{
|
||||
byte[]? data = [];
|
||||
int offset = 0;
|
||||
var deserializer = new WiseOverlayHeader();
|
||||
|
||||
var actual = deserializer.Deserialize(data, offset);
|
||||
Assert.Null(actual);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void InvalidArray_Null()
|
||||
{
|
||||
byte[]? data = [.. Enumerable.Repeat<byte>(0xFF, 1024)];
|
||||
int offset = 0;
|
||||
var deserializer = new WiseOverlayHeader();
|
||||
|
||||
var actual = deserializer.Deserialize(data, offset);
|
||||
Assert.Null(actual);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void NullStream_Null()
|
||||
{
|
||||
Stream? data = null;
|
||||
var deserializer = new WiseOverlayHeader();
|
||||
|
||||
var actual = deserializer.Deserialize(data);
|
||||
Assert.Null(actual);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void EmptyStream_Null()
|
||||
{
|
||||
Stream? data = new MemoryStream([]);
|
||||
var deserializer = new WiseOverlayHeader();
|
||||
|
||||
var actual = deserializer.Deserialize(data);
|
||||
Assert.Null(actual);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void InvalidStream_Null()
|
||||
{
|
||||
Stream? data = new MemoryStream([.. Enumerable.Repeat<byte>(0xFF, 1024)]);
|
||||
var deserializer = new WiseOverlayHeader();
|
||||
|
||||
var actual = deserializer.Deserialize(data);
|
||||
Assert.Null(actual);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using SabreTools.Serialization.Deserializers;
|
||||
using Xunit;
|
||||
|
||||
namespace SabreTools.Serialization.Test.Deserializers
|
||||
{
|
||||
public class WiseScriptTests
|
||||
{
|
||||
[Fact]
|
||||
public void NullArray_Null()
|
||||
{
|
||||
byte[]? data = null;
|
||||
int offset = 0;
|
||||
var deserializer = new WiseScript();
|
||||
|
||||
var actual = deserializer.Deserialize(data, offset);
|
||||
Assert.Null(actual);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void EmptyArray_Null()
|
||||
{
|
||||
byte[]? data = [];
|
||||
int offset = 0;
|
||||
var deserializer = new WiseScript();
|
||||
|
||||
var actual = deserializer.Deserialize(data, offset);
|
||||
Assert.Null(actual);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void InvalidArray_Null()
|
||||
{
|
||||
byte[]? data = [.. Enumerable.Repeat<byte>(0xFF, 1024)];
|
||||
int offset = 0;
|
||||
var deserializer = new WiseScript();
|
||||
|
||||
var actual = deserializer.Deserialize(data, offset);
|
||||
Assert.Null(actual);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void NullStream_Null()
|
||||
{
|
||||
Stream? data = null;
|
||||
var deserializer = new WiseScript();
|
||||
|
||||
var actual = deserializer.Deserialize(data);
|
||||
Assert.Null(actual);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void EmptyStream_Null()
|
||||
{
|
||||
Stream? data = new MemoryStream([]);
|
||||
var deserializer = new WiseScript();
|
||||
|
||||
var actual = deserializer.Deserialize(data);
|
||||
Assert.Null(actual);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void InvalidStream_Null()
|
||||
{
|
||||
Stream? data = new MemoryStream([.. Enumerable.Repeat<byte>(0xFF, 1024)]);
|
||||
var deserializer = new WiseScript();
|
||||
|
||||
var actual = deserializer.Deserialize(data);
|
||||
Assert.Null(actual);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using SabreTools.Serialization.Deserializers;
|
||||
using Xunit;
|
||||
|
||||
namespace SabreTools.Serialization.Test.Deserializers
|
||||
{
|
||||
public class WiseSectionHeaderTests
|
||||
{
|
||||
[Fact]
|
||||
public void NullArray_Null()
|
||||
{
|
||||
byte[]? data = null;
|
||||
int offset = 0;
|
||||
var deserializer = new WiseSectionHeader();
|
||||
|
||||
var actual = deserializer.Deserialize(data, offset);
|
||||
Assert.Null(actual);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void EmptyArray_Null()
|
||||
{
|
||||
byte[]? data = [];
|
||||
int offset = 0;
|
||||
var deserializer = new WiseSectionHeader();
|
||||
|
||||
var actual = deserializer.Deserialize(data, offset);
|
||||
Assert.Null(actual);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void InvalidArray_Null()
|
||||
{
|
||||
byte[]? data = [.. Enumerable.Repeat<byte>(0xFF, 1024)];
|
||||
int offset = 0;
|
||||
var deserializer = new WiseSectionHeader();
|
||||
|
||||
var actual = deserializer.Deserialize(data, offset);
|
||||
Assert.Null(actual);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void NullStream_Null()
|
||||
{
|
||||
Stream? data = null;
|
||||
var deserializer = new WiseSectionHeader();
|
||||
|
||||
var actual = deserializer.Deserialize(data);
|
||||
Assert.Null(actual);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void EmptyStream_Null()
|
||||
{
|
||||
Stream? data = new MemoryStream([]);
|
||||
var deserializer = new WiseSectionHeader();
|
||||
|
||||
var actual = deserializer.Deserialize(data);
|
||||
Assert.Null(actual);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void InvalidStream_Null()
|
||||
{
|
||||
Stream? data = new MemoryStream([.. Enumerable.Repeat<byte>(0xFF, 1024)]);
|
||||
var deserializer = new WiseSectionHeader();
|
||||
|
||||
var actual = deserializer.Deserialize(data);
|
||||
Assert.Null(actual);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFrameworks>net6.0;net8.0;net9.0</TargetFrameworks>
|
||||
<TargetFrameworks>net8.0;net9.0</TargetFrameworks>
|
||||
<IsPackable>false</IsPackable>
|
||||
<LangVersion>latest</LangVersion>
|
||||
<Nullable>enable</Nullable>
|
||||
@@ -12,11 +12,11 @@
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Remove="TestData\*" />
|
||||
<None Remove="TestData\**" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Content Include="TestData\*">
|
||||
<Content Include="TestData\**">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Content>
|
||||
</ItemGroup>
|
||||
@@ -26,11 +26,11 @@
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.13.0" />
|
||||
<PackageReference Include="SabreTools.Hashing" Version="1.4.2" />
|
||||
<PackageReference Include="SabreTools.Models" Version="1.5.8" />
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.14.1" />
|
||||
<PackageReference Include="SabreTools.Hashing" Version="1.5.0" />
|
||||
<PackageReference Include="SabreTools.Models" Version="1.7.1" />
|
||||
<PackageReference Include="xunit" Version="2.9.3" />
|
||||
<PackageReference Include="xunit.runner.visualstudio" Version="3.0.2">
|
||||
<PackageReference Include="xunit.runner.visualstudio" Version="3.1.4">
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
</PackageReference>
|
||||
|
||||
25
SabreTools.Serialization.Test/Serializers/MessTests.cs
Normal file
25
SabreTools.Serialization.Test/Serializers/MessTests.cs
Normal file
@@ -0,0 +1,25 @@
|
||||
using System.IO;
|
||||
using SabreTools.Serialization.Serializers;
|
||||
using Xunit;
|
||||
|
||||
namespace SabreTools.Serialization.Test.Serializers
|
||||
{
|
||||
public class MessTests
|
||||
{
|
||||
[Fact]
|
||||
public void SerializeArray_Null_Null()
|
||||
{
|
||||
var serializer = new Mess();
|
||||
byte[]? actual = serializer.SerializeArray(null);
|
||||
Assert.Null(actual);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void SerializeStream_Null_Null()
|
||||
{
|
||||
var serializer = new Mess();
|
||||
Stream? actual = serializer.Serialize(null);
|
||||
Assert.Null(actual);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
This is a fake file for testing
|
||||
@@ -0,0 +1 @@
|
||||
This is a fake file for testing
|
||||
@@ -0,0 +1 @@
|
||||
This is a fake file for testing
|
||||
1
SabreTools.Serialization.Test/TestData/PKZIP/multi.z01
Normal file
1
SabreTools.Serialization.Test/TestData/PKZIP/multi.z01
Normal file
@@ -0,0 +1 @@
|
||||
This is a fake file for testing
|
||||
1
SabreTools.Serialization.Test/TestData/PKZIP/multi.z02
Normal file
1
SabreTools.Serialization.Test/TestData/PKZIP/multi.z02
Normal file
@@ -0,0 +1 @@
|
||||
This is a fake file for testing
|
||||
1
SabreTools.Serialization.Test/TestData/PKZIP/multi.z03
Normal file
1
SabreTools.Serialization.Test/TestData/PKZIP/multi.z03
Normal file
@@ -0,0 +1 @@
|
||||
This is a fake file for testing
|
||||
1
SabreTools.Serialization.Test/TestData/PKZIP/multi.zip
Normal file
1
SabreTools.Serialization.Test/TestData/PKZIP/multi.zip
Normal file
@@ -0,0 +1 @@
|
||||
This is a fake file for testing
|
||||
1
SabreTools.Serialization.Test/TestData/PKZIP/multix.zipx
Normal file
1
SabreTools.Serialization.Test/TestData/PKZIP/multix.zipx
Normal file
@@ -0,0 +1 @@
|
||||
This is a fake file for testing
|
||||
1
SabreTools.Serialization.Test/TestData/PKZIP/multix.zx01
Normal file
1
SabreTools.Serialization.Test/TestData/PKZIP/multix.zx01
Normal file
@@ -0,0 +1 @@
|
||||
This is a fake file for testing
|
||||
1
SabreTools.Serialization.Test/TestData/PKZIP/multix.zx02
Normal file
1
SabreTools.Serialization.Test/TestData/PKZIP/multix.zx02
Normal file
@@ -0,0 +1 @@
|
||||
This is a fake file for testing
|
||||
1
SabreTools.Serialization.Test/TestData/PKZIP/multix.zx03
Normal file
1
SabreTools.Serialization.Test/TestData/PKZIP/multix.zx03
Normal file
@@ -0,0 +1 @@
|
||||
This is a fake file for testing
|
||||
1
SabreTools.Serialization.Test/TestData/PKZIP/single.zip
Normal file
1
SabreTools.Serialization.Test/TestData/PKZIP/single.zip
Normal file
@@ -0,0 +1 @@
|
||||
This is a fake file for testing
|
||||
1
SabreTools.Serialization.Test/TestData/PKZIP/single.zipx
Normal file
1
SabreTools.Serialization.Test/TestData/PKZIP/single.zipx
Normal file
@@ -0,0 +1 @@
|
||||
This is a fake file for testing
|
||||
@@ -0,0 +1 @@
|
||||
This is a fake file for testing
|
||||
@@ -0,0 +1 @@
|
||||
This is a fake file for testing
|
||||
@@ -0,0 +1 @@
|
||||
This is a fake file for testing
|
||||
1
SabreTools.Serialization.Test/TestData/RAR/multi-old.r00
Normal file
1
SabreTools.Serialization.Test/TestData/RAR/multi-old.r00
Normal file
@@ -0,0 +1 @@
|
||||
This is a fake file for testing
|
||||
1
SabreTools.Serialization.Test/TestData/RAR/multi-old.r01
Normal file
1
SabreTools.Serialization.Test/TestData/RAR/multi-old.r01
Normal file
@@ -0,0 +1 @@
|
||||
This is a fake file for testing
|
||||
1
SabreTools.Serialization.Test/TestData/RAR/multi-old.r02
Normal file
1
SabreTools.Serialization.Test/TestData/RAR/multi-old.r02
Normal file
@@ -0,0 +1 @@
|
||||
This is a fake file for testing
|
||||
1
SabreTools.Serialization.Test/TestData/RAR/multi-old.rar
Normal file
1
SabreTools.Serialization.Test/TestData/RAR/multi-old.rar
Normal file
@@ -0,0 +1 @@
|
||||
This is a fake file for testing
|
||||
@@ -0,0 +1 @@
|
||||
This is a fake file for testing
|
||||
@@ -0,0 +1 @@
|
||||
This is a fake file for testing
|
||||
@@ -0,0 +1 @@
|
||||
This is a fake file for testing
|
||||
1
SabreTools.Serialization.Test/TestData/RAR/single.rar
Normal file
1
SabreTools.Serialization.Test/TestData/RAR/single.rar
Normal file
@@ -0,0 +1 @@
|
||||
This is a fake file for testing
|
||||
@@ -0,0 +1 @@
|
||||
This is a fake file for testing
|
||||
@@ -0,0 +1 @@
|
||||
This is a fake file for testing
|
||||
@@ -0,0 +1 @@
|
||||
This is a fake file for testing
|
||||
@@ -0,0 +1 @@
|
||||
This is a fake file for testing
|
||||
61
SabreTools.Serialization.Test/Wrappers/BZip2Tests.cs
Normal file
61
SabreTools.Serialization.Test/Wrappers/BZip2Tests.cs
Normal file
@@ -0,0 +1,61 @@
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using SabreTools.Serialization.Wrappers;
|
||||
using Xunit;
|
||||
|
||||
namespace SabreTools.Serialization.Test.Wrappers
|
||||
{
|
||||
public class BZip2Tests
|
||||
{
|
||||
[Fact]
|
||||
public void NullArray_Null()
|
||||
{
|
||||
byte[]? data = null;
|
||||
int offset = 0;
|
||||
var actual = BZip2.Create(data, offset);
|
||||
Assert.Null(actual);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void EmptyArray_Null()
|
||||
{
|
||||
byte[]? data = [];
|
||||
int offset = 0;
|
||||
var actual = BZip2.Create(data, offset);
|
||||
Assert.Null(actual);
|
||||
}
|
||||
|
||||
[Fact(Skip = "This will never pass with the current code")]
|
||||
public void InvalidArray_Null()
|
||||
{
|
||||
byte[]? data = [.. Enumerable.Repeat<byte>(0xFF, 1024)];
|
||||
int offset = 0;
|
||||
var actual = BZip2.Create(data, offset);
|
||||
Assert.Null(actual);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void NullStream_Null()
|
||||
{
|
||||
Stream? data = null;
|
||||
var actual = BZip2.Create(data);
|
||||
Assert.Null(actual);
|
||||
}
|
||||
|
||||
[Fact(Skip = "This will never pass with the current code")]
|
||||
public void EmptyStream_Null()
|
||||
{
|
||||
Stream? data = new MemoryStream([]);
|
||||
var actual = BZip2.Create(data);
|
||||
Assert.Null(actual);
|
||||
}
|
||||
|
||||
[Fact(Skip = "This will never pass with the current code")]
|
||||
public void InvalidStream_Null()
|
||||
{
|
||||
Stream? data = new MemoryStream([.. Enumerable.Repeat<byte>(0xFF, 1024)]);
|
||||
var actual = BZip2.Create(data);
|
||||
Assert.Null(actual);
|
||||
}
|
||||
}
|
||||
}
|
||||
61
SabreTools.Serialization.Test/Wrappers/GZipTests.cs
Normal file
61
SabreTools.Serialization.Test/Wrappers/GZipTests.cs
Normal file
@@ -0,0 +1,61 @@
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using SabreTools.Serialization.Wrappers;
|
||||
using Xunit;
|
||||
|
||||
namespace SabreTools.Serialization.Test.Wrappers
|
||||
{
|
||||
public class GZipTests
|
||||
{
|
||||
[Fact]
|
||||
public void NullArray_Null()
|
||||
{
|
||||
byte[]? data = null;
|
||||
int offset = 0;
|
||||
var actual = GZip.Create(data, offset);
|
||||
Assert.Null(actual);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void EmptyArray_Null()
|
||||
{
|
||||
byte[]? data = [];
|
||||
int offset = 0;
|
||||
var actual = GZip.Create(data, offset);
|
||||
Assert.Null(actual);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void InvalidArray_Null()
|
||||
{
|
||||
byte[]? data = [.. Enumerable.Repeat<byte>(0xFF, 1024)];
|
||||
int offset = 0;
|
||||
var actual = GZip.Create(data, offset);
|
||||
Assert.Null(actual);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void NullStream_Null()
|
||||
{
|
||||
Stream? data = null;
|
||||
var actual = GZip.Create(data);
|
||||
Assert.Null(actual);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void EmptyStream_Null()
|
||||
{
|
||||
Stream? data = new MemoryStream([]);
|
||||
var actual = GZip.Create(data);
|
||||
Assert.Null(actual);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void InvalidStream_Null()
|
||||
{
|
||||
Stream? data = new MemoryStream([.. Enumerable.Repeat<byte>(0xFF, 1024)]);
|
||||
var actual = GZip.Create(data);
|
||||
Assert.Null(actual);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,3 +1,4 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using SabreTools.Serialization.Wrappers;
|
||||
@@ -57,5 +58,22 @@ namespace SabreTools.Serialization.Test.Wrappers
|
||||
var actual = PKZIP.Create(data);
|
||||
Assert.Null(actual);
|
||||
}
|
||||
|
||||
#region FindParts
|
||||
|
||||
[Theory]
|
||||
[InlineData("single.zip", 1)]
|
||||
[InlineData("single.zipx", 1)]
|
||||
[InlineData("multi.zip", 4)]
|
||||
[InlineData("multix.zipx", 4)]
|
||||
[InlineData("multi-split.zip.001", 3)]
|
||||
public void FindPartsTest(string filename, int expectedParts)
|
||||
{
|
||||
string firstPart = Path.Combine(Environment.CurrentDirectory, "TestData", "PKZIP", filename);
|
||||
var actual = PKZIP.FindParts(firstPart);
|
||||
Assert.Equal(expectedParts, actual.Count);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
78
SabreTools.Serialization.Test/Wrappers/RARTests.cs
Normal file
78
SabreTools.Serialization.Test/Wrappers/RARTests.cs
Normal file
@@ -0,0 +1,78 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using SabreTools.Serialization.Wrappers;
|
||||
using Xunit;
|
||||
|
||||
namespace SabreTools.Serialization.Test.Wrappers
|
||||
{
|
||||
public class RARTests
|
||||
{
|
||||
[Fact]
|
||||
public void NullArray_Null()
|
||||
{
|
||||
byte[]? data = null;
|
||||
int offset = 0;
|
||||
var actual = RAR.Create(data, offset);
|
||||
Assert.Null(actual);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void EmptyArray_Null()
|
||||
{
|
||||
byte[]? data = [];
|
||||
int offset = 0;
|
||||
var actual = RAR.Create(data, offset);
|
||||
Assert.Null(actual);
|
||||
}
|
||||
|
||||
[Fact(Skip = "This will never pass with the current code")]
|
||||
public void InvalidArray_Null()
|
||||
{
|
||||
byte[]? data = [.. Enumerable.Repeat<byte>(0xFF, 1024)];
|
||||
int offset = 0;
|
||||
var actual = RAR.Create(data, offset);
|
||||
Assert.Null(actual);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void NullStream_Null()
|
||||
{
|
||||
Stream? data = null;
|
||||
var actual = RAR.Create(data);
|
||||
Assert.Null(actual);
|
||||
}
|
||||
|
||||
[Fact(Skip = "This will never pass with the current code")]
|
||||
public void EmptyStream_Null()
|
||||
{
|
||||
Stream? data = new MemoryStream([]);
|
||||
var actual = RAR.Create(data);
|
||||
Assert.Null(actual);
|
||||
}
|
||||
|
||||
[Fact(Skip = "This will never pass with the current code")]
|
||||
public void InvalidStream_Null()
|
||||
{
|
||||
Stream? data = new MemoryStream([.. Enumerable.Repeat<byte>(0xFF, 1024)]);
|
||||
var actual = RAR.Create(data);
|
||||
Assert.Null(actual);
|
||||
}
|
||||
|
||||
#region FindParts
|
||||
|
||||
[Theory]
|
||||
[InlineData("single.rar", 1)]
|
||||
[InlineData("multi-old.rar", 4)]
|
||||
[InlineData("multi-new.part01.rar", 3)]
|
||||
[InlineData("multi-split.rar.001", 3)]
|
||||
public void FindPartsTest(string filename, int expectedParts)
|
||||
{
|
||||
string firstPart = Path.Combine(Environment.CurrentDirectory, "TestData", "RAR", filename);
|
||||
var actual = RAR.FindParts(firstPart);
|
||||
Assert.Equal(expectedParts, actual.Count);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
76
SabreTools.Serialization.Test/Wrappers/SevenZipTests.cs
Normal file
76
SabreTools.Serialization.Test/Wrappers/SevenZipTests.cs
Normal file
@@ -0,0 +1,76 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using SabreTools.Serialization.Wrappers;
|
||||
using Xunit;
|
||||
|
||||
namespace SabreTools.Serialization.Test.Wrappers
|
||||
{
|
||||
public class SevenZipTests
|
||||
{
|
||||
[Fact]
|
||||
public void NullArray_Null()
|
||||
{
|
||||
byte[]? data = null;
|
||||
int offset = 0;
|
||||
var actual = SevenZip.Create(data, offset);
|
||||
Assert.Null(actual);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void EmptyArray_Null()
|
||||
{
|
||||
byte[]? data = [];
|
||||
int offset = 0;
|
||||
var actual = SevenZip.Create(data, offset);
|
||||
Assert.Null(actual);
|
||||
}
|
||||
|
||||
[Fact(Skip = "This will never pass with the current code")]
|
||||
public void InvalidArray_Null()
|
||||
{
|
||||
byte[]? data = [.. Enumerable.Repeat<byte>(0xFF, 1024)];
|
||||
int offset = 0;
|
||||
var actual = SevenZip.Create(data, offset);
|
||||
Assert.Null(actual);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void NullStream_Null()
|
||||
{
|
||||
Stream? data = null;
|
||||
var actual = SevenZip.Create(data);
|
||||
Assert.Null(actual);
|
||||
}
|
||||
|
||||
[Fact(Skip = "This will never pass with the current code")]
|
||||
public void EmptyStream_Null()
|
||||
{
|
||||
Stream? data = new MemoryStream([]);
|
||||
var actual = SevenZip.Create(data);
|
||||
Assert.Null(actual);
|
||||
}
|
||||
|
||||
[Fact(Skip = "This will never pass with the current code")]
|
||||
public void InvalidStream_Null()
|
||||
{
|
||||
Stream? data = new MemoryStream([.. Enumerable.Repeat<byte>(0xFF, 1024)]);
|
||||
var actual = SevenZip.Create(data);
|
||||
Assert.Null(actual);
|
||||
}
|
||||
|
||||
#region FindParts
|
||||
|
||||
[Theory]
|
||||
[InlineData("single.7z", 1)]
|
||||
[InlineData("multi.7z.001", 3)]
|
||||
public void FindPartsTest(string filename, int expectedParts)
|
||||
{
|
||||
string firstPart = Path.Combine(Environment.CurrentDirectory, "TestData", "SevenZip", filename);
|
||||
var actual = SevenZip.FindParts(firstPart);
|
||||
Assert.Equal(expectedParts, actual.Count);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
61
SabreTools.Serialization.Test/Wrappers/TapeArchiveTests.cs
Normal file
61
SabreTools.Serialization.Test/Wrappers/TapeArchiveTests.cs
Normal file
@@ -0,0 +1,61 @@
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using SabreTools.Serialization.Wrappers;
|
||||
using Xunit;
|
||||
|
||||
namespace SabreTools.Serialization.Test.Wrappers
|
||||
{
|
||||
public class TapeArchiveTests
|
||||
{
|
||||
[Fact]
|
||||
public void NullArray_Null()
|
||||
{
|
||||
byte[]? data = null;
|
||||
int offset = 0;
|
||||
var actual = TapeArchive.Create(data, offset);
|
||||
Assert.Null(actual);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void EmptyArray_Null()
|
||||
{
|
||||
byte[]? data = [];
|
||||
int offset = 0;
|
||||
var actual = TapeArchive.Create(data, offset);
|
||||
Assert.Null(actual);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void InvalidArray_Null()
|
||||
{
|
||||
byte[]? data = [.. Enumerable.Repeat<byte>(0xFF, 1024)];
|
||||
int offset = 0;
|
||||
var actual = TapeArchive.Create(data, offset);
|
||||
Assert.Null(actual);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void NullStream_Null()
|
||||
{
|
||||
Stream? data = null;
|
||||
var actual = TapeArchive.Create(data);
|
||||
Assert.Null(actual);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void EmptyStream_Null()
|
||||
{
|
||||
Stream? data = new MemoryStream([]);
|
||||
var actual = TapeArchive.Create(data);
|
||||
Assert.Null(actual);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void InvalidStream_Null()
|
||||
{
|
||||
Stream? data = new MemoryStream([.. Enumerable.Repeat<byte>(0xFF, 1024)]);
|
||||
var actual = TapeArchive.Create(data);
|
||||
Assert.Null(actual);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using SabreTools.Serialization.Wrappers;
|
||||
using Xunit;
|
||||
|
||||
namespace SabreTools.Serialization.Test.Wrappers
|
||||
{
|
||||
public class WiseOverlayHeaderTests
|
||||
{
|
||||
[Fact]
|
||||
public void NullArray_Null()
|
||||
{
|
||||
byte[]? data = null;
|
||||
int offset = 0;
|
||||
var actual = WiseOverlayHeader.Create(data, offset);
|
||||
Assert.Null(actual);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void EmptyArray_Null()
|
||||
{
|
||||
byte[]? data = [];
|
||||
int offset = 0;
|
||||
var actual = WiseOverlayHeader.Create(data, offset);
|
||||
Assert.Null(actual);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void InvalidArray_Null()
|
||||
{
|
||||
byte[]? data = [.. Enumerable.Repeat<byte>(0xFF, 1024)];
|
||||
int offset = 0;
|
||||
var actual = WiseOverlayHeader.Create(data, offset);
|
||||
Assert.Null(actual);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void NullStream_Null()
|
||||
{
|
||||
Stream? data = null;
|
||||
var actual = WiseOverlayHeader.Create(data);
|
||||
Assert.Null(actual);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void EmptyStream_Null()
|
||||
{
|
||||
Stream? data = new MemoryStream([]);
|
||||
var actual = WiseOverlayHeader.Create(data);
|
||||
Assert.Null(actual);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void InvalidStream_Null()
|
||||
{
|
||||
Stream? data = new MemoryStream([.. Enumerable.Repeat<byte>(0xFF, 1024)]);
|
||||
var actual = WiseOverlayHeader.Create(data);
|
||||
Assert.Null(actual);
|
||||
}
|
||||
}
|
||||
}
|
||||
61
SabreTools.Serialization.Test/Wrappers/WiseScriptTests.cs
Normal file
61
SabreTools.Serialization.Test/Wrappers/WiseScriptTests.cs
Normal file
@@ -0,0 +1,61 @@
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using SabreTools.Serialization.Wrappers;
|
||||
using Xunit;
|
||||
|
||||
namespace SabreTools.Serialization.Test.Wrappers
|
||||
{
|
||||
public class WiseScriptTests
|
||||
{
|
||||
[Fact]
|
||||
public void NullArray_Null()
|
||||
{
|
||||
byte[]? data = null;
|
||||
int offset = 0;
|
||||
var actual = WiseScript.Create(data, offset);
|
||||
Assert.Null(actual);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void EmptyArray_Null()
|
||||
{
|
||||
byte[]? data = [];
|
||||
int offset = 0;
|
||||
var actual = WiseScript.Create(data, offset);
|
||||
Assert.Null(actual);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void InvalidArray_Null()
|
||||
{
|
||||
byte[]? data = [.. Enumerable.Repeat<byte>(0xFF, 1024)];
|
||||
int offset = 0;
|
||||
var actual = WiseScript.Create(data, offset);
|
||||
Assert.Null(actual);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void NullStream_Null()
|
||||
{
|
||||
Stream? data = null;
|
||||
var actual = WiseScript.Create(data);
|
||||
Assert.Null(actual);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void EmptyStream_Null()
|
||||
{
|
||||
Stream? data = new MemoryStream([]);
|
||||
var actual = WiseScript.Create(data);
|
||||
Assert.Null(actual);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void InvalidStream_Null()
|
||||
{
|
||||
Stream? data = new MemoryStream([.. Enumerable.Repeat<byte>(0xFF, 1024)]);
|
||||
var actual = WiseScript.Create(data);
|
||||
Assert.Null(actual);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using SabreTools.Serialization.Wrappers;
|
||||
using Xunit;
|
||||
|
||||
namespace SabreTools.Serialization.Test.Wrappers
|
||||
{
|
||||
public class WiseSectionHeaderTests
|
||||
{
|
||||
[Fact]
|
||||
public void NullArray_Null()
|
||||
{
|
||||
byte[]? data = null;
|
||||
int offset = 0;
|
||||
var actual = WiseSectionHeader.Create(data, offset);
|
||||
Assert.Null(actual);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void EmptyArray_Null()
|
||||
{
|
||||
byte[]? data = [];
|
||||
int offset = 0;
|
||||
var actual = WiseSectionHeader.Create(data, offset);
|
||||
Assert.Null(actual);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void InvalidArray_Null()
|
||||
{
|
||||
byte[]? data = [.. Enumerable.Repeat<byte>(0xFF, 1024)];
|
||||
int offset = 0;
|
||||
var actual = WiseSectionHeader.Create(data, offset);
|
||||
Assert.Null(actual);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void NullStream_Null()
|
||||
{
|
||||
Stream? data = null;
|
||||
var actual = WiseSectionHeader.Create(data);
|
||||
Assert.Null(actual);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void EmptyStream_Null()
|
||||
{
|
||||
Stream? data = new MemoryStream([]);
|
||||
var actual = WiseSectionHeader.Create(data);
|
||||
Assert.Null(actual);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void InvalidStream_Null()
|
||||
{
|
||||
Stream? data = new MemoryStream([.. Enumerable.Repeat<byte>(0xFF, 1024)]);
|
||||
var actual = WiseSectionHeader.Create(data);
|
||||
Assert.Null(actual);
|
||||
}
|
||||
}
|
||||
}
|
||||
61
SabreTools.Serialization.Test/Wrappers/XZTests.cs
Normal file
61
SabreTools.Serialization.Test/Wrappers/XZTests.cs
Normal file
@@ -0,0 +1,61 @@
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using SabreTools.Serialization.Wrappers;
|
||||
using Xunit;
|
||||
|
||||
namespace SabreTools.Serialization.Test.Wrappers
|
||||
{
|
||||
public class XZTests
|
||||
{
|
||||
[Fact]
|
||||
public void NullArray_Null()
|
||||
{
|
||||
byte[]? data = null;
|
||||
int offset = 0;
|
||||
var actual = XZ.Create(data, offset);
|
||||
Assert.Null(actual);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void EmptyArray_Null()
|
||||
{
|
||||
byte[]? data = [];
|
||||
int offset = 0;
|
||||
var actual = XZ.Create(data, offset);
|
||||
Assert.Null(actual);
|
||||
}
|
||||
|
||||
[Fact(Skip = "This will never pass with the current code")]
|
||||
public void InvalidArray_Null()
|
||||
{
|
||||
byte[]? data = [.. Enumerable.Repeat<byte>(0xFF, 1024)];
|
||||
int offset = 0;
|
||||
var actual = XZ.Create(data, offset);
|
||||
Assert.Null(actual);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void NullStream_Null()
|
||||
{
|
||||
Stream? data = null;
|
||||
var actual = XZ.Create(data);
|
||||
Assert.Null(actual);
|
||||
}
|
||||
|
||||
[Fact(Skip = "This will never pass with the current code")]
|
||||
public void EmptyStream_Null()
|
||||
{
|
||||
Stream? data = new MemoryStream([]);
|
||||
var actual = XZ.Create(data);
|
||||
Assert.Null(actual);
|
||||
}
|
||||
|
||||
[Fact(Skip = "This will never pass with the current code")]
|
||||
public void InvalidStream_Null()
|
||||
{
|
||||
Stream? data = new MemoryStream([.. Enumerable.Repeat<byte>(0xFF, 1024)]);
|
||||
var actual = XZ.Create(data);
|
||||
Assert.Null(actual);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -9,26 +9,68 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "InfoPrint", "InfoPrint\Info
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SabreTools.Serialization.Test", "SabreTools.Serialization.Test\SabreTools.Serialization.Test.csproj", "{B8A04C5E-A14F-4842-9035-2F6871A1DA10}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ExtractionTool", "ExtractionTool\ExtractionTool.csproj", "{1565A8FD-1399-4CA7-A806-11FCD11EC687}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
Debug|x64 = Debug|x64
|
||||
Debug|x86 = Debug|x86
|
||||
Release|Any CPU = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
Release|x64 = Release|x64
|
||||
Release|x86 = Release|x86
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{5B688801-5F36-483E-B2E8-F219BA5923A2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{5B688801-5F36-483E-B2E8-F219BA5923A2}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{5B688801-5F36-483E-B2E8-F219BA5923A2}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{5B688801-5F36-483E-B2E8-F219BA5923A2}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{5B688801-5F36-483E-B2E8-F219BA5923A2}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{5B688801-5F36-483E-B2E8-F219BA5923A2}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{5B688801-5F36-483E-B2E8-F219BA5923A2}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{5B688801-5F36-483E-B2E8-F219BA5923A2}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{5B688801-5F36-483E-B2E8-F219BA5923A2}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{5B688801-5F36-483E-B2E8-F219BA5923A2}.Release|x64.Build.0 = Release|Any CPU
|
||||
{5B688801-5F36-483E-B2E8-F219BA5923A2}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{5B688801-5F36-483E-B2E8-F219BA5923A2}.Release|x86.Build.0 = Release|Any CPU
|
||||
{F3DEE31A-4726-464C-A90C-C19D78F51898}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{F3DEE31A-4726-464C-A90C-C19D78F51898}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{F3DEE31A-4726-464C-A90C-C19D78F51898}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{F3DEE31A-4726-464C-A90C-C19D78F51898}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{F3DEE31A-4726-464C-A90C-C19D78F51898}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{F3DEE31A-4726-464C-A90C-C19D78F51898}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{F3DEE31A-4726-464C-A90C-C19D78F51898}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{F3DEE31A-4726-464C-A90C-C19D78F51898}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{F3DEE31A-4726-464C-A90C-C19D78F51898}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{F3DEE31A-4726-464C-A90C-C19D78F51898}.Release|x64.Build.0 = Release|Any CPU
|
||||
{F3DEE31A-4726-464C-A90C-C19D78F51898}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{F3DEE31A-4726-464C-A90C-C19D78F51898}.Release|x86.Build.0 = Release|Any CPU
|
||||
{B8A04C5E-A14F-4842-9035-2F6871A1DA10}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{B8A04C5E-A14F-4842-9035-2F6871A1DA10}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{B8A04C5E-A14F-4842-9035-2F6871A1DA10}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{B8A04C5E-A14F-4842-9035-2F6871A1DA10}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{B8A04C5E-A14F-4842-9035-2F6871A1DA10}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{B8A04C5E-A14F-4842-9035-2F6871A1DA10}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{B8A04C5E-A14F-4842-9035-2F6871A1DA10}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{B8A04C5E-A14F-4842-9035-2F6871A1DA10}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{B8A04C5E-A14F-4842-9035-2F6871A1DA10}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{B8A04C5E-A14F-4842-9035-2F6871A1DA10}.Release|x64.Build.0 = Release|Any CPU
|
||||
{B8A04C5E-A14F-4842-9035-2F6871A1DA10}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{B8A04C5E-A14F-4842-9035-2F6871A1DA10}.Release|x86.Build.0 = Release|Any CPU
|
||||
{1565A8FD-1399-4CA7-A806-11FCD11EC687}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{1565A8FD-1399-4CA7-A806-11FCD11EC687}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{1565A8FD-1399-4CA7-A806-11FCD11EC687}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{1565A8FD-1399-4CA7-A806-11FCD11EC687}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{1565A8FD-1399-4CA7-A806-11FCD11EC687}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{1565A8FD-1399-4CA7-A806-11FCD11EC687}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{1565A8FD-1399-4CA7-A806-11FCD11EC687}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{1565A8FD-1399-4CA7-A806-11FCD11EC687}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{1565A8FD-1399-4CA7-A806-11FCD11EC687}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{1565A8FD-1399-4CA7-A806-11FCD11EC687}.Release|x64.Build.0 = Release|Any CPU
|
||||
{1565A8FD-1399-4CA7-A806-11FCD11EC687}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{1565A8FD-1399-4CA7-A806-11FCD11EC687}.Release|x86.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
|
||||
@@ -111,4 +111,4 @@ namespace SabreTools.Serialization.CrossModel
|
||||
return file;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -128,4 +128,4 @@ namespace SabreTools.Serialization.CrossModel
|
||||
return rom;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -84,4 +84,4 @@ namespace SabreTools.Serialization.CrossModel
|
||||
return row;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@ namespace SabreTools.Serialization.CrossModel
|
||||
{
|
||||
if (obj == null)
|
||||
return null;
|
||||
|
||||
|
||||
var metadataFile = new Models.Metadata.MetadataFile
|
||||
{
|
||||
[Models.Metadata.MetadataFile.HeaderKey] = ConvertHeaderToInternalModel(obj),
|
||||
@@ -87,4 +87,4 @@ namespace SabreTools.Serialization.CrossModel
|
||||
return rom;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -339,4 +339,4 @@ namespace SabreTools.Serialization.CrossModel
|
||||
return video;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -355,4 +355,4 @@ namespace SabreTools.Serialization.CrossModel
|
||||
return video;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -76,4 +76,4 @@ namespace SabreTools.Serialization.CrossModel
|
||||
return file;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@ namespace SabreTools.Serialization.CrossModel
|
||||
{
|
||||
if (obj == null)
|
||||
return null;
|
||||
|
||||
|
||||
var metadataFile = new Models.Metadata.MetadataFile();
|
||||
|
||||
if (obj?.DosCenter != null)
|
||||
@@ -79,4 +79,4 @@ namespace SabreTools.Serialization.CrossModel
|
||||
return rom;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -56,4 +56,4 @@ namespace SabreTools.Serialization.CrossModel
|
||||
return row;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -67,4 +67,4 @@ namespace SabreTools.Serialization.CrossModel
|
||||
return rom;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -238,4 +238,4 @@ namespace SabreTools.Serialization.CrossModel
|
||||
return spamsum;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@ namespace SabreTools.Serialization.CrossModel
|
||||
{
|
||||
if (obj == null)
|
||||
return null;
|
||||
|
||||
|
||||
var metadataFile = new Models.Metadata.MetadataFile
|
||||
{
|
||||
[Models.Metadata.MetadataFile.HeaderKey] = ConvertHeaderToInternalModel(),
|
||||
@@ -181,4 +181,4 @@ namespace SabreTools.Serialization.CrossModel
|
||||
return rom;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@ namespace SabreTools.Serialization.CrossModel
|
||||
var machines = obj.Read<Models.Metadata.Machine[]>(Models.Metadata.MetadataFile.MachineKey);
|
||||
if (machines != null && machines.Length > 0)
|
||||
metadataFile.Set = Array.ConvertAll(machines, ConvertMachineFromInternalModel);
|
||||
|
||||
|
||||
return metadataFile;
|
||||
}
|
||||
|
||||
@@ -90,4 +90,4 @@ namespace SabreTools.Serialization.CrossModel
|
||||
return row;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@ namespace SabreTools.Serialization.CrossModel
|
||||
{
|
||||
if (obj == null)
|
||||
return null;
|
||||
|
||||
|
||||
var metadataFile = new Models.Metadata.MetadataFile
|
||||
{
|
||||
[Models.Metadata.MetadataFile.HeaderKey] = ConvertHeaderToInternalModel(),
|
||||
@@ -117,4 +117,4 @@ namespace SabreTools.Serialization.CrossModel
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -670,4 +670,4 @@ namespace SabreTools.Serialization.CrossModel
|
||||
return video;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -711,4 +711,4 @@ namespace SabreTools.Serialization.CrossModel
|
||||
return video;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,7 +26,6 @@ namespace SabreTools.Serialization.CrossModel
|
||||
datafile.Header = ConvertHeaderFromInternalModel(header);
|
||||
}
|
||||
|
||||
// TODO: Handle Dir items - Currently need to be generated from the machines
|
||||
var machines = obj.Read<Models.Metadata.Machine[]>(Models.Metadata.MetadataFile.MachineKey);
|
||||
if (machines != null && machines.Length > 0)
|
||||
datafile.Game = Array.ConvertAll(machines, m => ConvertMachineFromInternalModel(m, game));
|
||||
@@ -349,4 +348,4 @@ namespace SabreTools.Serialization.CrossModel
|
||||
return softwareList;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,7 +20,7 @@ namespace SabreTools.Serialization.CrossModel
|
||||
var machines = new List<Models.Metadata.Machine>();
|
||||
|
||||
if (item.Game != null && item.Game.Length > 0)
|
||||
machines.AddRange(Array.ConvertAll(item.Game, ConvertMachineToInternalModel));
|
||||
machines.AddRange(Array.ConvertAll(item.Game, g => ConvertMachineToInternalModel(g)));
|
||||
|
||||
foreach (var dir in item.Dir ?? [])
|
||||
{
|
||||
@@ -94,27 +94,40 @@ namespace SabreTools.Serialization.CrossModel
|
||||
/// <summary>
|
||||
/// Convert from <see cref="Models.Logiqx.Dir"/> to an array of <see cref="Models.Metadata.Machine"/>
|
||||
/// </summary>
|
||||
private static Models.Metadata.Machine[] ConvertDirToInternalModel(Dir item)
|
||||
private static Models.Metadata.Machine[] ConvertDirToInternalModel(Dir item, string? parent = null)
|
||||
{
|
||||
if (item.Game == null || item.Game.Length == 0)
|
||||
return [];
|
||||
// Get the directory name
|
||||
string? dirName = item.Name;
|
||||
if (parent != null)
|
||||
dirName = $"{parent}\\{item.Name}";
|
||||
|
||||
return Array.ConvertAll(item.Game, g =>
|
||||
{
|
||||
var machine = ConvertMachineToInternalModel(g);
|
||||
machine[Models.Metadata.Machine.DirNameKey] = item.Name;
|
||||
return machine;
|
||||
});
|
||||
// Handle machine items
|
||||
Models.Metadata.Machine[] machines = [];
|
||||
if (item.Game != null && item.Game.Length > 0)
|
||||
machines = Array.ConvertAll(item.Game, g => ConvertMachineToInternalModel(g, dirName));
|
||||
|
||||
// Handle dir items
|
||||
List<Models.Metadata.Machine> dirs = [];
|
||||
foreach (var subdir in item.Subdir ?? [])
|
||||
{
|
||||
dirs.AddRange(ConvertDirToInternalModel(subdir, dirName));
|
||||
}
|
||||
|
||||
return [.. machines, .. dirs];
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <see cref="Models.Logiqx.GameBase"/> to <see cref="Models.Metadata.Machine"/>
|
||||
/// </summary>
|
||||
private static Models.Metadata.Machine ConvertMachineToInternalModel(GameBase item)
|
||||
private static Models.Metadata.Machine ConvertMachineToInternalModel(GameBase item, string? dir = null)
|
||||
{
|
||||
string? machineName = item.Name;
|
||||
if (machineName != null && dir != null)
|
||||
machineName = $"{dir}\\{machineName}";
|
||||
|
||||
var machine = new Models.Metadata.Machine
|
||||
{
|
||||
[Models.Metadata.Machine.NameKey] = item.Name,
|
||||
[Models.Metadata.Machine.NameKey] = machineName,
|
||||
[Models.Metadata.Machine.SourceFileKey] = item.SourceFile,
|
||||
[Models.Metadata.Machine.IsBiosKey] = item.IsBios,
|
||||
[Models.Metadata.Machine.IsDeviceKey] = item.IsDevice,
|
||||
@@ -331,4 +344,4 @@ namespace SabreTools.Serialization.CrossModel
|
||||
return softwareList;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,4 +33,4 @@ namespace SabreTools.Serialization.CrossModel
|
||||
return m1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -37,4 +37,4 @@ namespace SabreTools.Serialization.CrossModel
|
||||
return header;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
36
SabreTools.Serialization/CrossModel/Mess.Deserializer.cs
Normal file
36
SabreTools.Serialization/CrossModel/Mess.Deserializer.cs
Normal file
@@ -0,0 +1,36 @@
|
||||
using System;
|
||||
using SabreTools.Serialization.Interfaces;
|
||||
|
||||
namespace SabreTools.Serialization.CrossModel
|
||||
{
|
||||
public partial class Mess : IModelSerializer<Models.Listxml.Mess, Models.Metadata.MetadataFile>
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
public Models.Listxml.Mess? Deserialize(Models.Metadata.MetadataFile? obj)
|
||||
{
|
||||
if (obj == null)
|
||||
return null;
|
||||
|
||||
var header = obj.Read<Models.Metadata.Header>(Models.Metadata.MetadataFile.HeaderKey);
|
||||
var m1 = header != null ? ConvertMessFromInternalModel(header) : new Models.Listxml.Mess();
|
||||
|
||||
var machines = obj.Read<Models.Metadata.Machine[]>(Models.Metadata.MetadataFile.MachineKey);
|
||||
if (machines != null && machines.Length > 0)
|
||||
m1.Game = Array.ConvertAll(machines, Listxml.ConvertMachineFromInternalModel);
|
||||
|
||||
return m1;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <see cref="Models.Metadata.Models.Metadata.Header"/> to <see cref="Models.Listxml.Mess"/>
|
||||
/// </summary>
|
||||
private static Models.Listxml.Mess ConvertMessFromInternalModel(Models.Metadata.Header item)
|
||||
{
|
||||
var m1 = new Models.Listxml.Mess
|
||||
{
|
||||
Version = item.ReadString(Models.Metadata.Header.VersionKey),
|
||||
};
|
||||
return m1;
|
||||
}
|
||||
}
|
||||
}
|
||||
40
SabreTools.Serialization/CrossModel/Mess.Serializer.cs
Normal file
40
SabreTools.Serialization/CrossModel/Mess.Serializer.cs
Normal file
@@ -0,0 +1,40 @@
|
||||
using System;
|
||||
using SabreTools.Serialization.Interfaces;
|
||||
|
||||
namespace SabreTools.Serialization.CrossModel
|
||||
{
|
||||
public partial class Mess : IModelSerializer<Models.Listxml.Mess, Models.Metadata.MetadataFile>
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
public Models.Metadata.MetadataFile? Serialize(Models.Listxml.Mess? item)
|
||||
{
|
||||
if (item == null)
|
||||
return null;
|
||||
|
||||
var metadataFile = new Models.Metadata.MetadataFile
|
||||
{
|
||||
[Models.Metadata.MetadataFile.HeaderKey] = ConvertHeaderToInternalModel(item),
|
||||
};
|
||||
|
||||
if (item?.Game != null && item.Game.Length > 0)
|
||||
{
|
||||
metadataFile[Models.Metadata.MetadataFile.MachineKey]
|
||||
= Array.ConvertAll(item.Game, Listxml.ConvertMachineToInternalModel);
|
||||
}
|
||||
|
||||
return metadataFile;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert from <see cref="Models.Listxml.Mess"/> to <see cref="Models.Metadata.Header"/>
|
||||
/// </summary>
|
||||
private static Models.Metadata.Header ConvertHeaderToInternalModel(Models.Listxml.Mess item)
|
||||
{
|
||||
var header = new Models.Metadata.Header
|
||||
{
|
||||
[Models.Metadata.Header.VersionKey] = item.Version,
|
||||
};
|
||||
return header;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -123,4 +123,4 @@ namespace SabreTools.Serialization.CrossModel
|
||||
return fileRomCRC;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -107,4 +107,4 @@ namespace SabreTools.Serialization.CrossModel
|
||||
return rom;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@ namespace SabreTools.Serialization.CrossModel
|
||||
var machines = obj.Read<Models.Metadata.Machine[]>(Models.Metadata.MetadataFile.MachineKey);
|
||||
if (machines != null && machines.Length > 0)
|
||||
softwareDb.Software = Array.ConvertAll(machines, ConvertMachineFromInternalModel);
|
||||
|
||||
|
||||
return softwareDb;
|
||||
}
|
||||
|
||||
@@ -140,4 +140,4 @@ namespace SabreTools.Serialization.CrossModel
|
||||
return sccPlusCart;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -121,4 +121,4 @@ namespace SabreTools.Serialization.CrossModel
|
||||
return rom;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -112,4 +112,4 @@ namespace SabreTools.Serialization.CrossModel
|
||||
return row;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@ namespace SabreTools.Serialization.CrossModel
|
||||
{
|
||||
if (obj == null)
|
||||
return null;
|
||||
|
||||
|
||||
var metadataFile = new Models.Metadata.MetadataFile
|
||||
{
|
||||
[Models.Metadata.MetadataFile.HeaderKey] = ConvertHeaderToInternalModel(obj),
|
||||
@@ -97,4 +97,4 @@ namespace SabreTools.Serialization.CrossModel
|
||||
return rom;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -153,4 +153,4 @@ namespace SabreTools.Serialization.CrossModel
|
||||
return row;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -116,4 +116,4 @@ namespace SabreTools.Serialization.CrossModel
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -82,7 +82,7 @@ namespace SabreTools.Serialization.CrossModel
|
||||
|
||||
var roms = item.Read<Models.Metadata.Rom[]>(Models.Metadata.DataArea.RomKey);
|
||||
if (roms != null && roms.Length > 0)
|
||||
dataArea.Rom = Array.ConvertAll(roms,ConvertFromInternalModel);
|
||||
dataArea.Rom = Array.ConvertAll(roms, ConvertFromInternalModel);
|
||||
|
||||
return dataArea;
|
||||
}
|
||||
@@ -242,4 +242,4 @@ namespace SabreTools.Serialization.CrossModel
|
||||
return sharedFeat;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -236,4 +236,4 @@ namespace SabreTools.Serialization.CrossModel
|
||||
return sharedFeat;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,7 +28,7 @@ namespace SabreTools.Serialization.Deserializers
|
||||
// Try to parse the record
|
||||
var record = ParseRecord(data);
|
||||
if (record == null)
|
||||
return null;
|
||||
continue;
|
||||
|
||||
// Add the record
|
||||
records.Add(record);
|
||||
@@ -64,27 +64,31 @@ namespace SabreTools.Serialization.Deserializers
|
||||
/// <returns>Filled Record on success, null on error</returns>
|
||||
private static Record? ParseRecord(Stream data)
|
||||
{
|
||||
// The first byte is the type
|
||||
// The first 4 bytes are the type and length
|
||||
RecordType type = (RecordType)data.ReadByteValue();
|
||||
data.Seek(-1, SeekOrigin.Current);
|
||||
uint recordLength = data.ReadUInt24LittleEndian();
|
||||
data.Seek(-4, SeekOrigin.Current);
|
||||
|
||||
// Create a record based on the type
|
||||
return type switch
|
||||
switch (type)
|
||||
{
|
||||
// Known record types
|
||||
RecordType.EndOfMediaKeyBlock => ParseEndOfMediaKeyBlockRecord(data),
|
||||
RecordType.ExplicitSubsetDifference => ParseExplicitSubsetDifferenceRecord(data),
|
||||
RecordType.MediaKeyData => ParseMediaKeyDataRecord(data),
|
||||
RecordType.SubsetDifferenceIndex => ParseSubsetDifferenceIndexRecord(data),
|
||||
RecordType.TypeAndVersion => ParseTypeAndVersionRecord(data),
|
||||
RecordType.DriveRevocationList => ParseDriveRevocationListRecord(data),
|
||||
RecordType.HostRevocationList => ParseHostRevocationListRecord(data),
|
||||
RecordType.VerifyMediaKey => ParseVerifyMediaKeyRecord(data),
|
||||
RecordType.Copyright => ParseCopyrightRecord(data),
|
||||
case RecordType.EndOfMediaKeyBlock: return ParseEndOfMediaKeyBlockRecord(data);
|
||||
case RecordType.ExplicitSubsetDifference: return ParseExplicitSubsetDifferenceRecord(data);
|
||||
case RecordType.MediaKeyData: return ParseMediaKeyDataRecord(data);
|
||||
case RecordType.SubsetDifferenceIndex: return ParseSubsetDifferenceIndexRecord(data);
|
||||
case RecordType.TypeAndVersion: return ParseTypeAndVersionRecord(data);
|
||||
case RecordType.DriveRevocationList: return ParseDriveRevocationListRecord(data);
|
||||
case RecordType.HostRevocationList: return ParseHostRevocationListRecord(data);
|
||||
case RecordType.VerifyMediaKey: return ParseVerifyMediaKeyRecord(data);
|
||||
case RecordType.Copyright: return ParseCopyrightRecord(data);
|
||||
|
||||
// Unknown record type
|
||||
_ => null,
|
||||
};
|
||||
default:
|
||||
if (recordLength > 4)
|
||||
_ = data.ReadBytes((int)recordLength - 4);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -106,7 +110,7 @@ namespace SabreTools.Serialization.Deserializers
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Parse a Stream into a DriveRevocationListEntry
|
||||
/// </summary>
|
||||
@@ -411,4 +415,4 @@ namespace SabreTools.Serialization.Deserializers
|
||||
return obj;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -76,4 +76,4 @@ namespace SabreTools.Serialization.Deserializers
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,4 +4,4 @@ namespace SabreTools.Serialization.Deserializers
|
||||
{
|
||||
// All logic taken care of in the base class
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -124,4 +124,4 @@ namespace SabreTools.Serialization.Deserializers
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -49,4 +49,4 @@ namespace SabreTools.Serialization.Deserializers
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,6 +17,9 @@ namespace SabreTools.Serialization.Deserializers
|
||||
|
||||
try
|
||||
{
|
||||
// Cache the current offset
|
||||
long initialOffset = data.Position;
|
||||
|
||||
// Create a new archive to fill
|
||||
var archive = new Archive();
|
||||
|
||||
@@ -40,7 +43,7 @@ namespace SabreTools.Serialization.Deserializers
|
||||
// Read all entries in turn
|
||||
for (int i = 0; i < header.Files; i++)
|
||||
{
|
||||
files[i] = ParseFileEntry(data);
|
||||
files[i] = ParseFileEntry(data, initialOffset);
|
||||
}
|
||||
|
||||
// Set the files
|
||||
@@ -61,8 +64,9 @@ namespace SabreTools.Serialization.Deserializers
|
||||
/// Parse a Stream into a FileEntry
|
||||
/// </summary>
|
||||
/// <param name="data">Stream to parse</param>
|
||||
/// <param name="initialOffset">Initial offset to use in address comparisons</param>
|
||||
/// <returns>Filled FileEntry on success, null on error</returns>
|
||||
public static FileEntry ParseFileEntry(Stream data)
|
||||
public static FileEntry ParseFileEntry(Stream data, long initialOffset)
|
||||
{
|
||||
var fileEntry = new FileEntry();
|
||||
|
||||
@@ -78,7 +82,7 @@ namespace SabreTools.Serialization.Deserializers
|
||||
if (fileEntry.Offset > 0)
|
||||
{
|
||||
long currentOffset = data.Position;
|
||||
data.Seek(fileEntry.Offset, SeekOrigin.Begin);
|
||||
data.Seek(initialOffset + fileEntry.Offset, SeekOrigin.Begin);
|
||||
fileEntry.CompressedSize = data.ReadInt32LittleEndian();
|
||||
data.Seek(currentOffset, SeekOrigin.Begin);
|
||||
}
|
||||
@@ -103,4 +107,4 @@ namespace SabreTools.Serialization.Deserializers
|
||||
return obj;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,6 +19,9 @@ namespace SabreTools.Serialization.Deserializers
|
||||
|
||||
try
|
||||
{
|
||||
// Cache the current offset
|
||||
long initialOffset = data.Position;
|
||||
|
||||
// Create a new Half-Life Level to fill
|
||||
var file = new BspFile();
|
||||
|
||||
@@ -46,7 +49,7 @@ namespace SabreTools.Serialization.Deserializers
|
||||
continue;
|
||||
|
||||
// Seek to the lump offset
|
||||
data.Seek(lumpEntry.Offset, SeekOrigin.Begin);
|
||||
data.Seek(initialOffset + lumpEntry.Offset, SeekOrigin.Begin);
|
||||
|
||||
// Read according to the lump type
|
||||
switch ((LumpType)l)
|
||||
@@ -674,4 +677,4 @@ namespace SabreTools.Serialization.Deserializers
|
||||
return new BspModelsLump { Models = [.. models] };
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
using SabreTools.Serialization.Interfaces;
|
||||
|
||||
namespace SabreTools.Serialization.Deserializers
|
||||
@@ -9,17 +7,15 @@ namespace SabreTools.Serialization.Deserializers
|
||||
/// Base class for all binary deserializers
|
||||
/// </summary>
|
||||
/// <typeparam name="TModel">Type of the model to deserialize</typeparam>
|
||||
/// <remarks>These methods assume there is a concrete implementation of the deserialzier for the model available</remarks>
|
||||
/// <remarks>
|
||||
/// This class allows all inheriting types to only implement <see cref="IStreamDeserializer<>"/>
|
||||
/// and still implicitly implement <see cref="IByteDeserializer<>"/> and <see cref="IFileDeserializer<>"/>
|
||||
/// </remarks>
|
||||
public abstract class BaseBinaryDeserializer<TModel> :
|
||||
IByteDeserializer<TModel>,
|
||||
IFileDeserializer<TModel>,
|
||||
IStreamDeserializer<TModel>
|
||||
{
|
||||
/// <summary>
|
||||
/// Indicates if compressed files should be decompressed before processing
|
||||
/// </summary>
|
||||
protected virtual bool SkipCompression => false;
|
||||
|
||||
#region IByteDeserializer
|
||||
|
||||
/// <inheritdoc/>
|
||||
@@ -35,7 +31,7 @@ namespace SabreTools.Serialization.Deserializers
|
||||
|
||||
// Create a memory stream and parse that
|
||||
var dataStream = new MemoryStream(data, offset, data.Length - offset);
|
||||
return DeserializeStream(dataStream);
|
||||
return Deserialize(dataStream);
|
||||
}
|
||||
|
||||
#endregion
|
||||
@@ -45,8 +41,8 @@ namespace SabreTools.Serialization.Deserializers
|
||||
/// <inheritdoc/>
|
||||
public virtual TModel? Deserialize(string? path)
|
||||
{
|
||||
using var stream = PathProcessor.OpenStream(path, SkipCompression);
|
||||
return DeserializeStream(stream);
|
||||
using var stream = PathProcessor.OpenStream(path);
|
||||
return Deserialize(stream);
|
||||
}
|
||||
|
||||
#endregion
|
||||
@@ -57,110 +53,5 @@ namespace SabreTools.Serialization.Deserializers
|
||||
public abstract TModel? Deserialize(Stream? data);
|
||||
|
||||
#endregion
|
||||
|
||||
#region Static Implementations
|
||||
|
||||
/// <inheritdoc cref="IByteDeserializer.Deserialize(byte[]?, int)"/>
|
||||
public static TModel? DeserializeBytes(byte[]? data, int offset)
|
||||
{
|
||||
var deserializer = GetType<IByteDeserializer<TModel>>();
|
||||
if (deserializer == null)
|
||||
return default;
|
||||
|
||||
return deserializer.Deserialize(data, offset);
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IFileDeserializer.Deserialize(string?)"/>
|
||||
public static TModel? DeserializeFile(string? path)
|
||||
{
|
||||
var deserializer = GetType<IFileDeserializer<TModel>>();
|
||||
if (deserializer == null)
|
||||
return default;
|
||||
|
||||
return deserializer.Deserialize(path);
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IStreamDeserializer.Deserialize(Stream?)"/>
|
||||
public static TModel? DeserializeStream(Stream? data)
|
||||
{
|
||||
var deserializer = GetType<IStreamDeserializer<TModel>>();
|
||||
if (deserializer == null)
|
||||
return default;
|
||||
|
||||
return deserializer.Deserialize(data);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Helpers
|
||||
|
||||
/// <summary>
|
||||
/// Get a constructed instance of a type, if possible
|
||||
/// </summary>
|
||||
/// <typeparam name="TDeserializer">Deserializer type to construct</typeparam>
|
||||
/// <returns>Deserializer of the requested type, null on error</returns>
|
||||
private static TDeserializer? GetType<TDeserializer>()
|
||||
{
|
||||
// If the deserializer type is invalid
|
||||
string? deserializerName = typeof(TDeserializer)?.Name;
|
||||
if (deserializerName == null)
|
||||
return default;
|
||||
|
||||
// If the deserializer has no generic arguments
|
||||
var genericArgs = typeof(TDeserializer).GetGenericArguments();
|
||||
if (genericArgs.Length == 0)
|
||||
return default;
|
||||
|
||||
// Loop through all loaded assemblies
|
||||
Type modelType = genericArgs[0];
|
||||
foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies())
|
||||
{
|
||||
// If the assembly is invalid
|
||||
if (assembly == null)
|
||||
return default;
|
||||
|
||||
// If not all types can be loaded, use the ones that could be
|
||||
Type?[] assemblyTypes = [];
|
||||
try
|
||||
{
|
||||
assemblyTypes = assembly.GetTypes();
|
||||
}
|
||||
catch (ReflectionTypeLoadException rtle)
|
||||
{
|
||||
assemblyTypes = rtle.Types ?? [];
|
||||
}
|
||||
|
||||
// Loop through all types
|
||||
foreach (Type? type in assemblyTypes)
|
||||
{
|
||||
// If the type is invalid
|
||||
if (type == null)
|
||||
continue;
|
||||
|
||||
// If the type isn't a class
|
||||
if (!type.IsClass)
|
||||
continue;
|
||||
|
||||
// If the type doesn't implement the interface
|
||||
var interfaceType = type.GetInterface(deserializerName);
|
||||
if (interfaceType == null)
|
||||
continue;
|
||||
|
||||
// If the interface doesn't use the correct type parameter
|
||||
var genericTypes = interfaceType.GetGenericArguments();
|
||||
if (genericTypes.Length != 1 || genericTypes[0] != modelType)
|
||||
continue;
|
||||
|
||||
// Try to create a concrete instance of the type
|
||||
var instance = (TDeserializer?)Activator.CreateInstance(type);
|
||||
if (instance != null)
|
||||
return instance;
|
||||
}
|
||||
}
|
||||
|
||||
return default;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user