Add JSON serialization to wrappers (.NET 6)

This commit is contained in:
Matt Nadareski
2023-01-13 10:41:50 -08:00
parent f85adda24c
commit 0fd0cf689a
26 changed files with 390 additions and 7 deletions

View File

@@ -268,6 +268,13 @@ namespace BurnOutSharp.Wrappers
Console.WriteLine();
}
#if NET6_0_OR_GREATER
/// <inheritdoc/>
public override string ExportJSON() => System.Text.Json.JsonSerializer.Serialize(_mediaKeyBlock, _jsonSerializerOptions);
#endif
#endregion
}
}

View File

@@ -126,6 +126,13 @@ namespace BurnOutSharp.Wrappers
Console.WriteLine();
}
#if NET6_0_OR_GREATER
/// <inheritdoc/>
public override string ExportJSON() => System.Text.Json.JsonSerializer.Serialize(_svm, _jsonSerializerOptions);
#endif
#endregion
}
}

View File

@@ -235,6 +235,13 @@ namespace BurnOutSharp.Wrappers
Console.WriteLine();
}
#if NET6_0_OR_GREATER
/// <inheritdoc/>
public override string ExportJSON() => System.Text.Json.JsonSerializer.Serialize(_archive, _jsonSerializerOptions);
#endif
#endregion
}
}

View File

@@ -215,6 +215,13 @@ namespace BurnOutSharp.Wrappers
Console.WriteLine();
}
#if NET6_0_OR_GREATER
/// <inheritdoc/>
public override string ExportJSON() => System.Text.Json.JsonSerializer.Serialize(_file, _jsonSerializerOptions);
#endif
#endregion
#region Extraction

View File

@@ -487,6 +487,13 @@ namespace BurnOutSharp.Wrappers
Console.WriteLine();
}
#if NET6_0_OR_GREATER
/// <inheritdoc/>
public override string ExportJSON() => System.Text.Json.JsonSerializer.Serialize(_binary, _jsonSerializerOptions);
#endif
#endregion
}
}

View File

@@ -705,6 +705,13 @@ namespace BurnOutSharp.Wrappers
Console.WriteLine();
}
#if NET6_0_OR_GREATER
/// <inheritdoc/>
public override string ExportJSON() => System.Text.Json.JsonSerializer.Serialize(_cia, _jsonSerializerOptions);
#endif
#endregion
}
}

View File

