Compare commits

..

46 Commits
1.4.3 ... 1.5.2

Author SHA1 Message Date
Matt Nadareski
ee8dad0c87 Bump version 2024-04-17 13:00:07 -04:00
Matt Nadareski
4163b2f22a Create non-typed variants of IWrapper and WrapperBase 2024-04-17 12:28:08 -04:00
Matt Nadareski
6aaf3afa38 Fix namespace issues 2024-04-17 11:52:22 -04:00
Matt Nadareski
2a7eb44281 Bump version 2024-04-17 11:45:26 -04:00
Matt Nadareski
08bbc93793 Update SabreTools.IO 2024-04-17 11:44:58 -04:00
Matt Nadareski
789478df13 Update SabreTools.IO 2024-04-16 13:16:59 -04:00
Matt Nadareski
cd4f1c9d97 Merge pull request #7 from SabreTools/deserializer-base
Deserializer base
2024-04-04 14:17:57 -04:00
Matt Nadareski
1a2e9fb942 Add PlayJ playlist wrapper 2024-04-04 14:15:27 -04:00
Matt Nadareski
d0865739de Add PIC wrapper 2024-04-04 14:13:03 -04:00
Matt Nadareski
0696bbab72 Add MoPaQ wrapper 2024-04-04 14:06:59 -04:00
Matt Nadareski
4b4c17ac24 Make model type inherent to interface 2024-04-04 14:03:02 -04:00
Matt Nadareski
d768172da1 Update README 2024-04-04 12:03:19 -04:00
Matt Nadareski
2a4d24309d Create base class for serializers 2024-04-04 12:03:19 -04:00
Matt Nadareski
bc01ce4552 Enforce IStreamDeserializer in base class 2024-04-04 12:03:19 -04:00
Matt Nadareski
ef0efe66bd Migrate IFileDeserializer implementation to base class 2024-04-04 12:03:19 -04:00
Matt Nadareski
7c21f65723 Migrate IByteSerializer implementation to base class 2024-04-04 12:03:19 -04:00
Matt Nadareski
cec53e907f Move static deserializers to base class 2024-04-04 12:03:19 -04:00
Matt Nadareski
006ced0430 Bump version 2024-04-04 12:00:53 -04:00
Matt Nadareski
bee6c0ba11 Add byte deserializers for remaining stream deserializers 2024-04-03 23:25:54 -04:00
Matt Nadareski
3cb880ff3f Update SabreTools.Models 2024-04-03 22:54:30 -04:00
Matt Nadareski
f1d54e4a14 Add XML byte deserialization 2024-04-03 22:41:49 -04:00
Matt Nadareski
f4aaed7f9c Move overlay extension method 2024-04-03 22:31:24 -04:00
Matt Nadareski
46ad76c5d2 Add flag for long/short SeparatedValue writing 2024-04-03 22:26:23 -04:00
Matt Nadareski
8f731cebc8 Add array constants for AttractMode 2024-04-03 22:21:39 -04:00
Matt Nadareski
6dbf9dacd6 Add flag for long/short AttractMode writing 2024-04-03 22:18:05 -04:00
Matt Nadareski
94ab760c67 Remove unnecessary code 2024-04-03 21:57:14 -04:00
Matt Nadareski
4ed3880bad Use SabreTools.Hashing for hash types 2024-04-03 21:56:21 -04:00
Matt Nadareski
ff8dcd30a5 Move some constants to the deserializer 2024-04-03 21:46:35 -04:00
Matt Nadareski
8ced91d0fa Move some constants to the deserializer 2024-04-03 21:44:02 -04:00
Matt Nadareski
f2c6fa2b8e Convert string serialization to new framework 2024-04-03 21:42:08 -04:00
Matt Nadareski
9b1bacd167 Move serializers to new organization 2024-04-03 21:27:50 -04:00
Matt Nadareski
964c97200c Move stream deserializers to new organization 2024-04-03 20:55:02 -04:00
Matt Nadareski
a3f3384ac9 Move file deserializers to new organization 2024-04-03 17:27:08 -04:00
Matt Nadareski
8b546fbf27 Start splitting serialziation differently for clarity 2024-04-03 16:41:54 -04:00
Matt Nadareski
15da711087 Rename IByteSerializer to IByteDeserializer 2024-04-03 16:37:26 -04:00
Matt Nadareski
bfee7dd449 Use better naming 2024-04-03 16:35:54 -04:00
Matt Nadareski
9de2a91e80 Fix inheritdoc 2024-04-03 16:15:48 -04:00
Matt Nadareski
bf50c801b2 Simplify some static deserializers 2024-04-03 16:00:18 -04:00
Matt Nadareski
c19a4a94f4 Use new static stream serializer 2024-04-03 15:50:06 -04:00
Matt Nadareski
b6fe94116b Add static serializers for IStreamSerializer 2024-04-03 15:43:36 -04:00
Matt Nadareski
bcf604c773 Use new static stream deserializer 2024-04-03 15:23:49 -04:00
Matt Nadareski
74984a9114 Add static deserializers for IStreamSerializer 2024-04-03 15:22:35 -04:00
Matt Nadareski
8c1e241286 Add static serializers for IFileSerializer 2024-04-03 14:58:06 -04:00
Matt Nadareski
f666d737cb Add static deserializers for IFileSerializer 2024-04-03 14:28:47 -04:00
Matt Nadareski
a01609f1d1 Add static serializers for IByteSerializer 2024-04-03 14:06:23 -04:00
Matt Nadareski
8ca9ccaf00 Handle invalid texture counts 2024-04-02 16:55:43 -04:00
301 changed files with 2870 additions and 4256 deletions

View File

@@ -4,26 +4,30 @@ 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).
## `SabreTools.Serialization.Bytes`
## Interfaces
This namespace comprises of deserializers that take byte arrays to convert into models.
Below is a table representing the various interfaces that are implemented within this library.
## `SabreTools.Serialization.CrossModel`
| Interface Name | Source Type | Destination Type |
| --- | --- | --- |
| `IByteDeserializer` | `byte[]?` | Model |
| `IByteSerializer` | Model | `byte[]?` |
| `IFileDeserializer` | `string?` path | Model |
| `IFileSerializer` | Model | `string?` path |
| `IModelSerializer` | Model | Model |
| `IStreamDeserializer` | `Stream?` | Model |
| `IStreamSerializer` | Model | `Stream?` |
| `IStringDeserializer` | `string?` representation | Model |
| `IStringSerializer` | Model | `string?` representation |
| `IWrapper` | N/A | N/A |
This namespace comprises of serializers and deserializers that convert models to other common ones. This is mainly used for metadata files converting to and from a common, `Dictionary`-based model.
## Namespaces
## `SabreTools.Serialization.Files`
Below is a table of all namespaces within the library and what they represent
This namespace comprises of serializers and deserializers that can convert to and from files on disk. Most of the serializers are symmetric, but this is not guaranteed. Unimplemented methods will throw `NotImplementedException`.
## `SabreTools.Serialization.Streams`
This namespace comprises of serializers and deserializers that can convert to and from any type of stream. Most of the serializers are symmetric, but this is not guaranteed. Unimplemented methods will throw `NotImplementedException`.
## `SabreTools.Serialization.Strings`
This namespace comprises of serializers and deserializers that can convert to and from strings. Most of the serializers are symmetric, but this is not guaranteed. Unimplemented methods will throw `NotImplementedException`.
## `SabreTools.Serialization.Wrappers`
This namespace comrpises of wrapping classes that include keeping a reference to the source of each serializable model. Some of the wrappers may also include what are referred to as "extension properties", which are generated properties derived from either parts of the model or the underlying source.
| Namespace | Description |
| --- | --- |
| `SabreTools.Serialization.CrossModel` | Convert between models; mainly used for metadata files converting to and from a common, `Dictionary`-based model |
| `SabreTools.Serialization.Deserializers` | Convert from external sources to models |
| `SabreTools.Serialization.Serializers` | Convert from models to external sources |
| `SabreTools.Serialization.Wrappers` | Classes that wrap serialization and models to allow for including extension properties |

View File

@@ -1,14 +0,0 @@
namespace SabreTools.Serialization
{
/// <summary>
/// Separated value serializer/deserializer for AttractMode romlists
/// </summary>
public static class AttractMode
{
public const string HeaderWithoutRomname = "#Name;Title;Emulator;CloneOf;Year;Manufacturer;Category;Players;Rotation;Control;Status;DisplayCount;DisplayType;AltRomname;AltTitle;Extra;Buttons";
public const int HeaderWithoutRomnameCount = 17;
public const string HeaderWithRomname = "#Romname;Title;Emulator;Cloneof;Year;Manufacturer;Category;Players;Rotation;Control;Status;DisplayCount;DisplayType;AltRomname;AltTitle;Extra;Buttons;Favourite;Tags;PlayedCount;PlayedTime;FileIsAvailable";
public const int HeaderWithRomnameCount = 22;
}
}

View File

@@ -1,25 +0,0 @@
using System.IO;
using SabreTools.Models.AACS;
using SabreTools.Serialization.Interfaces;
namespace SabreTools.Serialization.Bytes
{
public partial class AACS : IByteSerializer<MediaKeyBlock>
{
/// <inheritdoc/>
public MediaKeyBlock? Deserialize(byte[]? data, int offset)
{
// If the data is invalid
if (data == null)
return null;
// If the offset is out of bounds
if (offset < 0 || offset >= data.Length)
return null;
// Create a memory stream and parse that
MemoryStream dataStream = new MemoryStream(data, offset, data.Length - offset);
return new Streams.AACS().Deserialize(dataStream);
}
}
}

View File

@@ -1,25 +0,0 @@
using System.IO;
using SabreTools.Models.BDPlus;
using SabreTools.Serialization.Interfaces;
namespace SabreTools.Serialization.Bytes
{
public partial class BDPlus : IByteSerializer<SVM>
{
/// <inheritdoc/>
public SVM? Deserialize(byte[]? data, int offset)
{
// If the data is invalid
if (data == null)
return null;
// If the offset is out of bounds
if (offset < 0 || offset >= data.Length)
return null;
// Create a memory stream and parse that
MemoryStream dataStream = new MemoryStream(data, offset, data.Length - offset);
return new Streams.BDPlus().Deserialize(dataStream);
}
}
}

View File

@@ -1,25 +0,0 @@
using System.IO;
using SabreTools.Models.BFPK;
using SabreTools.Serialization.Interfaces;
namespace SabreTools.Serialization.Bytes
{
public partial class BFPK : IByteSerializer<Archive>
{
/// <inheritdoc/>
public Archive? Deserialize(byte[]? data, int offset)
{
// If the data is invalid
if (data == null)
return null;
// If the offset is out of bounds
if (offset < 0 || offset >= data.Length)
return null;
// Create a memory stream and parse that
MemoryStream dataStream = new MemoryStream(data, offset, data.Length - offset);
return new Streams.BFPK().Deserialize(dataStream);
}
}
}

View File

@@ -1,24 +0,0 @@
using System.IO;
using SabreTools.Serialization.Interfaces;
namespace SabreTools.Serialization.Bytes
{
public partial class BSP : IByteSerializer<Models.BSP.File>
{
/// <inheritdoc/>
public Models.BSP.File? Deserialize(byte[]? data, int offset)
{
// If the data is invalid
if (data == null)
return null;
// If the offset is out of bounds
if (offset < 0 || offset >= data.Length)
return null;
// Create a memory stream and parse that
MemoryStream dataStream = new MemoryStream(data, offset, data.Length - offset);
return new Streams.BSP().Deserialize(dataStream);
}
}
}

View File

@@ -1,25 +0,0 @@
using System.IO;
using SabreTools.Models.CFB;
using SabreTools.Serialization.Interfaces;
namespace SabreTools.Serialization.Bytes
{
public partial class CFB : IByteSerializer<Binary>
{
/// <inheritdoc/>
public Binary? Deserialize(byte[]? data, int offset)
{
// If the data is invalid
if (data == null)
return null;
// If the offset is out of bounds
if (offset < 0 || offset >= data.Length)
return null;
// Create a memory stream and parse that
MemoryStream dataStream = new MemoryStream(data, offset, data.Length - offset);
return new Streams.CFB().Deserialize(dataStream);
}
}
}

View File