@@ -0,0 +1,82 @@
#if NET6_0_OR_GREATER
using System;
using System.Reflection;
using System.Text.Json;
using System.Text.Json.Serialization;
namespace BurnOutSharp.Wrappers
{
/// <summary>
/// Serializer class for abstract classes
/// </summary>
/// <see href="https://stackoverflow.com/a/72775719"/>
internal class ConcreteAbstractSerializer : JsonConverterFactory
{
public override bool CanConvert(Type typeToConvert) => typeToConvert.IsAbstract;
class ConcreteAbstractSerializerOfType<TAbstract> : JsonConverter<TAbstract>
{
static ConcreteAbstractSerializerOfType()
{
if (!typeof(TAbstract).IsAbstract && !typeof(TAbstract).IsInterface)
throw new NotImplementedException(string.Format("Concrete class {0} is not supported", typeof(TAbstract)));
}
public override TAbstract? Read(ref System.Text.Json.Utf8JsonReader reader, Type typeToConvert, System.Text.Json.JsonSerializerOptions options) =>
throw new NotImplementedException();
public override void Write(System.Text.Json.Utf8JsonWriter writer, TAbstract value, System.Text.Json.JsonSerializerOptions options) =>
JsonSerializer.Serialize<object>(writer, value!, options);
}
public override JsonConverter CreateConverter(Type type, JsonSerializerOptions options) =>
(JsonConverter)Activator.CreateInstance(
typeof(ConcreteAbstractSerializerOfType<>).MakeGenericType(new Type[] { type }),
BindingFlags.Instance | BindingFlags.Public,
binder: null,
args: Array.Empty<object>(),
culture: null).ThrowOnNull();
}
/// <summary>
/// Serializer class for interfaces
/// </summary>
/// <see href="https://stackoverflow.com/a/72775719"/>
internal class ConcreteInterfaceSerializer : JsonConverterFactory
{
public override bool CanConvert(Type typeToConvert) => typeToConvert.IsInterface;
class ConcreteInterfaceSerializerOfType<TInterface> : JsonConverter<TInterface>
{
static ConcreteInterfaceSerializerOfType()
{
if (!typeof(TInterface).IsAbstract && !typeof(TInterface).IsInterface)
throw new NotImplementedException(string.Format("Concrete class {0} is not supported", typeof(TInterface)));
}
public override TInterface? Read(ref System.Text.Json.Utf8JsonReader reader, Type typeToConvert, System.Text.Json.JsonSerializerOptions options) =>
throw new NotImplementedException();
public override void Write(System.Text.Json.Utf8JsonWriter writer, TInterface value, System.Text.Json.JsonSerializerOptions options) =>
JsonSerializer.Serialize<object>(writer, value!, options);
}
public override JsonConverter CreateConverter(Type type, JsonSerializerOptions options) =>
(JsonConverter)Activator.CreateInstance(
typeof(ConcreteInterfaceSerializerOfType<>).MakeGenericType(new Type[] { type }),
BindingFlags.Instance | BindingFlags.Public,
binder: null,
args: Array.Empty<object>(),
culture: null).ThrowOnNull();
}
/// <summary>
/// Extensions for generic object types
/// </summary>
/// <see href="https://stackoverflow.com/a/72775719"/>
internal static class ObjectExtensions
{
public static T ThrowOnNull<T>(this T? value) where T : class => value ?? throw new ArgumentNullException();
}
}
#endif

View File

@@ -939,6 +939,13 @@ namespace BurnOutSharp.Wrappers
Console.WriteLine();
}
#if NET6_0_OR_GREATER
/// <inheritdoc/>
public override string ExportJSON() => System.Text.Json.JsonSerializer.Serialize(_file, _jsonSerializerOptions);
#endif
#endregion
#region Extraction

View File

@@ -991,6 +991,13 @@ namespace BurnOutSharp.Wrappers
Console.WriteLine();
}
#if NET6_0_OR_GREATER
/// <inheritdoc/>
public override string ExportJSON() => System.Text.Json.JsonSerializer.Serialize(_executable, _jsonSerializerOptions);
#endif
#endregion
#region REMOVE -- DO NOT USE

View File

@@ -204,6 +204,13 @@ namespace BurnOutSharp.Wrappers
Console.WriteLine();
}
#if NET6_0_OR_GREATER
/// <inheritdoc/>
public override string ExportJSON() => System.Text.Json.JsonSerializer.Serialize(_executable, _jsonSerializerOptions);
#endif
#endregion
}
}

View File

@@ -537,6 +537,13 @@ namespace BurnOutSharp.Wrappers
Console.WriteLine();
}
#if NET6_0_OR_GREATER
/// <inheritdoc/>
public override string ExportJSON() => System.Text.Json.JsonSerializer.Serialize(_cabinet, _jsonSerializerOptions);
#endif
#endregion
}
}

View File

@@ -740,6 +740,13 @@ namespace BurnOutSharp.Wrappers
Console.WriteLine();
}
#if NET6_0_OR_GREATER
/// <inheritdoc/>
public override string ExportJSON() => System.Text.Json.JsonSerializer.Serialize(_cart, _jsonSerializerOptions);
#endif
#endregion
}
}

View File

@@ -559,6 +559,13 @@ namespace BurnOutSharp.Wrappers
Console.WriteLine();
}
#if NET6_0_OR_GREATER
/// <inheritdoc/>
public override string ExportJSON() => System.Text.Json.JsonSerializer.Serialize(_file, _jsonSerializerOptions);
#endif
#endregion
}
}

View File

@@ -598,6 +598,13 @@ namespace BurnOutSharp.Wrappers
Console.WriteLine();
}
#if NET6_0_OR_GREATER
/// <inheritdoc/>
public override string ExportJSON() => System.Text.Json.JsonSerializer.Serialize(_executable, _jsonSerializerOptions);
#endif
#endregion
#region REMOVE -- DO NOT USE

View File

@@ -610,6 +610,13 @@ namespace BurnOutSharp.Wrappers
Console.WriteLine();
}
#if NET6_0_OR_GREATER
/// <inheritdoc/>
public override string ExportJSON() => System.Text.Json.JsonSerializer.Serialize(_cart, _jsonSerializerOptions);
#endif
#endregion
}
}

View File

@@ -149,6 +149,13 @@ namespace BurnOutSharp.Wrappers
Console.WriteLine();
}
#if NET6_0_OR_GREATER
/// <inheritdoc/>
public override string ExportJSON() => System.Text.Json.JsonSerializer.Serialize(_file, _jsonSerializerOptions);
#endif
#endregion
#region Extraction

View File

@@ -2924,6 +2924,13 @@ namespace BurnOutSharp.Wrappers
}
}
#if NET6_0_OR_GREATER
/// <inheritdoc/>
public override string ExportJSON() => System.Text.Json.JsonSerializer.Serialize(_executable, _jsonSerializerOptions);
#endif
#endregion
#region Debug Data

View File

@@ -280,6 +280,13 @@ namespace BurnOutSharp.Wrappers
Console.WriteLine();
}
#if NET6_0_OR_GREATER
/// <inheritdoc/>
public override string ExportJSON() => System.Text.Json.JsonSerializer.Serialize(_archive, _jsonSerializerOptions);
#endif
#endregion
}
}

View File

@@ -633,6 +633,13 @@ namespace BurnOutSharp.Wrappers
Console.WriteLine();
}
#if NET6_0_OR_GREATER
/// <inheritdoc/>
public override string ExportJSON() => System.Text.Json.JsonSerializer.Serialize(_file, _jsonSerializerOptions);
#endif
#endregion
#region Extraction

View File

@@ -156,6 +156,13 @@ namespace BurnOutSharp.Wrappers
Console.WriteLine();
}
#if NET6_0_OR_GREATER
/// <inheritdoc/>
public override string ExportJSON() => System.Text.Json.JsonSerializer.Serialize(_file, _jsonSerializerOptions);
#endif
#endregion
#region Extraction

View File

@@ -295,6 +295,13 @@ namespace BurnOutSharp.Wrappers
}
}
#if NET6_0_OR_GREATER
/// <inheritdoc/>
public override string ExportJSON() => System.Text.Json.JsonSerializer.Serialize(_file, _jsonSerializerOptions);
#endif
#endregion
#region Extraction

View File

@@ -199,6 +199,13 @@ namespace BurnOutSharp.Wrappers
Console.WriteLine();
}
#if NET6_0_OR_GREATER
/// <inheritdoc/>
public override string ExportJSON() => System.Text.Json.JsonSerializer.Serialize(_file, _jsonSerializerOptions);
#endif
#endregion
#region Extraction

View File

@@ -34,6 +34,25 @@ namespace BurnOutSharp.Wrappers
/// <remarks>This is only populated if <see cref="_dataSource"/> is <see cref="DataSource.Stream"/></remarks>
protected Stream _streamData = null;
#if NET6_0_OR_GREATER
/// <summary>
/// JSON serializer options for output printing
/// </summary>
protected System.Text.Json.JsonSerializerOptions _jsonSerializerOptions
{
get
{
var serializer = new System.Text.Json.JsonSerializerOptions { IncludeFields = true };
serializer.Converters.Add(new ConcreteAbstractSerializer());
serializer.Converters.Add(new ConcreteInterfaceSerializer());
serializer.Converters.Add(new System.Text.Json.Serialization.JsonStringEnumConverter());
return serializer;
}
}
#endif
#endregion
#region Data
@@ -264,10 +283,19 @@ namespace BurnOutSharp.Wrappers
#region Printing
/// <summary>
/// Pretty print the Executable information
/// Pretty print the item information
/// </summary>
public abstract void Print();
#if NET6_0_OR_GREATER
/// <summary>
/// Export the item information as JSON
/// </summary>
public abstract string ExportJSON();
#endif
#endregion
}
}