@@ -1,24 +0,0 @@
using System.IO;
using SabreTools.Serialization.Interfaces;
namespace SabreTools.Serialization.Bytes
{
public partial class CIA : IByteSerializer<Models.N3DS.CIA>
{
/// <inheritdoc/>
public Models.N3DS.CIA? Deserialize(byte[]? data, int offset)
{
// If the data is invalid
if (data == null)
return null;
// If the offset is out of bounds
if (offset < 0 || offset >= data.Length)
return null;
// Create a memory stream and parse that
MemoryStream dataStream = new MemoryStream(data, offset, data.Length - offset);
return new Streams.CIA().Deserialize(dataStream);
}
}
}

View File

@@ -1,24 +0,0 @@
using System.IO;
using SabreTools.Serialization.Interfaces;
namespace SabreTools.Serialization.Bytes
{
public partial class GCF : IByteSerializer<Models.GCF.File>
{
/// <inheritdoc/>
public Models.GCF.File? Deserialize(byte[]? data, int offset)
{
// If the data is invalid
if (data == null)
return null;
// If the offset is out of bounds
if (offset < 0 || offset >= data.Length)
return null;
// Create a memory stream and parse that
MemoryStream dataStream = new MemoryStream(data, offset, data.Length - offset);
return new Streams.GCF().Deserialize(dataStream);
}
}
}

View File

@@ -1,24 +0,0 @@
using System.IO;
using SabreTools.Serialization.Interfaces;
namespace SabreTools.Serialization.Bytes
{
public partial class IRD : IByteSerializer<Models.IRD.File>
{
/// <inheritdoc/>
public Models.IRD.File? Deserialize(byte[]? data, int offset)
{
// If the data is invalid
if (data == null)
return null;
// If the offset is out of bounds
if (offset < 0 || offset >= data.Length)
return null;
// Create a memory stream and parse that
MemoryStream dataStream = new MemoryStream(data, offset, data.Length - offset);
return new Streams.IRD().Deserialize(dataStream);
}
}
}

View File

@@ -1,26 +0,0 @@
using System.IO;
using SabreTools.Models.InstallShieldCabinet;
using SabreTools.Serialization.Interfaces;
namespace SabreTools.Serialization.Bytes
{
// TODO: Add multi-cabinet reading
public partial class InstallShieldCabinet : IByteSerializer<Cabinet>
{
/// <inheritdoc/>
public Cabinet? Deserialize(byte[]? data, int offset)
{
// If the data is invalid
if (data == null)
return null;
// If the offset is out of bounds
if (offset < 0 || offset >= data.Length)
return null;
// Create a memory stream and parse that
MemoryStream dataStream = new MemoryStream(data, offset, data.Length - offset);
return new Streams.InstallShieldCabinet().Deserialize(dataStream);
}
}
}

View File

@@ -1,25 +0,0 @@
using System.IO;
using SabreTools.Models.LinearExecutable;
using SabreTools.Serialization.Interfaces;
namespace SabreTools.Serialization.Bytes
{
public partial class LinearExecutable : IByteSerializer<Executable>
{
/// <inheritdoc/>
public Executable? Deserialize(byte[]? data, int offset)
{
// If the data is invalid
if (data == null)
return null;
// If the offset is out of bounds
if (offset < 0 || offset >= data.Length)
return null;
// Create a memory stream and parse that
MemoryStream dataStream = new MemoryStream(data, offset, data.Length - offset);
return new Streams.LinearExecutable().Deserialize(dataStream);
}
}
}

View File

@@ -1,25 +0,0 @@
using System.IO;
using SabreTools.Models.MSDOS;
using SabreTools.Serialization.Interfaces;
namespace SabreTools.Serialization.Bytes
{
public partial class MSDOS : IByteSerializer<Executable>
{
/// <inheritdoc/>
public Executable? Deserialize(byte[]? data, int offset)
{
// If the data is invalid
if (data == null)
return null;
// If the offset is out of bounds
if (offset < 0 || offset >= data.Length)
return null;
// Create a memory stream and parse that
MemoryStream dataStream = new MemoryStream(data, offset, data.Length - offset);
return new Streams.MSDOS().Deserialize(dataStream);
}
}
}

View File

@@ -1,26 +0,0 @@
using System.IO;
using SabreTools.Models.MicrosoftCabinet;
using SabreTools.Serialization.Interfaces;
namespace SabreTools.Serialization.Bytes
{
// TODO: Add multi-cabinet reading
public partial class MicrosoftCabinet : IByteSerializer<Cabinet>
{
/// <inheritdoc/>
public Cabinet? Deserialize(byte[]? data, int offset)
{
// If the data is invalid
if (data == null)
return null;
// If the offset is out of bounds
if (offset < 0 || offset >= data.Length)
return null;
// Create a memory stream and parse that
MemoryStream dataStream = new MemoryStream(data, offset, data.Length - offset);
return new Streams.MicrosoftCabinet().Deserialize(dataStream);
}
}
}

View File

@@ -1,25 +0,0 @@
using System.IO;
using SabreTools.Models.MoPaQ;
using SabreTools.Serialization.Interfaces;
namespace SabreTools.Serialization.Bytes
{
public partial class MoPaQ : IByteSerializer<Archive>
{
/// <inheritdoc/>
public Archive? Deserialize(byte[]? data, int offset)
{
// If the data is invalid
if (data == null)
return null;
// If the offset is out of bounds
if (offset < 0 || offset >= data.Length)
return null;
// Create a memory stream and parse that
MemoryStream dataStream = new MemoryStream(data, offset, data.Length - offset);
return new Streams.MoPaQ().Deserialize(dataStream);
}
}
}

View File

@@ -1,25 +0,0 @@
using System.IO;
using SabreTools.Models.N3DS;
using SabreTools.Serialization.Interfaces;
namespace SabreTools.Serialization.Bytes
{
public partial class N3DS : IByteSerializer<Cart>
{
/// <inheritdoc/>
public Cart? Deserialize(byte[]? data, int offset)
{
// If the data is invalid
if (data == null)
return null;
// If the offset is out of bounds
if (offset < 0 || offset >= data.Length)
return null;
// Create a memory stream and parse that
MemoryStream dataStream = new MemoryStream(data, offset, data.Length - offset);
return new Streams.N3DS().Deserialize(dataStream);
}
}
}

View File

@@ -1,24 +0,0 @@
using System.IO;
using SabreTools.Serialization.Interfaces;
namespace SabreTools.Serialization.Bytes
{
public partial class NCF : IByteSerializer<Models.NCF.File>
{
/// <inheritdoc/>
public Models.NCF.File? Deserialize(byte[]? data, int offset)
{
// If the data is invalid
if (data == null)
return null;
// If the offset is out of bounds
if (offset < 0 || offset >= data.Length)
return null;
// Create a memory stream and parse that
MemoryStream dataStream = new MemoryStream(data, offset, data.Length - offset);
return new Streams.NCF().Deserialize(dataStream);
}
}
}

View File

@@ -1,25 +0,0 @@
using System.IO;
using SabreTools.Models.NewExecutable;
using SabreTools.Serialization.Interfaces;
namespace SabreTools.Serialization.Bytes
{
public partial class NewExecutable : IByteSerializer<Executable>
{
/// <inheritdoc/>
public Executable? Deserialize(byte[]? data, int offset)
{
// If the data is invalid
if (data == null)
return null;
// If the offset is out of bounds
if (offset < 0 || offset >= data.Length)
return null;
// Create a memory stream and parse that
MemoryStream dataStream = new MemoryStream(data, offset, data.Length - offset);
return new Streams.NewExecutable().Deserialize(dataStream);
}
}
}

View File

@@ -1,25 +0,0 @@
using System.IO;
using SabreTools.Models.Nitro;
using SabreTools.Serialization.Interfaces;
namespace SabreTools.Serialization.Bytes
{
public partial class Nitro : IByteSerializer<Cart>
{
/// <inheritdoc/>
public Cart? Deserialize(byte[]? data, int offset)
{
// If the data is invalid
if (data == null)
return null;
// If the offset is out of bounds
if (offset < 0 || offset >= data.Length)
return null;
// Create a memory stream and parse that
MemoryStream dataStream = new MemoryStream(data, offset, data.Length - offset);
return new Streams.Nitro().Deserialize(dataStream);
}
}
}

View File

@@ -1,24 +0,0 @@
using System.IO;
using SabreTools.Serialization.Interfaces;
namespace SabreTools.Serialization.Bytes
{
public partial class PAK : IByteSerializer<Models.PAK.File>
{
/// <inheritdoc/>
public Models.PAK.File? Deserialize(byte[]? data, int offset)
{
// If the data is invalid
if (data == null)
return null;
// If the offset is out of bounds
if (offset < 0 || offset >= data.Length)
return null;
// Create a memory stream and parse that
MemoryStream dataStream = new MemoryStream(data, offset, data.Length - offset);
return new Streams.PAK().Deserialize(dataStream);
}
}
}

View File

@@ -1,25 +0,0 @@
using System.IO;
using SabreTools.Models.PFF;
using SabreTools.Serialization.Interfaces;
namespace SabreTools.Serialization.Bytes
{
public partial class PFF : IByteSerializer<Archive>
{
/// <inheritdoc/>
public Archive? Deserialize(byte[]? data, int offset)
{
// If the data is invalid
if (data == null)
return null;
// If the offset is out of bounds
if (offset < 0 || offset >= data.Length)
return null;
// Create a memory stream and parse that
MemoryStream dataStream = new MemoryStream(data, offset, data.Length - offset);
return new Streams.PFF().Deserialize(dataStream);
}
}
}

View File

@@ -1,25 +0,0 @@
using System.IO;
using SabreTools.Models.PlayJ;
using SabreTools.Serialization.Interfaces;
namespace SabreTools.Serialization.Bytes
{
public partial class PlayJAudio : IByteSerializer<AudioFile>
{
/// <inheritdoc/>
public AudioFile? Deserialize(byte[]? data, int offset)
{
// If the data is invalid
if (data == null)
return null;
// If the offset is out of bounds
if (offset < 0 || offset >= data.Length)
return null;
// Create a memory stream and parse that
MemoryStream dataStream = new MemoryStream(data, offset, data.Length - offset);
return new Streams.PlayJAudio().Deserialize(dataStream);
}
}
}

View File

@@ -1,25 +0,0 @@
using System.IO;
using SabreTools.Models.PlayJ;
using SabreTools.Serialization.Interfaces;
namespace SabreTools.Serialization.Bytes
{
public partial class PlayJPlaylist : IByteSerializer<Playlist>
{
/// <inheritdoc/>
public Playlist? Deserialize(byte[]? data, int offset)
{
// If the data is invalid
if (data == null)
return null;
// If the offset is out of bounds
if (offset < 0 || offset >= data.Length)
return null;
// Create a memory stream and parse that
MemoryStream dataStream = new MemoryStream(data, offset, data.Length - offset);
return new Streams.PlayJPlaylist().Deserialize(dataStream);
}
}
}

View File

@@ -1,25 +0,0 @@
using System.IO;
using SabreTools.Models.PortableExecutable;
using SabreTools.Serialization.Interfaces;
namespace SabreTools.Serialization.Bytes
{
public partial class PortableExecutable : IByteSerializer<Executable>
{
/// <inheritdoc/>
public Executable? Deserialize(byte[]? data, int offset)
{
// If the data is invalid
if (data == null)
return null;
// If the offset is out of bounds
if (offset < 0 || offset >= data.Length)
return null;
// Create a memory stream and parse that
MemoryStream dataStream = new MemoryStream(data, offset, data.Length - offset);
return new Streams.PortableExecutable().Deserialize(dataStream);
}
}
}

View File

@@ -1,25 +0,0 @@
using System.IO;
using SabreTools.Models.Quantum;
using SabreTools.Serialization.Interfaces;
namespace SabreTools.Serialization.Bytes
{
public partial class Quantum : IByteSerializer<Archive>
{
/// <inheritdoc/>
public Archive? Deserialize(byte[]? data, int offset)
{
// If the data is invalid
if (data == null)
return null;
// If the offset is out of bounds
if (offset < 0 || offset >= data.Length)
return null;
// Create a memory stream and parse that
MemoryStream dataStream = new MemoryStream(data, offset, data.Length - offset);
return new Streams.Quantum().Deserialize(dataStream);
}
}
}

View File