View File

@@ -295,6 +295,13 @@ namespace BurnOutSharp.Wrappers
Console.WriteLine();
}
#if NET6_0_OR_GREATER
/// <inheritdoc/>
public override string ExportJSON() => System.Text.Json.JsonSerializer.Serialize(_file, _jsonSerializerOptions);
#endif
#endregion
#region Extraction

View File

@@ -13,21 +13,22 @@ namespace Test
/// 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>
public static void PrintPathInfo(string path, bool debug)
public static void PrintPathInfo(string path, bool json, bool debug)
{
Console.WriteLine($"Checking possible path: {path}");
// Check if the file or directory exists
if (File.Exists(path))
{
PrintFileInfo(path, debug);
PrintFileInfo(path, json, debug);
}
else if (Directory.Exists(path))
{
foreach (string file in Directory.EnumerateFiles(path, "*", SearchOption.AllDirectories))
{
PrintFileInfo(file, debug);
PrintFileInfo(file, json, debug);
}
}
else
@@ -39,10 +40,15 @@ namespace Test
/// <summary>
/// Print information for a single file, if possible
/// </summary>
private static void PrintFileInfo(string file, bool debug)
private static void PrintFileInfo(string file, bool json, bool debug)
{
Console.WriteLine($"Attempting to print info for {file}");
#if NET6_0_OR_GREATER
// Setup the JSON output
string serializedData = null;
#endif
using (Stream stream = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.Read))
{
// Read the first 8 bytes
@@ -162,6 +168,11 @@ namespace Test
// Print the AACS MKB info to screen
mkb.Print();
#if NET6_0_OR_GREATER
// Assign the serialized data
serializedData = mkb.ExportJSON();
#endif
}
// BD+ SVM
@@ -181,6 +192,11 @@ namespace Test
// Print the BD+ SVM info to screen
svm.Print();
#if NET6_0_OR_GREATER
// Assign the serialized data
serializedData = svm.ExportJSON();
#endif
}
// BFPK archive
@@ -200,6 +216,11 @@ namespace Test
// Print the BFPK info to screen
bfpk.Print();
#if NET6_0_OR_GREATER
// Assign the serialized data
serializedData = bfpk.ExportJSON();
#endif
}
// BSP
@@ -219,6 +240,11 @@ namespace Test
// Print the BSP info to screen
bsp.Print();
#if NET6_0_OR_GREATER
// Assign the serialized data
serializedData = bsp.ExportJSON();
#endif
}
// CFB
@@ -238,6 +264,11 @@ namespace Test
// Print the CFB to screen
cfb.Print();
#if NET6_0_OR_GREATER
// Assign the serialized data
serializedData = cfb.ExportJSON();
#endif
}
// CIA
@@ -257,6 +288,11 @@ namespace Test
// Print the CIA info to screen
cia.Print();
#if NET6_0_OR_GREATER
// Assign the serialized data
serializedData = cia.ExportJSON();
#endif
}
// GCF
@@ -276,6 +312,11 @@ namespace Test
// Print the GCF info to screen
gcf.Print();
#if NET6_0_OR_GREATER
// Assign the serialized data
serializedData = gcf.ExportJSON();
#endif
}
// IS-CAB archive
@@ -321,6 +362,11 @@ namespace Test
// Print the cabinet info to screen
cabinet.Print();
#if NET6_0_OR_GREATER
// Assign the serialized data
serializedData = cabinet.ExportJSON();
#endif
}
// N3DS
@@ -340,6 +386,11 @@ namespace Test
// Print the N3DS info to screen
n3ds.Print();
#if NET6_0_OR_GREATER
// Assign the serialized data
serializedData = n3ds.ExportJSON();
#endif
}
// NCF
@@ -359,6 +410,11 @@ namespace Test
// Print the NCF info to screen
ncf.Print();
#if NET6_0_OR_GREATER
// Assign the serialized data
serializedData = ncf.ExportJSON();
#endif
}
// Nitro
@@ -378,6 +434,11 @@ namespace Test
// Print the Nitro info to screen
nitro.Print();
#if NET6_0_OR_GREATER
// Assign the serialized data
serializedData = nitro.ExportJSON();
#endif
}
// PAK
@@ -397,6 +458,11 @@ namespace Test
// Print the PAK info to screen
pak.Print();
#if NET6_0_OR_GREATER
// Assign the serialized data
serializedData = pak.ExportJSON();
#endif
}
// Quantum
@@ -416,6 +482,11 @@ namespace Test
// Print the Quantum info to screen
quantum.Print();
#if NET6_0_OR_GREATER
// Assign the serialized data
serializedData = quantum.ExportJSON();
#endif
}
// SGA
@@ -435,6 +506,11 @@ namespace Test
// Print the SGA info to screen
sga.Print();
#if NET6_0_OR_GREATER
// Assign the serialized data
serializedData = sga.ExportJSON();
#endif
}
// VBSP
@@ -454,6 +530,11 @@ namespace Test
// Print the VBSP info to screen
vbsp.Print();
#if NET6_0_OR_GREATER
// Assign the serialized data
serializedData = vbsp.ExportJSON();
#endif
}
// VPK
@@ -473,6 +554,11 @@ namespace Test
// Print the VPK info to screen
vpk.Print();
#if NET6_0_OR_GREATER
// Assign the serialized data
serializedData = vpk.ExportJSON();
#endif
}
// WAD
@@ -492,6 +578,11 @@ namespace Test
// Print the WAD info to screen
wad.Print();
#if NET6_0_OR_GREATER
// Assign the serialized data
serializedData = wad.ExportJSON();
#endif
}
// XZP
@@ -511,6 +602,11 @@ namespace Test
// Print the XZP info to screen
xzp.Print();
#if NET6_0_OR_GREATER
// Assign the serialized data
serializedData = xzp.ExportJSON();
#endif
}
// Everything else
@@ -522,6 +618,17 @@ namespace Test
return;
}
}
#if NET6_0_OR_GREATER
// If we have serialized data, write it out to a file
if (json && !string.IsNullOrEmpty(serializedData))
{
// No-op for now
Console.WriteLine(serializedData);
}
#endif
}
}
}