@@ -1,24 +0,0 @@
using System.IO;
using SabreTools.Serialization.Interfaces;
namespace SabreTools.Serialization.Bytes
{
public partial class SGA : IByteSerializer<Models.SGA.File>
{
/// <inheritdoc/>
public Models.SGA.File? Deserialize(byte[]? data, int offset)
{
// If the data is invalid
if (data == null)
return null;
// If the offset is out of bounds
if (offset < 0 || offset >= data.Length)
return null;
// Create a memory stream and parse that
MemoryStream dataStream = new MemoryStream(data, offset, data.Length - offset);
return new Streams.SGA().Deserialize(dataStream);
}
}
}

View File

@@ -1,24 +0,0 @@
using System.IO;
using SabreTools.Serialization.Interfaces;
namespace SabreTools.Serialization.Bytes
{
public partial class VBSP : IByteSerializer<Models.VBSP.File>
{
/// <inheritdoc/>
public Models.VBSP.File? Deserialize(byte[]? data, int offset)
{
// If the data is invalid
if (data == null)
return null;
// If the offset is out of bounds
if (offset < 0 || offset >= data.Length)
return null;
// Create a memory stream and parse that
MemoryStream dataStream = new MemoryStream(data, offset, data.Length - offset);
return new Streams.VBSP().Deserialize(dataStream);
}
}
}

View File

@@ -1,24 +0,0 @@
using System.IO;
using SabreTools.Serialization.Interfaces;
namespace SabreTools.Serialization.Bytes
{
public partial class VPK : IByteSerializer<Models.VPK.File>
{
/// <inheritdoc/>
public Models.VPK.File? Deserialize(byte[]? data, int offset)
{
// If the data is invalid
if (data == null)
return null;
// If the offset is out of bounds
if (offset < 0 || offset >= data.Length)
return null;
// Create a memory stream and parse that
MemoryStream dataStream = new MemoryStream(data, offset, data.Length - offset);
return new Streams.VPK().Deserialize(dataStream);
}
}
}

View File

@@ -1,24 +0,0 @@
using System.IO;
using SabreTools.Serialization.Interfaces;
namespace SabreTools.Serialization.Bytes
{
public partial class WAD : IByteSerializer<Models.WAD.File>
{
/// <inheritdoc/>
public Models.WAD.File? Deserialize(byte[]? data, int offset)
{
// If the data is invalid
if (data == null)
return null;
// If the offset is out of bounds
if (offset < 0 || offset >= data.Length)
return null;
// Create a memory stream and parse that
MemoryStream dataStream = new MemoryStream(data, offset, data.Length - offset);
return new Streams.WAD().Deserialize(dataStream);
}
}
}

View File

@@ -1,24 +0,0 @@
using System.IO;
using SabreTools.Serialization.Interfaces;
namespace SabreTools.Serialization.Bytes
{
public partial class XZP : IByteSerializer<Models.XZP.File>
{
/// <inheritdoc/>
public Models.XZP.File? Deserialize(byte[]? data, int offset)
{
// If the data is invalid
if (data == null)
return null;
// If the offset is out of bounds
if (offset < 0 || offset >= data.Length)
return null;
// Create a memory stream and parse that
MemoryStream dataStream = new MemoryStream(data, offset, data.Length - offset);
return new Streams.XZP().Deserialize(dataStream);
}
}
}

View File

@@ -1,5 +1,6 @@
using System.Collections.Generic;
using System.Linq;
using SabreTools.Hashing;
using SabreTools.Models.Hashfile;
using SabreTools.Serialization.Interfaces;
@@ -8,10 +9,10 @@ namespace SabreTools.Serialization.CrossModel
public partial class Hashfile : IModelSerializer<Models.Hashfile.Hashfile, Models.Metadata.MetadataFile>
{
/// <inheritdoc/>
public Models.Hashfile.Hashfile? Deserialize(Models.Metadata.MetadataFile? obj) => Deserialize(obj, Hash.CRC);
public Models.Hashfile.Hashfile? Deserialize(Models.Metadata.MetadataFile? obj) => Deserialize(obj, HashType.CRC32);
/// <inheritdoc/>
public Models.Hashfile.Hashfile? Deserialize(Models.Metadata.MetadataFile? obj, Hash hash)
public Models.Hashfile.Hashfile? Deserialize(Models.Metadata.MetadataFile? obj, HashType hash)
{
if (obj == null)
return null;
@@ -73,7 +74,7 @@ namespace SabreTools.Serialization.CrossModel
/// <summary>
/// Convert from <cref="Models.Metadata.MetadataFile"/> to an array of <cref="Models.Hashfile.Hashfile"/>
/// </summary>
public static Models.Hashfile.Hashfile[]? ConvertArrayFromInternalModel(Models.Metadata.MetadataFile? item, Hash hash)
public static Models.Hashfile.Hashfile[]? ConvertArrayFromInternalModel(Models.Metadata.MetadataFile? item, HashType hash)
{
if (item == null)
return null;
@@ -93,7 +94,7 @@ namespace SabreTools.Serialization.CrossModel
/// <summary>
/// Convert from <cref="Models.Metadata.Machine"/> to <cref="Models.Hashfile.Hashfile"/>
/// </summary>
private static Models.Hashfile.Hashfile ConvertMachineFromInternalModel(Models.Metadata.Machine item, Hash hash)
private static Models.Hashfile.Hashfile ConvertMachineFromInternalModel(Models.Metadata.Machine item, HashType hash)
{
var roms = item.Read<Models.Metadata.Rom[]>(Models.Metadata.Machine.RomKey);
if (roms == null)
@@ -101,43 +102,43 @@ namespace SabreTools.Serialization.CrossModel
return new Models.Hashfile.Hashfile
{
SFV = hash == Hash.CRC
SFV = hash == HashType.CRC32 || hash == HashType.CRC32_ISO || hash == HashType.CRC32_Naive || hash == HashType.CRC32_Optimized || hash == HashType.CRC32_Parallel
? roms
.Where(r => r != null)
.Select(ConvertToSFV)
.ToArray()
: null,
MD5 = hash == Hash.MD5
MD5 = hash == HashType.MD5
? roms
.Where(r => r != null)
.Select(ConvertToMD5)
.ToArray()
: null,
SHA1 = hash == Hash.SHA1
SHA1 = hash == HashType.SHA1
? roms
.Where(r => r != null)
.Select(ConvertToSHA1)
.ToArray()
: null,
SHA256 = hash == Hash.SHA256
SHA256 = hash == HashType.SHA256
? roms
.Where(r => r != null)
.Select(ConvertToSHA256)
.ToArray()
: null,
SHA384 = hash == Hash.SHA384
SHA384 = hash == HashType.SHA384
? roms
.Where(r => r != null)
.Select(ConvertToSHA384)
.ToArray()
: null,
SHA512 = hash == Hash.SHA512
SHA512 = hash == HashType.SHA512
? roms
.Where(r => r != null)
.Select(ConvertToSHA512)
.ToArray()
: null,
SpamSum = hash == Hash.SpamSum
SpamSum = hash == HashType.SpamSum
? roms
.Where(r => r != null)
.Select(ConvertToSpamSum)

View File

@@ -2,16 +2,15 @@ using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using SabreTools.IO;
using SabreTools.IO.Extensions;
using SabreTools.Models.AACS;
using SabreTools.Serialization.Interfaces;
namespace SabreTools.Serialization.Streams
namespace SabreTools.Serialization.Deserializers
{
public partial class AACS : IStreamSerializer<MediaKeyBlock>
public class AACS : BaseBinaryDeserializer<MediaKeyBlock>
{
/// <inheritdoc/>
public MediaKeyBlock? Deserialize(Stream? data)
public override MediaKeyBlock? Deserialize(Stream? data)
{
// If the data is invalid
if (data == null || data.Length == 0 || !data.CanSeek || !data.CanRead)

View File

@@ -0,0 +1,7 @@
namespace SabreTools.Serialization.Deserializers
{
public class ArchiveDotOrg : XmlFile<Models.ArchiveDotOrg.Files>
{
// All logic taken care of in the base class
}
}

View File

@@ -4,14 +4,23 @@ using System.Linq;
using System.Text;
using SabreTools.IO.Readers;
using SabreTools.Models.AttractMode;
using SabreTools.Serialization.Interfaces;
namespace SabreTools.Serialization.Streams
namespace SabreTools.Serialization.Deserializers
{
public partial class AttractMode : IStreamSerializer<MetadataFile>
public class AttractMode : BaseBinaryDeserializer<MetadataFile>
{
#region Constants
public const int HeaderWithoutRomnameCount = 17;
public const int HeaderWithRomnameCount = 22;
#endregion
#region IStreamDeserializer
/// <inheritdoc/>
public MetadataFile? Deserialize(Stream? data)
public override MetadataFile? Deserialize(Stream? data)
{
// If the stream is null
if (data == null)
@@ -41,7 +50,7 @@ namespace SabreTools.Serialization.Streams
// Parse the line into a row
Row row;
if (reader.Line.Count < Serialization.AttractMode.HeaderWithRomnameCount)
if (reader.Line.Count < HeaderWithRomnameCount)
{
row = new Row
{
@@ -65,8 +74,8 @@ namespace SabreTools.Serialization.Streams
};
// If we have additional fields
if (reader.Line.Count > Serialization.AttractMode.HeaderWithoutRomnameCount)
row.ADDITIONAL_ELEMENTS = reader.Line.Skip(Serialization.AttractMode.HeaderWithoutRomnameCount).ToArray();
if (reader.Line.Count > HeaderWithoutRomnameCount)
row.ADDITIONAL_ELEMENTS = reader.Line.Skip(HeaderWithoutRomnameCount).ToArray();
}
else
{
@@ -92,8 +101,8 @@ namespace SabreTools.Serialization.Streams
};
// If we have additional fields
if (reader.Line.Count > Serialization.AttractMode.HeaderWithRomnameCount)
row.ADDITIONAL_ELEMENTS = reader.Line.Skip(Serialization.AttractMode.HeaderWithRomnameCount).ToArray();
if (reader.Line.Count > HeaderWithRomnameCount)
row.ADDITIONAL_ELEMENTS = reader.Line.Skip(HeaderWithRomnameCount).ToArray();
}
rows.Add(row);
@@ -103,5 +112,7 @@ namespace SabreTools.Serialization.Streams
dat.Row = rows.ToArray();
return dat;
}
#endregion
}
}

View File

@@ -1,16 +1,15 @@
using System.IO;
using System.Text;
using SabreTools.IO;
using SabreTools.IO.Extensions;
using SabreTools.Models.BDPlus;
using SabreTools.Serialization.Interfaces;
using static SabreTools.Models.BDPlus.Constants;
namespace SabreTools.Serialization.Streams
namespace SabreTools.Serialization.Deserializers
{
public partial class BDPlus : IStreamSerializer<SVM>
public class BDPlus : BaseBinaryDeserializer<SVM>
{
/// <inheritdoc/>
public SVM? Deserialize(Stream? data)
public override SVM? Deserialize(Stream? data)
{
// If the data is invalid
if (data == null || data.Length == 0 || !data.CanSeek || !data.CanRead)

View File

@@ -1,16 +1,15 @@
using System.IO;
using System.Text;
using SabreTools.IO;
using SabreTools.IO.Extensions;
using SabreTools.Models.BFPK;
using SabreTools.Serialization.Interfaces;
using static SabreTools.Models.BFPK.Constants;
namespace SabreTools.Serialization.Streams
namespace SabreTools.Serialization.Deserializers
{
public partial class BFPK : IStreamSerializer<Archive>
public class BFPK : BaseBinaryDeserializer<Archive>
{
/// <inheritdoc/>
public Archive? Deserialize(Stream? data)
public override Archive? Deserialize(Stream? data)
{
// If the data is invalid
if (data == null || data.Length == 0 || !data.CanSeek || !data.CanRead)

View File

@@ -1,17 +1,16 @@
using System.IO;
using System.Linq;
using System.Text;
using SabreTools.IO;
using SabreTools.IO.Extensions;
using SabreTools.Models.BSP;
using SabreTools.Serialization.Interfaces;
using static SabreTools.Models.BSP.Constants;
namespace SabreTools.Serialization.Streams
namespace SabreTools.Serialization.Deserializers
{
public partial class BSP : IStreamSerializer<Models.BSP.File>
public class BSP : BaseBinaryDeserializer<Models.BSP.File>
{
/// <inheritdoc/>
public Models.BSP.File? Deserialize(Stream? data)
public override Models.BSP.File? Deserialize(Stream? data)
{
// If the data is invalid
if (data == null || data.Length == 0 || !data.CanSeek || !data.CanRead)
@@ -149,6 +148,8 @@ namespace SabreTools.Serialization.Streams
for (int i = 0; i < textureHeader.TextureCount; i++)
{
offsets[i] = data.ReadUInt32();
if (data.Position >= data.Length)
break;
}
textureHeader.Offsets = offsets;

View File

@@ -0,0 +1,134 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using SabreTools.Serialization.Interfaces;
namespace SabreTools.Serialization.Deserializers
{
/// <summary>
/// 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>
public abstract class BaseBinaryDeserializer<TModel> :
IByteDeserializer<TModel>,
IFileDeserializer<TModel>,
IStreamDeserializer<TModel>
{
#region IByteDeserializer
/// <inheritdoc/>
public virtual TModel? Deserialize(byte[]? data, int offset)
{
// If the data is invalid
if (data == null)
return default;
// If the offset is out of bounds
if (offset < 0 || offset >= data.Length)
return default;
// Create a memory stream and parse that
var dataStream = new MemoryStream(data, offset, data.Length - offset);
return DeserializeStream(dataStream);
}
#endregion
#region IFileDeserializer
/// <inheritdoc/>
public virtual TModel? Deserialize(string? path)
{
using var stream = PathProcessor.OpenStream(path);
return DeserializeStream(stream);
}
#endregion
#region IStreamDeserializer
/// <inheritdoc/>
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>()
{
var assembly = Assembly.GetExecutingAssembly();
if (assembly == null)
return default;
// If not all types can be loaded, use the ones that could be
List<Type> assemblyTypes = [];
try
{
assemblyTypes = assembly.GetTypes().ToList<Type>();
}
catch (ReflectionTypeLoadException rtle)
{
assemblyTypes = rtle.Types.Where(t => t != null)!.ToList<Type>();
}
// Loop through all types
foreach (Type type in assemblyTypes)
{
// If the type isn't a class or doesn't implement the interface
if (!type.IsClass || type.GetInterface(typeof(TDeserializer).Name) == null)
continue;
// Try to create a concrete instance of the type
var instance = (TDeserializer?)Activator.CreateInstance(type);
if (instance != null)
return instance;
}
return default;
}
#endregion
}
}

View File

@@ -2,17 +2,16 @@ using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using SabreTools.IO;
using SabreTools.IO.Extensions;
using SabreTools.Models.CFB;
using SabreTools.Serialization.Interfaces;
using static SabreTools.Models.CFB.Constants;
namespace SabreTools.Serialization.Streams
namespace SabreTools.Serialization.Deserializers
{
public partial class CFB : IStreamSerializer<Binary>
public class CFB : BaseBinaryDeserializer<Binary>
{
/// <inheritdoc/>
public Binary? Deserialize(Stream? data)
public override Binary? Deserialize(Stream? data)
{
// If the data is invalid
if (data == null || data.Length == 0 || !data.CanSeek || !data.CanRead)

View File

@@ -1,16 +1,15 @@
using System;
using System.IO;
using System.Text;
using SabreTools.IO;
using SabreTools.IO.Extensions;
using SabreTools.Models.N3DS;
using SabreTools.Serialization.Interfaces;
namespace SabreTools.Serialization.Streams
namespace SabreTools.Serialization.Deserializers
{
public partial class CIA : IStreamSerializer<Models.N3DS.CIA>
public class CIA : BaseBinaryDeserializer<Models.N3DS.CIA>
{
/// <inheritdoc/>
public Models.N3DS.CIA? Deserialize(Stream? data)
public override Models.N3DS.CIA? Deserialize(Stream? data)
{
// If the data is invalid
if (data == null || data.Length == 0 || !data.CanSeek || !data.CanRead)

View File

@@ -0,0 +1,32 @@
using System.IO;
using System.Text;
namespace SabreTools.Serialization.Deserializers
{
public class Catalog : JsonFile<Models.Xbox.Catalog>
{
#region IByteDeserializer
/// <remarks>Catalog.js file is encoded as UTF-16 LE</remarks>
public override Models.Xbox.Catalog? Deserialize(byte[]? data, int offset)
=> Deserialize(data, offset, new UnicodeEncoding());
#endregion
#region IFileDeserializer
/// <remarks>Catalog.js file is encoded as UTF-16 LE</remarks>
public override Models.Xbox.Catalog? Deserialize(string? path)
=> Deserialize(path, new UnicodeEncoding());
#endregion
#region IStreamDeserializer
/// <remarks>Catalog.js file is encoded as UTF-16 LE</remarks>
public override Models.Xbox.Catalog? Deserialize(Stream? data)
=> Deserialize(data, new UnicodeEncoding());
#endregion
}
}

View File

@@ -4,14 +4,76 @@ using System.IO;
using System.Text;
using SabreTools.IO.Readers;
using SabreTools.Models.ClrMamePro;
using SabreTools.Serialization.Interfaces;
namespace SabreTools.Serialization.Streams
namespace SabreTools.Serialization.Deserializers
{
public partial class ClrMamePro : IStreamSerializer<MetadataFile>
public class ClrMamePro : BaseBinaryDeserializer<MetadataFile>
{
#region IByteDeserializer
/// <inheritdoc cref="IByteDeserializer.Deserialize(byte[]?, int)"/>
public static MetadataFile? DeserializeBytes(byte[]? data, int offset, bool quotes = true)
{
var deserializer = new ClrMamePro();
return deserializer.Deserialize(data, offset, quotes);
}
/// <inheritdoc/>
public MetadataFile? Deserialize(Stream? data) => Deserialize(data, true);
public override MetadataFile? Deserialize(byte[]? data, int offset)
=> Deserialize(data, offset, true);
/// <inheritdoc/>
public MetadataFile? Deserialize(byte[]? data, int offset, bool quotes)
{
// If the data is invalid
if (data == null)
return default;
// If the offset is out of bounds
if (offset < 0 || offset >= data.Length)
return default;
// Create a memory stream and parse that
var dataStream = new MemoryStream(data, offset, data.Length - offset);
return DeserializeStream(dataStream, quotes);
}
#endregion
#region IFileDeserializer
/// <inheritdoc cref="IFileDeserializer.Deserialize(string?)"/>
public static MetadataFile? DeserializeFile(string? path, bool quotes = true)
{
var deserializer = new ClrMamePro();
return deserializer.Deserialize(path, quotes);
}
/// <inheritdoc/>
public override MetadataFile? Deserialize(string? path)
=> Deserialize(path, true);
/// <inheritdoc/>
public MetadataFile? Deserialize(string? path, bool quotes)
{
using var stream = PathProcessor.OpenStream(path);
return DeserializeStream(stream, quotes);
}
#endregion
#region IStreamDeserializer
/// <inheritdoc cref="IStreamDeserializer.Deserialize(Stream?)"/>
public static MetadataFile? DeserializeStream(Stream? data, bool quotes = true)
{
var deserializer = new ClrMamePro();
return deserializer.Deserialize(data, quotes);
}
/// <inheritdoc/>
public override MetadataFile? Deserialize(Stream? data)
=> Deserialize(data, true);
/// <inheritdoc cref="Deserialize(Stream)"/>
public MetadataFile? Deserialize(Stream? data, bool quotes)
@@ -891,5 +953,7 @@ namespace SabreTools.Serialization.Streams
driver.ADDITIONAL_ELEMENTS = itemAdditional.ToArray();
return driver;
}
#endregion
}
}

View File

@@ -3,16 +3,15 @@ using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
using SabreTools.IO;
using SabreTools.IO.Extensions;
using SabreTools.Models.CueSheets;
using SabreTools.Serialization.Interfaces;
namespace SabreTools.Serialization.Streams
namespace SabreTools.Serialization.Deserializers
{
public partial class CueSheet : IStreamSerializer<Models.CueSheets.CueSheet>
public class CueSheet : BaseBinaryDeserializer<Models.CueSheets.CueSheet>
{
/// <inheritdoc/>
public Models.CueSheets.CueSheet? Deserialize(Stream? data)
public override Models.CueSheets.CueSheet? Deserialize(Stream? data)
{
// If the data is invalid
if (data == null || data.Length == 0 || !data.CanSeek || !data.CanRead)
@@ -513,26 +512,15 @@ namespace SabreTools.Serialization.Streams
/// <returns>CueFileType, if possible</returns>
private static CueFileType GetFileType(string? fileType)
{
switch (fileType?.ToLowerInvariant())
return (fileType?.ToLowerInvariant()) switch
{
case "binary":
return CueFileType.BINARY;
case "motorola":
return CueFileType.MOTOROLA;
case "aiff":
return CueFileType.AIFF;
case "wave":
return CueFileType.WAVE;
case "mp3":
return CueFileType.MP3;
default:
return CueFileType.BINARY;
}
"binary" => CueFileType.BINARY,
"motorola" => CueFileType.MOTOROLA,
"aiff" => CueFileType.AIFF,
"wave" => CueFileType.WAVE,
"mp3" => CueFileType.MP3,
_ => CueFileType.BINARY,
};
}
/// <summary>
@@ -542,35 +530,18 @@ namespace SabreTools.Serialization.Streams
/// <returns>CueTrackDataType, if possible (default AUDIO)</returns>
private static CueTrackDataType GetDataType(string? dataType)
{
switch (dataType?.ToLowerInvariant())
return (dataType?.ToLowerInvariant()) switch
{
case "audio":
return CueTrackDataType.AUDIO;
case "cdg":
return CueTrackDataType.CDG;
case "mode1/2048":
return CueTrackDataType.MODE1_2048;
case "mode1/2352":
return CueTrackDataType.MODE1_2352;
case "mode2/2336":
return CueTrackDataType.MODE2_2336;
case "mode2/2352":
return CueTrackDataType.MODE2_2352;
case "cdi/2336":
return CueTrackDataType.CDI_2336;
case "cdi/2352":
return CueTrackDataType.CDI_2352;
default:
return CueTrackDataType.AUDIO;
}
"audio" => CueTrackDataType.AUDIO,
"cdg" => CueTrackDataType.CDG,
"mode1/2048" => CueTrackDataType.MODE1_2048,
"mode1/2352" => CueTrackDataType.MODE1_2352,
"mode2/2336" => CueTrackDataType.MODE2_2336,
"mode2/2352" => CueTrackDataType.MODE2_2352,
"cdi/2336" => CueTrackDataType.CDI_2336,
"cdi/2352" => CueTrackDataType.CDI_2352,
_ => CueTrackDataType.AUDIO,
};
}
/// <summary>
@@ -619,4 +590,4 @@ namespace SabreTools.Serialization.Streams
#endregion
}
}
}

View File

@@ -3,14 +3,13 @@ using System.IO;
using System.Text;
using SabreTools.IO.Readers;
using SabreTools.Models.DosCenter;
using SabreTools.Serialization.Interfaces;
namespace SabreTools.Serialization.Streams
namespace SabreTools.Serialization.Deserializers
{
public partial class DosCenter : IStreamSerializer<MetadataFile>
public class DosCenter : BaseBinaryDeserializer<MetadataFile>
{
/// <inheritdoc/>
public MetadataFile? Deserialize(Stream? data)
public override MetadataFile? Deserialize(Stream? data)
{
// If the stream is null
if (data == null)

View File

@@ -4,14 +4,13 @@ using System.Linq;
using System.Text;
using SabreTools.IO.Readers;
using SabreTools.Models.EverdriveSMDB;
using SabreTools.Serialization.Interfaces;
namespace SabreTools.Serialization.Streams
namespace SabreTools.Serialization.Deserializers
{
public partial class EverdriveSMDB : IStreamSerializer<MetadataFile>
public class EverdriveSMDB : BaseBinaryDeserializer<MetadataFile>
{
/// <inheritdoc/>
public MetadataFile? Deserialize(Stream? data)
public override MetadataFile? Deserialize(Stream? data)
{
// If the stream is null
if (data == null)

View File

@@ -1,16 +1,15 @@
using System.Collections.Generic;
using System.IO;
using System.Text;
using SabreTools.IO;
using SabreTools.IO.Extensions;
using SabreTools.Models.GCF;
using SabreTools.Serialization.Interfaces;
namespace SabreTools.Serialization.Streams
namespace SabreTools.Serialization.Deserializers
{
public partial class GCF : IStreamSerializer<Models.GCF.File>
public class GCF : BaseBinaryDeserializer<Models.GCF.File>
{
/// <inheritdoc/>
public Models.GCF.File? Deserialize(Stream? data)
public override Models.GCF.File? Deserialize(Stream? data)
{
// If the data is invalid
if (data == null || data.Length == 0 || !data.CanSeek || !data.CanRead)

View File

@@ -2,18 +2,82 @@ using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using SabreTools.Hashing;
using SabreTools.Models.Hashfile;
using SabreTools.Serialization.Interfaces;
namespace SabreTools.Serialization.Streams
namespace SabreTools.Serialization.Deserializers
{
public partial class Hashfile : IStreamSerializer<Models.Hashfile.Hashfile>
// TODO: Create variants for the implemented types
public class Hashfile : BaseBinaryDeserializer<Models.Hashfile.Hashfile>
{
#region IByteDeserializer
/// <inheritdoc cref="IByteDeserializer.Deserialize(byte[]?, int)"/>
public static Models.Hashfile.Hashfile? DeserializeBytes(byte[]? data, int offset, HashType hash = HashType.CRC32)
{
var deserializer = new Hashfile();
return deserializer.Deserialize(data, offset, hash);
}
/// <inheritdoc/>
public Models.Hashfile.Hashfile? Deserialize(Stream? data) => Deserialize(data, Hash.CRC);
public override Models.Hashfile.Hashfile? Deserialize(byte[]? data, int offset)
=> Deserialize(data, offset, HashType.CRC32);
/// <inheritdoc/>
public Models.Hashfile.Hashfile? Deserialize(byte[]? data, int offset, HashType hash)
{
// If the data is invalid
if (data == null)
return null;
// If the offset is out of bounds
if (offset < 0 || offset >= data.Length)
return null;
// Create a memory stream and parse that
var dataStream = new MemoryStream(data, offset, data.Length - offset);
return DeserializeStream(dataStream, hash);
}
#endregion
#region IFileDeserializer
/// <inheritdoc cref="IFileDeserializer.Deserialize(string?)"/>
public static Models.Hashfile.Hashfile? DeserializeFile(string? path, HashType hash = HashType.CRC32)
{
var deserializer = new Hashfile();
return deserializer.Deserialize(path, hash);
}
/// <inheritdoc/>
public override Models.Hashfile.Hashfile? Deserialize(string? path)
=> Deserialize(path, HashType.CRC32);
/// <inheritdoc/>
public Models.Hashfile.Hashfile? Deserialize(string? path, HashType hash)
{
using var stream = PathProcessor.OpenStream(path);
return DeserializeStream(stream, hash);
}
#endregion
#region IStreamDeserializer
/// <inheritdoc cref="IStreamDeserializer.Deserialize(Stream?)"/>
public static Models.Hashfile.Hashfile? DeserializeStream(Stream? data, HashType hash = HashType.CRC32)
{
var deserializer = new Hashfile();
return deserializer.Deserialize(data, hash);
}
/// <inheritdoc/>
public override Models.Hashfile.Hashfile? Deserialize(Stream? data)
=> Deserialize(data, HashType.CRC32);
/// <inheritdoc cref="Deserialize(Stream)"/>
public Models.Hashfile.Hashfile? Deserialize(Stream? data, Hash hash)
public Models.Hashfile.Hashfile? Deserialize(Stream? data, HashType hash)
{
// If the stream is null
if (data == null)
@@ -41,7 +105,11 @@ namespace SabreTools.Serialization.Streams
// Parse the line into a hash
switch (hash)
{
case Hash.CRC:
case HashType.CRC32:
case HashType.CRC32_ISO:
case HashType.CRC32_Naive:
case HashType.CRC32_Optimized:
case HashType.CRC32_Parallel:
var sfv = new SFV
{
#if NETFRAMEWORK
@@ -54,7 +122,7 @@ namespace SabreTools.Serialization.Streams
};
hashes.Add(sfv);
break;
case Hash.MD5:
case HashType.MD5:
var md5 = new MD5
{
Hash = lineParts[0],
@@ -66,7 +134,7 @@ namespace SabreTools.Serialization.Streams
};
hashes.Add(md5);
break;
case Hash.SHA1:
case HashType.SHA1:
var sha1 = new SHA1
{
Hash = lineParts[0],
@@ -78,7 +146,7 @@ namespace SabreTools.Serialization.Streams
};
hashes.Add(sha1);
break;
case Hash.SHA256:
case HashType.SHA256:
var sha256 = new SHA256
{
Hash = lineParts[0],
@@ -90,7 +158,7 @@ namespace SabreTools.Serialization.Streams
};
hashes.Add(sha256);
break;
case Hash.SHA384:
case HashType.SHA384:
var sha384 = new SHA384
{
Hash = lineParts[0],
@@ -102,7 +170,7 @@ namespace SabreTools.Serialization.Streams
};
hashes.Add(sha384);
break;
case Hash.SHA512:
case HashType.SHA512:
var sha512 = new SHA512
{
Hash = lineParts[0],
@@ -114,7 +182,7 @@ namespace SabreTools.Serialization.Streams
};
hashes.Add(sha512);
break;
case Hash.SpamSum:
case HashType.SpamSum:
var spamSum = new SpamSum
{
Hash = lineParts[0],
@@ -132,30 +200,36 @@ namespace SabreTools.Serialization.Streams
// Assign the hashes to the hashfile and return
switch (hash)
{
case Hash.CRC:
case HashType.CRC32:
case HashType.CRC32_ISO:
case HashType.CRC32_Naive:
case HashType.CRC32_Optimized:
case HashType.CRC32_Parallel:
dat.SFV = hashes.Cast<SFV>().ToArray();
break;
case Hash.MD5:
case HashType.MD5:
dat.MD5 = hashes.Cast<MD5>().ToArray();
break;
case Hash.SHA1:
case HashType.SHA1:
dat.SHA1 = hashes.Cast<SHA1>().ToArray();
break;
case Hash.SHA256:
case HashType.SHA256:
dat.SHA256 = hashes.Cast<SHA256>().ToArray();
break;
case Hash.SHA384:
case HashType.SHA384:
dat.SHA384 = hashes.Cast<SHA384>().ToArray();
break;
case Hash.SHA512:
case HashType.SHA512:
dat.SHA512 = hashes.Cast<SHA512>().ToArray();
break;
case Hash.SpamSum:
case HashType.SpamSum:
dat.SpamSum = hashes.Cast<SpamSum>().ToArray();
break;
}
dat.ADDITIONAL_ELEMENTS = [.. additional];
return dat;
}
#endregion
}
}

View File

@@ -1,15 +1,13 @@
using System;
using System.IO;
using System.Text;
using SabreTools.IO;
using SabreTools.Serialization.Interfaces;
using SabreTools.IO.Extensions;
namespace SabreTools.Serialization.Streams
namespace SabreTools.Serialization.Deserializers
{
public partial class IRD : IStreamSerializer<Models.IRD.File>
public class IRD : BaseBinaryDeserializer<Models.IRD.File>
{
/// <inheritdoc/>
public Models.IRD.File? Deserialize(Stream? data)
public override Models.IRD.File? Deserialize(Stream? data)
{
// If the data is invalid
if (data == null || data.Length == 0 || !data.CanSeek || !data.CanRead)

View File

@@ -1,18 +1,17 @@
using System.Collections.Generic;
using System.IO;
using System.Text;
using SabreTools.IO;
using SabreTools.IO.Extensions;
using SabreTools.Models.InstallShieldCabinet;
using SabreTools.Serialization.Interfaces;
using static SabreTools.Models.InstallShieldCabinet.Constants;
namespace SabreTools.Serialization.Streams
namespace SabreTools.Serialization.Deserializers
{
// TODO: Add multi-cabinet reading
public partial class InstallShieldCabinet : IStreamSerializer<Cabinet>
public class InstallShieldCabinet : BaseBinaryDeserializer<Cabinet>
{
/// <inheritdoc/>
public Cabinet? Deserialize(Stream? data)
public override Cabinet? Deserialize(Stream? data)
{
// If the data is invalid
if (data == null || data.Length == 0 || !data.CanSeek || !data.CanRead)

View File

@@ -0,0 +1,95 @@
using System.IO;
using System.Text;
using Newtonsoft.Json;
namespace SabreTools.Serialization.Deserializers
{
/// <summary>
/// Base class for other JSON serializers
/// </summary>
/// <typeparam name="T"></typeparam>
public class JsonFile<T> : BaseBinaryDeserializer<T>
{
#region IByteDeserializer
/// <inheritdoc/>
public override T? Deserialize(byte[]? data, int offset)
=> Deserialize(data, offset, new UTF8Encoding(false));
/// <summary>
/// Deserialize a byte array into <typeparamref name="T"/>
/// </summary>
/// <typeparam name="T">Type of object to deserialize to</typeparam>
/// <param name="data">Byte array to parse</param>
/// <param name="offset">Offset into the byte array</param>
/// <param name="encoding">Encoding to parse text as</param>
/// <returns>Filled object on success, null on error</returns>
public T? Deserialize(byte[]? data, int offset, Encoding encoding)
{
// If the data is invalid
if (data == null)
return default;
// If the offset is out of bounds
if (offset < 0 || offset >= data.Length)
return default;
// Create a memory stream and parse that
var dataStream = new MemoryStream(data, offset, data.Length - offset);
return Deserialize(dataStream, encoding);
}
#endregion
#region IFileDeserializer
/// <inheritdoc/>
public override T? Deserialize(string? path)
=> Deserialize(path, new UTF8Encoding(false));
/// <summary>
/// Deserialize a file into <typeparamref name="T"/>
/// </summary>
/// <typeparam name="T">Type of object to deserialize to</typeparam>
/// <param name="path">Path to deserialize from</param>
/// <param name="encoding">Encoding to parse text as</param>
/// <returns>Filled object on success, null on error</returns>
public T? Deserialize(string? path, Encoding encoding)
{
using var data = PathProcessor.OpenStream(path);
return Deserialize(data, encoding);
}
#endregion
#region IStreamDeserializer
/// <inheritdoc/>
public override T? Deserialize(Stream? data)
=> Deserialize(data, new UTF8Encoding(false));
/// <summary>
/// Deserialize a Stream into <typeparamref name="T"/>
/// </summary>
/// <typeparam name="T">Type of object to deserialize to</typeparam>
/// <param name="data">Stream to parse</param>
/// <param name="encoding">Text encoding to use</param>
/// <returns>Filled object on success, null on error</returns>
public T? Deserialize(Stream? data, Encoding encoding)
{
// If the stream is null
if (data == null)
return default;
// Setup the serializer and the reader
var serializer = JsonSerializer.Create();
var streamReader = new StreamReader(data, encoding);
var jsonReader = new JsonTextReader(streamReader);
// Perform the deserialization and return
return serializer.Deserialize<T>(jsonReader);
}
#endregion
}
}

View File

@@ -1,17 +1,16 @@
using System.Collections.Generic;
using System.IO;
using System.Text;
using SabreTools.IO;
using SabreTools.IO.Extensions;
using SabreTools.Models.LinearExecutable;
using SabreTools.Serialization.Interfaces;
using static SabreTools.Models.LinearExecutable.Constants;
namespace SabreTools.Serialization.Streams
namespace SabreTools.Serialization.Deserializers
{
public partial class LinearExecutable : IStreamSerializer<Executable>
public class LinearExecutable : BaseBinaryDeserializer<Executable>
{
/// <inheritdoc/>
public Executable? Deserialize(Stream? data)
public override Executable? Deserialize(Stream? data)
{
// If the data is invalid
if (data == null || data.Length == 0 || !data.CanSeek || !data.CanRead)

View File

@@ -3,14 +3,13 @@ using System.Collections.Generic;
using System.IO;
using System.Text;
using SabreTools.Models.Listrom;
using SabreTools.Serialization.Interfaces;
namespace SabreTools.Serialization.Streams
namespace SabreTools.Serialization.Deserializers
{
public partial class Listrom : IStreamSerializer<MetadataFile>
public class Listrom : BaseBinaryDeserializer<MetadataFile>
{
/// <inheritdoc/>
public MetadataFile? Deserialize(Stream? data)
public override MetadataFile? Deserialize(Stream? data)
{
// If the stream is null
if (data == null)

View File

@@ -0,0 +1,7 @@
namespace SabreTools.Serialization.Deserializers
{
public class Listxml : XmlFile<Models.Listxml.Mame>
{
// All logic taken care of in the base class
}
}

View File

@@ -0,0 +1,7 @@
namespace SabreTools.Serialization.Deserializers
{
public class Logiqx : XmlFile<Models.Logiqx.Datafile>
{
// All logic taken care of in the base class
}
}

View File

@@ -0,0 +1,7 @@
namespace SabreTools.Serialization.Deserializers
{
public class M1 : XmlFile<Models.Listxml.M1>
{
// All logic taken care of in the base class
}
}

View File

@@ -1,16 +1,15 @@
using System.IO;
using System.Text;
using SabreTools.IO;
using SabreTools.IO.Extensions;
using SabreTools.Models.MSDOS;
using SabreTools.Serialization.Interfaces;
using static SabreTools.Models.MSDOS.Constants;
namespace SabreTools.Serialization.Streams
namespace SabreTools.Serialization.Deserializers
{
public partial class MSDOS : IStreamSerializer<Executable>
public class MSDOS : BaseBinaryDeserializer<Executable>
{
/// <inheritdoc/>
public Executable? Deserialize(Stream? data)
public override Executable? Deserialize(Stream? data)
{
// If the data is invalid
if (data == null || data.Length == 0 || !data.CanSeek || !data.CanRead)

View File

@@ -1,17 +1,16 @@
using System.IO;
using System.Text;
using SabreTools.IO;
using SabreTools.IO.Extensions;
using SabreTools.Models.MicrosoftCabinet;
using SabreTools.Serialization.Interfaces;
using static SabreTools.Models.MicrosoftCabinet.Constants;
namespace SabreTools.Serialization.Streams
namespace SabreTools.Serialization.Deserializers
{
// TODO: Add multi-cabinet reading
public partial class MicrosoftCabinet : IStreamSerializer<Cabinet>
public class MicrosoftCabinet : BaseBinaryDeserializer<Cabinet>
{
/// <inheritdoc/>
public Cabinet? Deserialize(Stream? data)
public override Cabinet? Deserialize(Stream? data)
{
// If the data is invalid
if (data == null || data.Length == 0 || !data.CanSeek || !data.CanRead)

View File

@@ -2,17 +2,16 @@ using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using SabreTools.IO;
using SabreTools.IO.Extensions;
using SabreTools.Models.MoPaQ;
using SabreTools.Serialization.Interfaces;
using static SabreTools.Models.MoPaQ.Constants;
namespace SabreTools.Serialization.Streams
namespace SabreTools.Serialization.Deserializers
{
public partial class MoPaQ : IStreamSerializer<Archive>
public class MoPaQ : BaseBinaryDeserializer<Archive>
{
/// <inheritdoc/>
public Archive? Deserialize(Stream? data)
public override Archive? Deserialize(Stream? data)
{
// If the data is invalid
if (data == null || data.Length == 0 || !data.CanSeek || !data.CanRead)

View File

@@ -1,17 +1,16 @@
using System;
using System.IO;
using System.Text;
using SabreTools.IO;
using SabreTools.IO.Extensions;
using SabreTools.Models.N3DS;
using SabreTools.Serialization.Interfaces;
using static SabreTools.Models.N3DS.Constants;
namespace SabreTools.Serialization.Streams
namespace SabreTools.Serialization.Deserializers
{
public partial class N3DS : IStreamSerializer<Cart>
public class N3DS : BaseBinaryDeserializer<Cart>
{
/// <inheritdoc/>
public Cart? Deserialize(Stream? data)
public override Cart? Deserialize(Stream? data)
{
// If the data is invalid
if (data == null || data.Length == 0 || !data.CanSeek || !data.CanRead)

View File

@@ -1,16 +1,15 @@
using System.Collections.Generic;
using System.IO;
using System.Text;
using SabreTools.IO;
using SabreTools.IO.Extensions;
using SabreTools.Models.NCF;
using SabreTools.Serialization.Interfaces;
namespace SabreTools.Serialization.Streams
namespace SabreTools.Serialization.Deserializers
{
public partial class NCF : IStreamSerializer<Models.NCF.File>
public class NCF : BaseBinaryDeserializer<Models.NCF.File>
{
/// <inheritdoc/>
public Models.NCF.File? Deserialize(Stream? data)
public override Models.NCF.File? Deserialize(Stream? data)
{
// If the data is invalid
if (data == null || data.Length == 0 || !data.CanSeek || !data.CanRead)

View File

@@ -2,17 +2,16 @@ using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using SabreTools.IO;
using SabreTools.IO.Extensions;
using SabreTools.Models.NewExecutable;
using SabreTools.Serialization.Interfaces;
using static SabreTools.Models.NewExecutable.Constants;
namespace SabreTools.Serialization.Streams
namespace SabreTools.Serialization.Deserializers
{
public partial class NewExecutable : IStreamSerializer<Executable>
public class NewExecutable : BaseBinaryDeserializer<Executable>
{
/// <inheritdoc/>
public Executable? Deserialize(Stream? data)
public override Executable? Deserialize(Stream? data)
{
// If the data is invalid
if (data == null || data.Length == 0 || !data.CanSeek || !data.CanRead)

View File

@@ -1,16 +1,15 @@
using System.Collections.Generic;
using System.IO;
using System.Text;
using SabreTools.IO;
using SabreTools.IO.Extensions;
using SabreTools.Models.Nitro;
using SabreTools.Serialization.Interfaces;
namespace SabreTools.Serialization.Streams
namespace SabreTools.Serialization.Deserializers
{
public partial class Nitro : IStreamSerializer<Cart>
public class Nitro : BaseBinaryDeserializer<Cart>
{
/// <inheritdoc/>
public Cart? Deserialize(Stream? data)
public override Cart? Deserialize(Stream? data)
{
// If the data is invalid
if (data == null || data.Length == 0 || !data.CanSeek || !data.CanRead)

View File

@@ -0,0 +1,7 @@
namespace SabreTools.Serialization.Deserializers
{
public class OfflineList : XmlFile<Models.OfflineList.Dat>
{
// All logic taken care of in the base class
}
}

View File

@@ -0,0 +1,7 @@
namespace SabreTools.Serialization.Deserializers
{
public class OpenMSX : XmlFile<Models.OpenMSX.SoftwareDb>
{
// All logic taken care of in the base class
}
}

View File

@@ -1,16 +1,15 @@
using System.IO;
using System.Text;
using SabreTools.IO;
using SabreTools.IO.Extensions;
using SabreTools.Models.PAK;
using SabreTools.Serialization.Interfaces;
using static SabreTools.Models.PAK.Constants;
namespace SabreTools.Serialization.Streams
namespace SabreTools.Serialization.Deserializers
{
public partial class PAK : IStreamSerializer<Models.PAK.File>
public class PAK : BaseBinaryDeserializer<Models.PAK.File>
{
/// <inheritdoc/>
public Models.PAK.File? Deserialize(Stream? data)
public override Models.PAK.File? Deserialize(Stream? data)
{
// If the data is invalid
if (data == null || data.Length == 0 || !data.CanSeek || !data.CanRead)

View File

@@ -1,16 +1,15 @@
using System.IO;
using System.Text;
using SabreTools.IO;
using SabreTools.IO.Extensions;
using SabreTools.Models.PFF;
using SabreTools.Serialization.Interfaces;
using static SabreTools.Models.PFF.Constants;
namespace SabreTools.Serialization.Streams
namespace SabreTools.Serialization.Deserializers
{
public partial class PFF : IStreamSerializer<Archive>
public class PFF : BaseBinaryDeserializer<Archive>
{
/// <inheritdoc/>
public Archive? Deserialize(Stream? data)
public override Archive? Deserialize(Stream? data)
{
// If the data is invalid
if (data == null || data.Length == 0 || !data.CanSeek || !data.CanRead)

View File

@@ -1,17 +1,18 @@
using System.Collections.Generic;
using System.IO;
using System.Text;
using SabreTools.IO;
using SabreTools.IO.Extensions;
using SabreTools.Models.PIC;
using SabreTools.Serialization.Interfaces;
using static SabreTools.Models.PIC.Constants;
namespace SabreTools.Serialization.Streams
namespace SabreTools.Serialization.Deserializers
{
public partial class PIC : IStreamSerializer<DiscInformation>
public class PIC : BaseBinaryDeserializer<DiscInformation>
{
#region IStreamDeserializer
/// <inheritdoc/>
public DiscInformation? Deserialize(Stream? data)
public override DiscInformation? Deserialize(Stream? data)
{
// If the data is invalid
if (data == null || data.Length == 0 || !data.CanSeek || !data.CanRead)
@@ -176,5 +177,7 @@ namespace SabreTools.Serialization.Streams
return trailer;
}
#endregion
}
}

View File

@@ -1,16 +1,23 @@
using System.IO;
using System.Text;
using SabreTools.IO;
using SabreTools.IO.Extensions;
using SabreTools.Models.PlayJ;
using SabreTools.Serialization.Interfaces;
using static SabreTools.Models.PlayJ.Constants;
namespace SabreTools.Serialization.Streams
namespace SabreTools.Serialization.Deserializers
{
public partial class PlayJAudio : IStreamSerializer<AudioFile>
public class PlayJAudio : BaseBinaryDeserializer<AudioFile>
{
/// <inheritdoc cref="IStreamDeserializer.Deserialize(Stream?)"/>
public static AudioFile? DeserializeStream(Stream? data, long adjust = 0)
{
var deserializer = new PlayJAudio();
return deserializer.Deserialize(data, adjust);
}
/// <inheritdoc/>
public AudioFile? Deserialize(Stream? data) => Deserialize(data, 0);
public override AudioFile? Deserialize(Stream? data)
=> Deserialize(data, 0);
/// <inheritdoc cref="Deserialize(Stream)"/>
/// <param name="adjust">Offset to adjust all seeking by</param>

View File

@@ -1,14 +1,13 @@
using System.IO;
using SabreTools.IO;
using SabreTools.IO.Extensions;
using SabreTools.Models.PlayJ;
using SabreTools.Serialization.Interfaces;
namespace SabreTools.Serialization.Streams
namespace SabreTools.Serialization.Deserializers
{
public partial class PlayJPlaylist : IStreamSerializer<Playlist>
public class PlayJPlaylist : BaseBinaryDeserializer<Playlist>
{
/// <inheritdoc/>
public Playlist? Deserialize(Stream? data)
public override Playlist? Deserialize(Stream? data)
{
// If the data is invalid
if (data == null || data.Length == 0 || !data.CanSeek || !data.CanRead)
@@ -45,7 +44,7 @@ namespace SabreTools.Serialization.Streams
for (int i = 0; i < playlist.AudioFiles.Length; i++)
{
long currentOffset = data.Position;
var entryHeader = new PlayJAudio().Deserialize(data, currentOffset);
var entryHeader = PlayJAudio.DeserializeStream(data, currentOffset);
if (entryHeader == null)
return null;

View File

@@ -3,17 +3,16 @@ using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using SabreTools.IO;
using SabreTools.IO.Extensions;
using SabreTools.Models.PortableExecutable;
using SabreTools.Serialization.Interfaces;
using static SabreTools.Models.PortableExecutable.Constants;
namespace SabreTools.Serialization.Streams
namespace SabreTools.Serialization.Deserializers
{
public partial class PortableExecutable : IStreamSerializer<Executable>
public class PortableExecutable : BaseBinaryDeserializer<Executable>
{
/// <inheritdoc/>
public Executable? Deserialize(Stream? data)
public override Executable? Deserialize(Stream? data)
{
// If the data is invalid
if (data == null || data.Length == 0 || !data.CanSeek || !data.CanRead)

View File

@@ -1,16 +1,15 @@
using System.IO;
using System.Text;
using SabreTools.IO;
using SabreTools.IO.Extensions;
using SabreTools.Models.Quantum;
using SabreTools.Serialization.Interfaces;
using static SabreTools.Models.Quantum.Constants;
namespace SabreTools.Serialization.Streams
namespace SabreTools.Serialization.Deserializers
{
public partial class Quantum : IStreamSerializer<Archive>
public class Quantum : BaseBinaryDeserializer<Archive>
{
/// <inheritdoc/>
public Archive? Deserialize(Stream? data)
public override Archive? Deserialize(Stream? data)
{
// If the data is invalid
if (data == null || data.Length == 0 || !data.CanSeek || !data.CanRead)

View File

@@ -4,14 +4,13 @@ using System.Linq;
using System.Text;
using SabreTools.IO.Readers;
using SabreTools.Models.RomCenter;
using SabreTools.Serialization.Interfaces;
namespace SabreTools.Serialization.Streams
namespace SabreTools.Serialization.Deserializers
{
public partial class RomCenter : IStreamSerializer<MetadataFile>
public class RomCenter : BaseBinaryDeserializer<MetadataFile>
{
/// <inheritdoc/>
public MetadataFile? Deserialize(Stream? data)
public override MetadataFile? Deserialize(Stream? data)
{
// If the stream is null
if (data == null)

View File

@@ -1,17 +1,16 @@
using System.Collections.Generic;
using System.IO;
using System.Text;
using SabreTools.IO;
using SabreTools.IO.Extensions;
using SabreTools.Models.SGA;
using SabreTools.Serialization.Interfaces;
using static SabreTools.Models.SGA.Constants;
namespace SabreTools.Serialization.Streams
namespace SabreTools.Serialization.Deserializers
{
public partial class SGA : IStreamSerializer<Models.SGA.File>
public class SGA : BaseBinaryDeserializer<Models.SGA.File>
{
/// <inheritdoc/>
public Models.SGA.File? Deserialize(Stream? data)
public override Models.SGA.File? Deserialize(Stream? data)
{
// If the data is invalid
if (data == null || data.Length == 0 || !data.CanSeek || !data.CanRead)

View File

@@ -4,14 +4,85 @@ using System.Linq;
using System.Text;
using SabreTools.IO.Readers;
using SabreTools.Models.SeparatedValue;
using SabreTools.Serialization.Interfaces;
namespace SabreTools.Serialization.Streams
namespace SabreTools.Serialization.Deserializers
{
public partial class SeparatedValue : IStreamSerializer<MetadataFile>
// TODO: Create variants for the 3 common types: CSV, SSV, TSV
public class SeparatedValue : BaseBinaryDeserializer<MetadataFile>
{
#region Constants
public const int HeaderWithoutExtendedHashesCount = 14;
public const int HeaderWithExtendedHashesCount = 17;
#endregion
#region IByteDeserializer
/// <inheritdoc cref="IByteDeserializer.Deserialize(byte[]?, int)"/>
public static MetadataFile? DeserializeBytes(byte[]? data, int offset, char delim)
{
var deserializer = new SeparatedValue();
return deserializer.Deserialize(data, offset, delim);
}
/// <inheritdoc/>
public MetadataFile? Deserialize(Stream? data) => Deserialize(data, ',');
public override MetadataFile? Deserialize(byte[]? data, int offset)
=> Deserialize(data, offset, ',');
/// <inheritdoc/>
public MetadataFile? Deserialize(byte[]? data, int offset, char delim)
{
// If the data is invalid
if (data == null)
return null;
// If the offset is out of bounds
if (offset < 0 || offset >= data.Length)
return null;
// Create a memory stream and parse that
var dataStream = new MemoryStream(data, offset, data.Length - offset);
return DeserializeStream(dataStream, delim);
}
#endregion
#region IFileDeserializer
/// <inheritdoc cref="IFileDeserializer.Deserialize(string?)"/>
public static MetadataFile? DeserializeFile(string? path, char delim = ',')
{
var deserializer = new SeparatedValue();
return deserializer.Deserialize(path, delim);
}
/// <inheritdoc/>
public override MetadataFile? Deserialize(string? path)
=> Deserialize(path, ',');
/// <inheritdoc/>
public MetadataFile? Deserialize(string? path, char delim)
{
using var stream = PathProcessor.OpenStream(path);
return DeserializeStream(stream, delim);
}
#endregion
#region IStreamDeserializer
/// <inheritdoc cref="IStreamDeserializer.Deserialize(Stream?)"/>
public static MetadataFile? DeserializeStream(Stream? data, char delim = ',')
{
var deserializer = new SeparatedValue();
return deserializer.Deserialize(data, delim);
}
/// <inheritdoc/>
public override MetadataFile? Deserialize(Stream? data)
=> Deserialize(data, ',');
/// <inheritdoc cref="Deserialize(Stream)"/>
public MetadataFile? Deserialize(Stream? data, char delim)
@@ -45,7 +116,7 @@ namespace SabreTools.Serialization.Streams
// Parse the line into a row
Row? row = null;
if (reader.Line.Count < Serialization.SeparatedValue.HeaderWithExtendedHashesCount)
if (reader.Line.Count < HeaderWithExtendedHashesCount)
{
row = new Row
{
@@ -66,8 +137,8 @@ namespace SabreTools.Serialization.Streams
};
// If we have additional fields
if (reader.Line.Count > Serialization.SeparatedValue.HeaderWithoutExtendedHashesCount)
row.ADDITIONAL_ELEMENTS = reader.Line.Skip(Serialization.SeparatedValue.HeaderWithoutExtendedHashesCount).ToArray();
if (reader.Line.Count > HeaderWithoutExtendedHashesCount)
row.ADDITIONAL_ELEMENTS = reader.Line.Skip(HeaderWithoutExtendedHashesCount).ToArray();
}
else
{
@@ -93,8 +164,8 @@ namespace SabreTools.Serialization.Streams
};
// If we have additional fields
if (reader.Line.Count > Serialization.SeparatedValue.HeaderWithExtendedHashesCount)
row.ADDITIONAL_ELEMENTS = reader.Line.Skip(Serialization.SeparatedValue.HeaderWithExtendedHashesCount).ToArray();
if (reader.Line.Count > HeaderWithExtendedHashesCount)
row.ADDITIONAL_ELEMENTS = reader.Line.Skip(HeaderWithExtendedHashesCount).ToArray();
}
rows.Add(row);
}
@@ -103,5 +174,7 @@ namespace SabreTools.Serialization.Streams
dat.Row = rows.ToArray();
return dat;
}
#endregion
}
}

View File

@@ -0,0 +1,7 @@
namespace SabreTools.Serialization.Deserializers
{
public class SoftwareList : XmlFile<Models.SoftwareList.SoftwareList>
{
// All logic taken care of in the base class
}
}

View File

@@ -1,16 +1,15 @@
using System.IO;
using System.Text;
using SabreTools.IO;
using SabreTools.IO.Extensions;
using SabreTools.Models.VBSP;
using SabreTools.Serialization.Interfaces;
using static SabreTools.Models.VBSP.Constants;
namespace SabreTools.Serialization.Streams
namespace SabreTools.Serialization.Deserializers
{
public partial class VBSP : IStreamSerializer<Models.VBSP.File>
public class VBSP : BaseBinaryDeserializer<Models.VBSP.File>
{
/// <inheritdoc/>
public Models.VBSP.File? Deserialize(Stream? data)
public override Models.VBSP.File? Deserialize(Stream? data)
{
// If the data is invalid
if (data == null || data.Length == 0 || !data.CanSeek || !data.CanRead)

View File

@@ -1,17 +1,16 @@
using System.Collections.Generic;
using System.IO;
using System.Text;
using SabreTools.IO;
using SabreTools.IO.Extensions;
using SabreTools.Models.VPK;
using SabreTools.Serialization.Interfaces;
using static SabreTools.Models.VPK.Constants;
namespace SabreTools.Serialization.Streams
namespace SabreTools.Serialization.Deserializers
{
public partial class VPK : IStreamSerializer<Models.VPK.File>
public class VPK : BaseBinaryDeserializer<Models.VPK.File>
{
/// <inheritdoc/>
public Models.VPK.File? Deserialize(Stream? data)
public override Models.VPK.File? Deserialize(Stream? data)
{
// If the data is invalid
if (data == null || data.Length == 0 || !data.CanSeek || !data.CanRead)

View File

@@ -1,16 +1,15 @@
using System.IO;
using System.Text;
using SabreTools.IO;
using SabreTools.IO.Extensions;
using SabreTools.Models.WAD;
using SabreTools.Serialization.Interfaces;
using static SabreTools.Models.WAD.Constants;
namespace SabreTools.Serialization.Streams
namespace SabreTools.Serialization.Deserializers
{
public partial class WAD : IStreamSerializer<Models.WAD.File>
public class WAD : BaseBinaryDeserializer<Models.WAD.File>
{
/// <inheritdoc/>
public Models.WAD.File? Deserialize(Stream? data)
public override Models.WAD.File? Deserialize(Stream? data)
{
// If the data is invalid
if (data == null || data.Length == 0 || !data.CanSeek || !data.CanRead)

View File

@@ -1,9 +1,19 @@
using SabreTools.Serialization.Interfaces;
namespace SabreTools.Serialization.Strings
namespace SabreTools.Serialization.Deserializers
{
public partial class XMID : IStringSerializer<Models.Xbox.XMID>
public partial class XMID :
IStringDeserializer<Models.Xbox.XMID>
{
#region IStringDeserializer
/// <inheritdoc cref="IStringDeserializer.Deserialize(string?)"/>
public static Models.Xbox.XMID? DeserializeString(string? str)
{
var deserializer = new XMID();
return deserializer.Deserialize(str);
}
/// <inheritdoc/>
public Models.Xbox.XMID? Deserialize(string? str)
{
@@ -36,5 +46,7 @@ namespace SabreTools.Serialization.Strings
return xmid;
}
#endregion
}
}

View File

@@ -1,16 +1,15 @@
using System.IO;
using System.Text;
using SabreTools.IO;
using SabreTools.IO.Extensions;
using SabreTools.Models.XZP;
using SabreTools.Serialization.Interfaces;
using static SabreTools.Models.XZP.Constants;
namespace SabreTools.Serialization.Streams
namespace SabreTools.Serialization.Deserializers
{
public partial class XZP : IStreamSerializer<Models.XZP.File>
public class XZP : BaseBinaryDeserializer<Models.XZP.File>
{
/// <inheritdoc/>
public Models.XZP.File? Deserialize(Stream? data)
public override Models.XZP.File? Deserialize(Stream? data)
{
// If the data is invalid
if (data == null || data.Length == 0 || !data.CanSeek || !data.CanRead)

View File

@@ -1,9 +1,19 @@
using SabreTools.Serialization.Interfaces;
namespace SabreTools.Serialization.Strings
namespace SabreTools.Serialization.Deserializers
{
public partial class XeMID : IStringSerializer<Models.Xbox.XeMID>
public partial class XeMID :
IStringDeserializer<Models.Xbox.XeMID>
{
#region IStringDeserializer
/// <inheritdoc cref="IStringDeserializer.Deserialize(string?)"/>
public static Models.Xbox.XeMID? DeserializeString(string? str)
{
var deserializer = new XeMID();
return deserializer.Deserialize(str);
}
/// <inheritdoc/>
public Models.Xbox.XeMID? Deserialize(string? str)
{
@@ -60,5 +70,7 @@ namespace SabreTools.Serialization.Strings
return xemid;
}
#endregion
}
}

View File

@@ -2,18 +2,17 @@ using System.IO;
using System.Xml;
using System.Xml.Schema;
using System.Xml.Serialization;
using SabreTools.Serialization.Interfaces;
namespace SabreTools.Serialization.Streams
namespace SabreTools.Serialization.Deserializers
{
/// <summary>
/// Base class for other XML serializers
/// Base class for other XML deserializers
/// </summary>
/// <typeparam name="T"></typeparam>
public partial class XmlFile<T> : IStreamSerializer<T>
public class XmlFile<T> : BaseBinaryDeserializer<T>
{
/// <inheritdoc/>
public T? Deserialize(Stream? data)
public override T? Deserialize(Stream? data)
{
// If the stream is null
if (data == null)

View File

@@ -1,13 +0,0 @@
namespace SabreTools.Serialization
{
public enum Hash
{
CRC,
MD5,
SHA1,
SHA256,
SHA384,
SHA512,
SpamSum,
}
}

View File

@@ -4,7 +4,7 @@ using System.IO;
using System.Linq;
using System.Text;
using System.Xml.Serialization;
using SabreTools.IO;
using SabreTools.IO.Extensions;
using SabreTools.Models.PortableExecutable;
namespace SabreTools.Serialization
@@ -92,6 +92,65 @@ namespace SabreTools.Serialization
return -1;
}
#region Debug
/// <summary>
/// Read debug data as an NB10 Program Database
/// </summary>
/// <param name="data">Data to parse into a database</param>
/// <param name="offset">Offset into the byte array</param>
/// <returns>A filled NB10 Program Database on success, null on error</returns>
public static NB10ProgramDatabase? AsNB10ProgramDatabase(this byte[] data, ref int offset)
{
// If we have data that's invalid, we can't do anything
if (data == null)
return null;
var nb10ProgramDatabase = new NB10ProgramDatabase();
nb10ProgramDatabase.Signature = data.ReadUInt32(ref offset);
if (nb10ProgramDatabase.Signature != 0x3031424E)
return null;
nb10ProgramDatabase.Offset = data.ReadUInt32(ref offset);
nb10ProgramDatabase.Timestamp = data.ReadUInt32(ref offset);
nb10ProgramDatabase.Age = data.ReadUInt32(ref offset);
nb10ProgramDatabase.PdbFileName = data.ReadString(ref offset, Encoding.ASCII); // TODO: Actually null-terminated UTF-8?
return nb10ProgramDatabase;
}
/// <summary>
/// Read debug data as an RSDS Program Database
/// </summary>
/// <param name="data">Data to parse into a database</param>
/// <param name="offset">Offset into the byte array</param>
/// <returns>A filled RSDS Program Database on success, null on error</returns>
public static RSDSProgramDatabase? AsRSDSProgramDatabase(this byte[]? data, ref int offset)
{
// If we have data that's invalid, we can't do anything
if (data == null)
return null;
var rsdsProgramDatabase = new RSDSProgramDatabase();
rsdsProgramDatabase.Signature = data.ReadUInt32(ref offset);
if (rsdsProgramDatabase.Signature != 0x53445352)
return null;
var guid = data.ReadBytes(ref offset, 0x10);
if (guid != null)
rsdsProgramDatabase.GUID = new Guid(guid);
rsdsProgramDatabase.Age = data.ReadUInt32(ref offset);
rsdsProgramDatabase.PathAndFileName = data.ReadString(ref offset, Encoding.ASCII); // TODO: Actually null-terminated UTF-8
return rsdsProgramDatabase;
}
#endregion
#region Overlay
/// <summary>
/// Read overlay data as a SecuROM AddD overlay data
/// </summary>
@@ -153,61 +212,6 @@ namespace SabreTools.Serialization
return addD;
}
#region Debug
/// <summary>
/// Read debug data as an NB10 Program Database
/// </summary>
/// <param name="data">Data to parse into a database</param>
/// <param name="offset">Offset into the byte array</param>
/// <returns>A filled NB10 Program Database on success, null on error</returns>
public static NB10ProgramDatabase? AsNB10ProgramDatabase(this byte[] data, ref int offset)
{
// If we have data that's invalid, we can't do anything
if (data == null)
return null;
var nb10ProgramDatabase = new NB10ProgramDatabase();
nb10ProgramDatabase.Signature = data.ReadUInt32(ref offset);
if (nb10ProgramDatabase.Signature != 0x3031424E)
return null;
nb10ProgramDatabase.Offset = data.ReadUInt32(ref offset);
nb10ProgramDatabase.Timestamp = data.ReadUInt32(ref offset);
nb10ProgramDatabase.Age = data.ReadUInt32(ref offset);
nb10ProgramDatabase.PdbFileName = data.ReadString(ref offset, Encoding.ASCII); // TODO: Actually null-terminated UTF-8?
return nb10ProgramDatabase;
}
/// <summary>
/// Read debug data as an RSDS Program Database
/// </summary>
/// <param name="data">Data to parse into a database</param>
/// <param name="offset">Offset into the byte array</param>
/// <returns>A filled RSDS Program Database on success, null on error</returns>
public static RSDSProgramDatabase? AsRSDSProgramDatabase(this byte[]? data, ref int offset)
{
// If we have data that's invalid, we can't do anything
if (data == null)
return null;
var rsdsProgramDatabase = new RSDSProgramDatabase();
rsdsProgramDatabase.Signature = data.ReadUInt32(ref offset);
if (rsdsProgramDatabase.Signature != 0x53445352)
return null;
var guid = data.ReadBytes(ref offset, 0x10);
if (guid != null)
rsdsProgramDatabase.GUID = new Guid(guid);
rsdsProgramDatabase.Age = data.ReadUInt32(ref offset);
rsdsProgramDatabase.PathAndFileName = data.ReadString(ref offset, Encoding.ASCII); // TODO: Actually null-terminated UTF-8
return rsdsProgramDatabase;
}
#endregion
// TODO: Implement other resource types from https://learn.microsoft.com/en-us/windows/win32/menurc/resource-file-formats

View File

@@ -1,14 +0,0 @@
using SabreTools.Serialization.Interfaces;
namespace SabreTools.Serialization.Files
{
public partial class AACS : IFileSerializer<Models.AACS.MediaKeyBlock>
{
/// <inheritdoc/>
public Models.AACS.MediaKeyBlock? Deserialize(string? path)
{
using var stream = PathProcessor.OpenStream(path);
return new Streams.AACS().Deserialize(stream);
}
}
}

View File

@@ -1,22 +0,0 @@
using SabreTools.Serialization.Interfaces;
namespace SabreTools.Serialization.Files
{
public partial class AACS : IFileSerializer<Models.AACS.MediaKeyBlock>
{
/// <inheritdoc/>
public bool Serialize(Models.AACS.MediaKeyBlock? obj, string? path)
{
if (string.IsNullOrEmpty(path))
return false;
using var stream = new Streams.AACS().Serialize(obj);
if (stream == null)
return false;
using var fs = System.IO.File.OpenWrite(path);
stream.CopyTo(fs);
return true;
}
}
}

View File

@@ -1,7 +0,0 @@
namespace SabreTools.Serialization.Files
{
public partial class ArchiveDotOrg : XmlFile<Models.ArchiveDotOrg.Files>
{
// All serialization logic is in the base class
}
}

View File

@@ -1,7 +0,0 @@
namespace SabreTools.Serialization.Files
{
public partial class ArchiveDotOrg : XmlFile<Models.ArchiveDotOrg.Files>
{
// All serialization logic is in the base class
}
}

View File

@@ -1,15 +0,0 @@
using SabreTools.Models.AttractMode;
using SabreTools.Serialization.Interfaces;
namespace SabreTools.Serialization.Files
{
public partial class AttractMode : IFileSerializer<MetadataFile>
{
/// <inheritdoc/>
public MetadataFile? Deserialize(string? path)
{
using var stream = PathProcessor.OpenStream(path);
return new Streams.AttractMode().Deserialize(stream);
}
}
}

View File

@@ -1,24 +0,0 @@
using System.IO;
using SabreTools.Models.AttractMode;
using SabreTools.Serialization.Interfaces;
namespace SabreTools.Serialization.Files
{
public partial class AttractMode : IFileSerializer<MetadataFile>
{
/// <inheritdoc/>
public bool Serialize(MetadataFile? obj, string? path)
{
if (string.IsNullOrEmpty(path))
return false;
using var stream = new Streams.AttractMode().Serialize(obj);
if (stream == null)
return false;
using var fs = File.OpenWrite(path);
stream.CopyTo(fs);
return true;
}
}
}

View File

@@ -1,14 +0,0 @@
using SabreTools.Serialization.Interfaces;
namespace SabreTools.Serialization.Files
{
public partial class BDPlus : IFileSerializer<Models.BDPlus.SVM>
{
/// <inheritdoc/>
public Models.BDPlus.SVM? Deserialize(string? path)
{
using var stream = PathProcessor.OpenStream(path);
return new Streams.BDPlus().Deserialize(stream);
}
}
}

View File

@@ -1,22 +0,0 @@
using SabreTools.Serialization.Interfaces;
namespace SabreTools.Serialization.Files
{
public partial class BDPlus : IFileSerializer<Models.BDPlus.SVM>
{
/// <inheritdoc/>
public bool Serialize(Models.BDPlus.SVM? obj, string? path)
{
if (string.IsNullOrEmpty(path))
return false;
using var stream = new Streams.BDPlus().Serialize(obj);
if (stream == null)
return false;
using var fs = System.IO.File.OpenWrite(path);
stream.CopyTo(fs);
return true;
}
}
}

View File

@@ -1,14 +0,0 @@
using SabreTools.Serialization.Interfaces;
namespace SabreTools.Serialization.Files
{
public partial class BFPK : IFileSerializer<Models.BFPK.Archive>
{
/// <inheritdoc/>
public Models.BFPK.Archive? Deserialize(string? path)
{
using var stream = PathProcessor.OpenStream(path);
return new Streams.BFPK().Deserialize(stream);
}
}
}

View File

@@ -1,22 +0,0 @@
using SabreTools.Serialization.Interfaces;
namespace SabreTools.Serialization.Files
{
public partial class BFPK : IFileSerializer<Models.BFPK.Archive>
{
/// <inheritdoc/>
public bool Serialize(Models.BFPK.Archive? obj, string? path)
{
if (string.IsNullOrEmpty(path))
return false;
using var stream = new Streams.BFPK().Serialize(obj);
if (stream == null)
return false;
using var fs = System.IO.File.OpenWrite(path);
stream.CopyTo(fs);
return true;
}
}
}

View File

@@ -1,14 +0,0 @@
using SabreTools.Serialization.Interfaces;
namespace SabreTools.Serialization.Files
{
public partial class BSP : IFileSerializer<Models.BSP.File>
{
/// <inheritdoc/>
public Models.BSP.File? Deserialize(string? path)
{
using var stream = PathProcessor.OpenStream(path);
return new Streams.BSP().Deserialize(stream);
}
}
}

View File

@@ -1,22 +0,0 @@
using SabreTools.Serialization.Interfaces;
namespace SabreTools.Serialization.Files
{
public partial class BSP : IFileSerializer<Models.BSP.File>
{
/// <inheritdoc/>
public bool Serialize(Models.BSP.File? obj, string? path)
{
if (string.IsNullOrEmpty(path))
return false;
using var stream = new Streams.BSP().Serialize(obj);
if (stream == null)
return false;
using var fs = System.IO.File.OpenWrite(path);
stream.CopyTo(fs);
return true;
}
}
}

View File

@@ -1,14 +0,0 @@
using SabreTools.Serialization.Interfaces;
namespace SabreTools.Serialization.Files
{
public partial class CFB : IFileSerializer<Models.CFB.Binary>
{
/// <inheritdoc/>
public Models.CFB.Binary? Deserialize(string? path)
{
using var stream = PathProcessor.OpenStream(path);
return new Streams.CFB().Deserialize(stream);
}
}
}

View File

@@ -1,22 +0,0 @@
using SabreTools.Serialization.Interfaces;
namespace SabreTools.Serialization.Files
{
public partial class CFB : IFileSerializer<Models.CFB.Binary>
{
/// <inheritdoc/>
public bool Serialize(Models.CFB.Binary? obj, string? path)
{
if (string.IsNullOrEmpty(path))
return false;
using var stream = new Streams.CFB().Serialize(obj);
if (stream == null)
return false;
using var fs = System.IO.File.OpenWrite(path);
stream.CopyTo(fs);
return true;
}
}
}

View File

@@ -1,14 +0,0 @@
using SabreTools.Serialization.Interfaces;
namespace SabreTools.Serialization.Files
{
public partial class CIA : IFileSerializer<Models.N3DS.CIA>
{
/// <inheritdoc/>
public Models.N3DS.CIA? Deserialize(string? path)
{
using var stream = PathProcessor.OpenStream(path);
return new Streams.CIA().Deserialize(stream);
}
}
}

View File

@@ -1,22 +0,0 @@
using SabreTools.Serialization.Interfaces;
namespace SabreTools.Serialization.Files
{
public partial class CIA : IFileSerializer<Models.N3DS.CIA>
{
/// <inheritdoc/>
public bool Serialize(Models.N3DS.CIA? obj, string? path)
{
if (string.IsNullOrEmpty(path))
return false;
using var stream = new Streams.CIA().Serialize(obj);
if (stream == null)
return false;
using var fs = System.IO.File.OpenWrite(path);
stream.CopyTo(fs);
return true;
}
}
}

Some files were not shown because too many files have changed in this diff Show More