View File

@@ -18,7 +18,7 @@ namespace Test
p.ProgressChanged += Protector.Changed;
// Set initial values for scanner flags
bool debug = false, archives = true, contents = true, packers = true, paths = true, info = false, extract = false;
bool debug = false, archives = true, contents = true, json = false, packers = true, paths = true, info = false, extract = false;
string outputPath = string.Empty;
var inputPaths = new List<string>();
@@ -52,6 +52,15 @@ namespace Test
contents = false;
break;
#if NET6_0_OR_GREATER
case "-j":
case "--json":
json = true;
break;
#endif
case "-np":
case "--no-packers":
packers = false;
@@ -130,7 +139,7 @@ namespace Test
foreach (string inputPath in inputPaths)
{
if (info)
Printer.PrintPathInfo(inputPath, debug);
Printer.PrintPathInfo(inputPath, json, debug);
else if (extract)
Extractor.ExtractPath(inputPath, outputPath);
else
@@ -158,6 +167,9 @@ namespace Test
Console.WriteLine("-np, --no-packers Disable scanning for packers");
Console.WriteLine("-ns, --no-paths Disable scanning for path checks");
Console.WriteLine("-i, --info Print executable info");
#if NET6_0_OR_GREATER
Console.WriteLine("-j, --json Print executable info as JSON");
#endif
Console.WriteLine("-x, --extract Extract archive formats");
Console.WriteLine("-o, --outdir [PATH] Set output path for extraction (REQUIRED)");
}