Compare commits

...

22 Commits
1.1.6 ... 1.3.0

Author SHA1 Message Date
Matt Nadareski
aaa6422921 Bump version 2023-11-21 21:11:24 -05:00
Matt Nadareski
f24b88031b Address some suggestions 2023-11-21 21:10:43 -05:00
Matt Nadareski
edf9fed751 Support .NET Framework 2.0 2023-11-21 20:59:20 -05:00
Matt Nadareski
beca747943 Fix other data endpoint issues 2023-11-15 12:44:32 -05:00
Matt Nadareski
58e538eff6 Bump version 2023-11-15 12:41:21 -05:00
Matt Nadareski
4f04c8aa89 Fix end-of-data issue, add .NET 8 syntax 2023-11-15 12:34:57 -05:00
Matt Nadareski
d7c1e4e83a Support ancient .NET 2023-11-14 14:50:47 -05:00
Matt Nadareski
975eefdc61 Expand supported RIDs 2023-11-08 22:51:40 -05:00
Matt Nadareski
d8cd5854ce Enable latest language version 2023-11-07 23:30:26 -05:00
Matt Nadareski
0790fc93b6 Bump version 2023-10-25 15:34:38 -04:00
Matt Nadareski
7f6c128521 Update README 2023-10-25 15:04:22 -04:00
Matt Nadareski
87df6b3ebd Add IRD wrapper 2023-10-25 14:51:07 -04:00
Matt Nadareski
2ca7326074 Implement IRD serializers 2023-10-25 14:43:43 -04:00
Matt Nadareski
3b90af7b3a Split XgdInfo into two proper wrappers 2023-10-25 13:29:59 -04:00
Matt Nadareski
6eda2f2541 Update models, add XgdInfo extensions 2023-10-25 13:17:36 -04:00
Matt Nadareski
defe1c53aa Port a version of XgdInfo from MPF 2023-10-24 23:33:53 -04:00
Matt Nadareski
e5fe0a71ef Add Xbox string serialization 2023-10-24 23:24:17 -04:00
Matt Nadareski
83450f693f Make Strings namespace and move Xbox 2023-10-24 23:20:27 -04:00
Matt Nadareski
1f70e1f544 Remove unnecessary validation / methods from Xbox 2023-10-24 23:05:16 -04:00
Matt Nadareski
4bfc83d5d4 Make XMID consistent with XeMID 2023-10-24 21:50:26 -04:00
Matt Nadareski
7364661900 Add two X360 publishers 2023-10-24 21:43:21 -04:00
Matt Nadareski
1cafc4079d Make XeMID logic a bit clearer 2023-10-24 16:56:41 -04:00
216 changed files with 1369 additions and 4069 deletions

View File

@@ -7,11 +7,7 @@ namespace SabreTools.Serialization.Bytes
public partial class AACS : IByteSerializer<MediaKeyBlock>
{
/// <inheritdoc/>
#if NET48
public MediaKeyBlock Deserialize(byte[] data, int offset)
#else
public MediaKeyBlock? Deserialize(byte[]? data, int offset)
#endif
{
// If the data is invalid
if (data == null)

View File

@@ -7,11 +7,7 @@ namespace SabreTools.Serialization.Bytes
public partial class BDPlus : IByteSerializer<SVM>
{
/// <inheritdoc/>
#if NET48
public SVM Deserialize(byte[] data, int offset)
#else
public SVM? Deserialize(byte[]? data, int offset)
#endif
{
// If the data is invalid
if (data == null)

View File

@@ -7,11 +7,7 @@ namespace SabreTools.Serialization.Bytes
public partial class BFPK : IByteSerializer<Archive>
{
/// <inheritdoc/>
#if NET48
public Archive Deserialize(byte[] data, int offset)
#else
public Archive? Deserialize(byte[]? data, int offset)
#endif
{
// If the data is invalid
if (data == null)

View File

@@ -6,11 +6,7 @@ namespace SabreTools.Serialization.Bytes
public partial class BSP : IByteSerializer<Models.BSP.File>
{
/// <inheritdoc/>
#if NET48
public Models.BSP.File Deserialize(byte[] data, int offset)
#else
public Models.BSP.File? Deserialize(byte[]? data, int offset)
#endif
{
// If the data is invalid
if (data == null)

View File

@@ -7,11 +7,7 @@ namespace SabreTools.Serialization.Bytes
public partial class CFB : IByteSerializer<Binary>
{
/// <inheritdoc/>
#if NET48
public Binary Deserialize(byte[] data, int offset)
#else
public Binary? Deserialize(byte[]? data, int offset)
#endif
{
// If the data is invalid
if (data == null)

View File

@@ -6,11 +6,7 @@ namespace SabreTools.Serialization.Bytes
public partial class CIA : IByteSerializer<Models.N3DS.CIA>
{
/// <inheritdoc/>
#if NET48
public Models.N3DS.CIA Deserialize(byte[] data, int offset)
#else
public Models.N3DS.CIA? Deserialize(byte[]? data, int offset)
#endif
{
// If the data is invalid
if (data == null)

View File

@@ -6,11 +6,7 @@ namespace SabreTools.Serialization.Bytes
public partial class GCF : IByteSerializer<Models.GCF.File>
{
/// <inheritdoc/>
#if NET48
public Models.GCF.File Deserialize(byte[] data, int offset)
#else
public Models.GCF.File? Deserialize(byte[]? data, int offset)
#endif
{
// If the data is invalid
if (data == null)

24
Bytes/IRD.Deserializer.cs Normal file
View File

@@ -0,0 +1,24 @@
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

@@ -8,11 +8,7 @@ namespace SabreTools.Serialization.Bytes
public partial class InstallShieldCabinet : IByteSerializer<Cabinet>
{
/// <inheritdoc/>
#if NET48
public Cabinet Deserialize(byte[] data, int offset)
#else
public Cabinet? Deserialize(byte[]? data, int offset)
#endif
{
// If the data is invalid
if (data == null)

View File

@@ -7,11 +7,7 @@ namespace SabreTools.Serialization.Bytes
public partial class LinearExecutable : IByteSerializer<Executable>
{
/// <inheritdoc/>
#if NET48
public Executable Deserialize(byte[] data, int offset)
#else
public Executable? Deserialize(byte[]? data, int offset)
#endif
{
// If the data is invalid
if (data == null)

View File

@@ -7,11 +7,7 @@ namespace SabreTools.Serialization.Bytes
public partial class MSDOS : IByteSerializer<Executable>
{
/// <inheritdoc/>
#if NET48
public Executable Deserialize(byte[] data, int offset)
#else
public Executable? Deserialize(byte[]? data, int offset)
#endif
{
// If the data is invalid
if (data == null)

View File

@@ -8,11 +8,7 @@ namespace SabreTools.Serialization.Bytes
public partial class MicrosoftCabinet : IByteSerializer<Cabinet>
{
/// <inheritdoc/>
#if NET48
public Cabinet Deserialize(byte[] data, int offset)
#else
public Cabinet? Deserialize(byte[]? data, int offset)
#endif
{
// If the data is invalid
if (data == null)

View File

@@ -7,11 +7,7 @@ namespace SabreTools.Serialization.Bytes
public partial class MoPaQ : IByteSerializer<Archive>
{
/// <inheritdoc/>
#if NET48
public Archive Deserialize(byte[] data, int offset)
#else
public Archive? Deserialize(byte[]? data, int offset)
#endif
{
// If the data is invalid
if (data == null)

View File

@@ -7,11 +7,7 @@ namespace SabreTools.Serialization.Bytes
public partial class N3DS : IByteSerializer<Cart>
{
/// <inheritdoc/>
#if NET48
public Cart Deserialize(byte[] data, int offset)
#else
public Cart? Deserialize(byte[]? data, int offset)
#endif
{
// If the data is invalid
if (data == null)

View File

@@ -6,11 +6,7 @@ namespace SabreTools.Serialization.Bytes
public partial class NCF : IByteSerializer<Models.NCF.File>
{
/// <inheritdoc/>
#if NET48
public Models.NCF.File Deserialize(byte[] data, int offset)
#else
public Models.NCF.File? Deserialize(byte[]? data, int offset)
#endif
{
// If the data is invalid
if (data == null)

View File

@@ -7,11 +7,7 @@ namespace SabreTools.Serialization.Bytes
public partial class NewExecutable : IByteSerializer<Executable>
{
/// <inheritdoc/>
#if NET48
public Executable Deserialize(byte[] data, int offset)
#else
public Executable? Deserialize(byte[]? data, int offset)
#endif
{
// If the data is invalid
if (data == null)

View File

@@ -7,11 +7,7 @@ namespace SabreTools.Serialization.Bytes
public partial class Nitro : IByteSerializer<Cart>
{
/// <inheritdoc/>
#if NET48
public Cart Deserialize(byte[] data, int offset)
#else
public Cart? Deserialize(byte[]? data, int offset)
#endif
{
// If the data is invalid
if (data == null)

View File

@@ -6,11 +6,7 @@ namespace SabreTools.Serialization.Bytes
public partial class PAK : IByteSerializer<Models.PAK.File>
{
/// <inheritdoc/>
#if NET48
public Models.PAK.File Deserialize(byte[] data, int offset)
#else
public Models.PAK.File? Deserialize(byte[]? data, int offset)
#endif
{
// If the data is invalid
if (data == null)

View File

@@ -7,11 +7,7 @@ namespace SabreTools.Serialization.Bytes
public partial class PFF : IByteSerializer<Archive>
{
/// <inheritdoc/>
#if NET48
public Archive Deserialize(byte[] data, int offset)
#else
public Archive? Deserialize(byte[]? data, int offset)
#endif
{
// If the data is invalid
if (data == null)

View File

@@ -7,11 +7,7 @@ namespace SabreTools.Serialization.Bytes
public partial class PlayJAudio : IByteSerializer<AudioFile>
{
/// <inheritdoc/>
#if NET48
public AudioFile Deserialize(byte[] data, int offset)
#else
public AudioFile? Deserialize(byte[]? data, int offset)
#endif
{
// If the data is invalid
if (data == null)

View File

@@ -7,11 +7,7 @@ namespace SabreTools.Serialization.Bytes
public partial class PlayJPlaylist : IByteSerializer<Playlist>
{
/// <inheritdoc/>
#if NET48
public Playlist Deserialize(byte[] data, int offset)
#else
public Playlist? Deserialize(byte[]? data, int offset)
#endif
{
// If the data is invalid
if (data == null)

View File

@@ -7,11 +7,7 @@ namespace SabreTools.Serialization.Bytes
public partial class PortableExecutable : IByteSerializer<Executable>
{
/// <inheritdoc/>
#if NET48
public Executable Deserialize(byte[] data, int offset)
#else
public Executable? Deserialize(byte[]? data, int offset)
#endif
{
// If the data is invalid
if (data == null)

View File

@@ -7,11 +7,7 @@ namespace SabreTools.Serialization.Bytes
public partial class Quantum : IByteSerializer<Archive>
{
/// <inheritdoc/>
#if NET48
public Archive Deserialize(byte[] data, int offset)
#else
public Archive? Deserialize(byte[]? data, int offset)
#endif
{
// If the data is invalid
if (data == null)

View File

@@ -6,11 +6,7 @@ namespace SabreTools.Serialization.Bytes
public partial class SGA : IByteSerializer<Models.SGA.File>
{
/// <inheritdoc/>
#if NET48
public Models.SGA.File Deserialize(byte[] data, int offset)
#else
public Models.SGA.File? Deserialize(byte[]? data, int offset)
#endif
{
// If the data is invalid
if (data == null)

View File

@@ -6,11 +6,7 @@ namespace SabreTools.Serialization.Bytes
public partial class VBSP : IByteSerializer<Models.VBSP.File>
{
/// <inheritdoc/>
#if NET48
public Models.VBSP.File Deserialize(byte[] data, int offset)
#else
public Models.VBSP.File? Deserialize(byte[]? data, int offset)
#endif
{
// If the data is invalid
if (data == null)

View File

@@ -6,11 +6,7 @@ namespace SabreTools.Serialization.Bytes
public partial class VPK : IByteSerializer<Models.VPK.File>
{
/// <inheritdoc/>
#if NET48
public Models.VPK.File Deserialize(byte[] data, int offset)
#else
public Models.VPK.File? Deserialize(byte[]? data, int offset)
#endif
{
// If the data is invalid
if (data == null)

View File

@@ -6,11 +6,7 @@ namespace SabreTools.Serialization.Bytes
public partial class WAD : IByteSerializer<Models.WAD.File>
{
/// <inheritdoc/>
#if NET48
public Models.WAD.File Deserialize(byte[] data, int offset)
#else
public Models.WAD.File? Deserialize(byte[]? data, int offset)
#endif
{
// If the data is invalid
if (data == null)

View File

@@ -6,11 +6,7 @@ namespace SabreTools.Serialization.Bytes
public partial class XZP : IByteSerializer<Models.XZP.File>
{
/// <inheritdoc/>
#if NET48
public Models.XZP.File Deserialize(byte[] data, int offset)
#else
public Models.XZP.File? Deserialize(byte[]? data, int offset)
#endif
{
// If the data is invalid
if (data == null)

View File

@@ -8,11 +8,7 @@ namespace SabreTools.Serialization.CrossModel
public partial class ArchiveDotOrg : IModelSerializer<Models.ArchiveDotOrg.Files, Models.Metadata.MetadataFile>
{
/// <inheritdoc/>
#if NET48
public Models.ArchiveDotOrg.Files Deserialize(Models.Metadata.MetadataFile obj)
#else
public Models.ArchiveDotOrg.Files? Deserialize(Models.Metadata.MetadataFile? obj)
#endif
{
if (obj == null)
return null;
@@ -38,7 +34,7 @@ namespace SabreTools.Serialization.CrossModel
{
var roms = item.Read<Models.Metadata.Rom[]>(Models.Metadata.Machine.RomKey);
if (roms == null)
return Array.Empty<File>();
return [];
return roms
.Where(r => r != null)

View File

@@ -6,11 +6,7 @@ namespace SabreTools.Serialization.CrossModel
public partial class ArchiveDotOrg : IModelSerializer<Models.ArchiveDotOrg.Files, Models.Metadata.MetadataFile>
{
/// <inheritdoc/>
#if NET48
public Models.Metadata.MetadataFile Serialize(Models.ArchiveDotOrg.Files item)
#else
public Models.Metadata.MetadataFile? Serialize(Models.ArchiveDotOrg.Files? item)
#endif
{
if (item == null)
return null;
@@ -47,11 +43,7 @@ namespace SabreTools.Serialization.CrossModel
/// <summary>
/// Convert from <cref="Models.ArchiveDotOrg.File"/> to <cref="Models.Metadata.Machine"/>
/// </summary>
#if NET48
private static Models.Metadata.Machine ConvertMachineToInternalModel(Models.ArchiveDotOrg.File item)
#else
private static Models.Metadata.Machine ConvertMachineToInternalModel(Models.ArchiveDotOrg.File? item)
#endif
{
var machine = new Models.Metadata.Machine
{
@@ -63,11 +55,7 @@ namespace SabreTools.Serialization.CrossModel
/// <summary>
/// Convert from <cref="Models.ArchiveDotOrg.File"/> to <cref="Models.Metadata.Rom"/>
/// </summary>
#if NET48
private static Models.Metadata.Rom ConvertToInternalModel(Models.ArchiveDotOrg.File item)
#else
private static Models.Metadata.Rom? ConvertToInternalModel(Models.ArchiveDotOrg.File? item)
#endif
{
if (item == null)
return null;

View File

@@ -8,11 +8,7 @@ namespace SabreTools.Serialization.CrossModel
public partial class AttractMode : IModelSerializer<MetadataFile, Models.Metadata.MetadataFile>
{
/// <inheritdoc/>
#if NET48
public MetadataFile Deserialize(Models.Metadata.MetadataFile obj)
#else
public MetadataFile? Deserialize(Models.Metadata.MetadataFile? obj)
#endif
{
if (obj == null)
return null;
@@ -51,7 +47,7 @@ namespace SabreTools.Serialization.CrossModel
{
var roms = item.Read<Models.Metadata.Rom[]>(Models.Metadata.Machine.RomKey);
if (roms == null || !roms.Any())
return Array.Empty<Row>();
return [];
return roms
.Where(r => r != null)

View File

@@ -7,11 +7,7 @@ namespace SabreTools.Serialization.CrossModel
public partial class AttractMode : IModelSerializer<MetadataFile, Models.Metadata.MetadataFile>
{
/// <inheritdoc/>
#if NET48
public Models.Metadata.MetadataFile Serialize(MetadataFile obj)
#else
public Models.Metadata.MetadataFile? Serialize(MetadataFile? obj)
#endif
{
if (obj == null)
return null;
@@ -48,11 +44,7 @@ namespace SabreTools.Serialization.CrossModel
/// <summary>
/// Convert from <cref="Models.AttractMode.Row"/> to <cref="Models.Metadata.Machine"/>
/// </summary>
#if NET48
private static Models.Metadata.Machine ConvertMachineToInternalModel(Row item)
#else
private static Models.Metadata.Machine? ConvertMachineToInternalModel(Row? item)
#endif
{
if (item == null)
return null;

View File

@@ -7,18 +7,10 @@ namespace SabreTools.Serialization.CrossModel
public partial class ClrMamePro : IModelSerializer<MetadataFile, Models.Metadata.MetadataFile>
{
/// <inheritdoc/>
#if NET48
public MetadataFile Deserialize(Models.Metadata.MetadataFile obj) => Deserialize(obj, false);
#else
public MetadataFile? Deserialize(Models.Metadata.MetadataFile? obj) => Deserialize(obj, false);
#endif
/// <inheritdoc cref="Deserialize(Models.Metadata.MetadataFile)"/>
#if NET48
public MetadataFile Deserialize(Models.Metadata.MetadataFile obj, bool game)
#else
public MetadataFile? Deserialize(Models.Metadata.MetadataFile? obj, bool game)
#endif
{
if (obj == null)
return null;
@@ -72,15 +64,7 @@ namespace SabreTools.Serialization.CrossModel
/// </summary>
private static GameBase ConvertMachineFromInternalModel(Models.Metadata.Machine item, bool game = false)
{
#if NET48
GameBase gameBase;
if (game)
gameBase = new Game();
else
gameBase = new Machine();
#else
GameBase gameBase = game ? new Models.ClrMamePro.Game() : new Models.ClrMamePro.Machine();
#endif
gameBase.Name = item.ReadString(Models.Metadata.Machine.NameKey);
gameBase.Description = item.ReadString(Models.Metadata.Machine.DescriptionKey);

View File

@@ -7,11 +7,7 @@ namespace SabreTools.Serialization.CrossModel
public partial class ClrMamePro : IModelSerializer<MetadataFile, Models.Metadata.MetadataFile>
{
/// <inheritdoc/>
#if NET48
public Models.Metadata.MetadataFile Serialize(MetadataFile obj)
#else
public Models.Metadata.MetadataFile? Serialize(MetadataFile? obj)
#endif
{
if (obj == null)
return null;
@@ -62,11 +58,7 @@ namespace SabreTools.Serialization.CrossModel
/// <summary>
/// Convert from <cref="Models.ClrMamePro.GameBase"/> to <cref="Models.Metadata.Machine"/>
/// </summary>
#if NET48
private static Models.Metadata.Machine ConvertMachineToInternalModel(GameBase item)
#else
private static Models.Metadata.Machine? ConvertMachineToInternalModel(GameBase? item)
#endif
{
if (item == null)
return null;

View File

@@ -7,11 +7,7 @@ namespace SabreTools.Serialization.CrossModel
public partial class DosCenter : IModelSerializer<MetadataFile, Models.Metadata.MetadataFile>
{
/// <inheritdoc/>
#if NET48
public MetadataFile Deserialize(Models.Metadata.MetadataFile obj)
#else
public MetadataFile? Deserialize(Models.Metadata.MetadataFile? obj)
#endif
{
if (obj == null)
return null;

View File

@@ -7,11 +7,7 @@ namespace SabreTools.Serialization.CrossModel
public partial class DosCenter : IModelSerializer<MetadataFile, Models.Metadata.MetadataFile>
{
/// <inheritdoc/>
#if NET48
public Models.Metadata.MetadataFile Serialize(MetadataFile obj)
#else
public Models.Metadata.MetadataFile? Serialize(MetadataFile? obj)
#endif
{
if (obj == null)
return null;

View File

@@ -8,11 +8,7 @@ namespace SabreTools.Serialization.CrossModel
public partial class EverdriveSMDB : IModelSerializer<MetadataFile, Models.Metadata.MetadataFile>
{
/// <inheritdoc/>
#if NET48
public MetadataFile Deserialize(Models.Metadata.MetadataFile obj)
#else
public MetadataFile? Deserialize(Models.Metadata.MetadataFile? obj)
#endif
{
if (obj == null)
return null;
@@ -38,7 +34,7 @@ namespace SabreTools.Serialization.CrossModel
{
var roms = item.Read<Models.Metadata.Rom[]>(Models.Metadata.Machine.RomKey);
if (roms == null || !roms.Any())
return Array.Empty<Row>();
return [];
return roms
.Where(r => r != null)

View File

@@ -7,11 +7,7 @@ namespace SabreTools.Serialization.CrossModel
public partial class EverdriveSMDB : IModelSerializer<MetadataFile, Models.Metadata.MetadataFile>
{
/// <inheritdoc/>
#if NET48
public Models.Metadata.MetadataFile Serialize(MetadataFile obj)
#else
public Models.Metadata.MetadataFile? Serialize(MetadataFile? obj)
#endif
{
if (obj == null)
return null;

View File

@@ -8,18 +8,10 @@ namespace SabreTools.Serialization.CrossModel
public partial class Hashfile : IModelSerializer<Models.Hashfile.Hashfile, Models.Metadata.MetadataFile>
{
/// <inheritdoc/>
#if NET48
public Models.Hashfile.Hashfile Deserialize(Models.Metadata.MetadataFile obj) => Deserialize(obj, Hash.CRC);
#else
public Models.Hashfile.Hashfile? Deserialize(Models.Metadata.MetadataFile? obj) => Deserialize(obj, Hash.CRC);
#endif
/// <inheritdoc/>
#if NET48
public Models.Hashfile.Hashfile Deserialize(Models.Metadata.MetadataFile obj, Hash hash)
#else
public Models.Hashfile.Hashfile? Deserialize(Models.Metadata.MetadataFile? obj, Hash hash)
#endif
{
if (obj == null)
return null;
@@ -81,11 +73,7 @@ namespace SabreTools.Serialization.CrossModel
/// <summary>
/// Convert from <cref="Models.Metadata.MetadataFile"/> to an array of <cref="Models.Hashfile.Hashfile"/>
/// </summary>
#if NET48
public static Models.Hashfile.Hashfile[] ConvertArrayFromInternalModel(Models.Metadata.MetadataFile item, Hash hash)
#else
public static Models.Hashfile.Hashfile[]? ConvertArrayFromInternalModel(Models.Metadata.MetadataFile? item, Hash hash)
#endif
{
if (item == null)
return null;

View File

@@ -7,11 +7,7 @@ namespace SabreTools.Serialization.CrossModel
public partial class Hashfile : IModelSerializer<Models.Hashfile.Hashfile, Models.Metadata.MetadataFile>
{
/// <inheritdoc/>
#if NET48
public Models.Metadata.MetadataFile Serialize(Models.Hashfile.Hashfile obj)
#else
public Models.Metadata.MetadataFile? Serialize(Models.Hashfile.Hashfile? obj)
#endif
{
if (obj == null)
return null;

View File

@@ -8,11 +8,7 @@ namespace SabreTools.Serialization.CrossModel
public partial class Listrom : IModelSerializer<MetadataFile, Models.Metadata.MetadataFile>
{
/// <inheritdoc/>
#if NET48
public MetadataFile Deserialize(Models.Metadata.MetadataFile obj)
#else
public MetadataFile? Deserialize(Models.Metadata.MetadataFile? obj)
#endif
{
if (obj == null)
return null;

View File

@@ -8,11 +8,7 @@ namespace SabreTools.Serialization.CrossModel
public partial class Listrom : IModelSerializer<MetadataFile, Models.Metadata.MetadataFile>
{
/// <inheritdoc/>
#if NET48
public Models.Metadata.MetadataFile Serialize(MetadataFile obj)
#else
public Models.Metadata.MetadataFile? Serialize(MetadataFile? obj)
#endif
{
if (obj == null)
return null;
@@ -51,7 +47,7 @@ namespace SabreTools.Serialization.CrossModel
private static Models.Metadata.Machine ConvertMachineToInternalModel(Set item)
{
var machine = new Models.Metadata.Machine();
if (!string.IsNullOrWhiteSpace(item.Device))
if (!string.IsNullOrEmpty(item.Device))
{
machine[Models.Metadata.Machine.NameKey] = item.Device;
machine[Models.Metadata.Machine.IsDeviceKey] = "yes";

View File

@@ -7,11 +7,7 @@ namespace SabreTools.Serialization.CrossModel
public partial class Listxml : IModelSerializer<Mame, Models.Metadata.MetadataFile>
{
/// <inheritdoc/>
#if NET48
public Mame Deserialize(Models.Metadata.MetadataFile obj)
#else
public Mame? Deserialize(Models.Metadata.MetadataFile? obj)
#endif
{
if (obj == null)
return null;
@@ -34,11 +30,7 @@ namespace SabreTools.Serialization.CrossModel
/// <summary>
/// Convert from <cref="Models.Metadata.Models.Metadata.MetadataFile"/> to <cref="Models.Listxml.Mame"/>
/// </summary>
#if NET48
private static Mame ConvertMameFromInternalModel(Models.Metadata.MetadataFile item)
#else
public static Mame? ConvertMameFromInternalModel(Models.Metadata.MetadataFile? item)
#endif
{
if (item == null)
return null;

View File

@@ -7,11 +7,7 @@ namespace SabreTools.Serialization.CrossModel
public partial class Listxml : IModelSerializer<Mame, Models.Metadata.MetadataFile>
{
/// <inheritdoc/>
#if NET48
public Models.Metadata.MetadataFile Serialize(Mame item)
#else
public Models.Metadata.MetadataFile? Serialize(Mame? item)
#endif
{
if (item == null)
return null;

View File

@@ -7,18 +7,10 @@ namespace SabreTools.Serialization.CrossModel
public partial class Logiqx : IModelSerializer<Datafile, Models.Metadata.MetadataFile>
{
/// <inheritdoc/>
#if NET48
public Datafile Deserialize(Models.Metadata.MetadataFile obj) => Deserialize(obj, false);
#else
public Datafile? Deserialize(Models.Metadata.MetadataFile? obj) => Deserialize(obj, false);
#endif
/// <inheritdoc/>
#if NET48
public Datafile Deserialize(Models.Metadata.MetadataFile obj, bool game)
#else
public Datafile? Deserialize(Models.Metadata.MetadataFile? obj, bool game)
#endif
{
if (obj == null)
return null;
@@ -111,15 +103,7 @@ namespace SabreTools.Serialization.CrossModel
/// </summary>
private static GameBase ConvertMachineFromInternalModel(Models.Metadata.Machine item, bool game = false)
{
#if NET48
GameBase gameBase;
if (game)
gameBase = new Game();
else
gameBase = new Machine();
#else
GameBase gameBase = game ? new Game() : new Machine();
#endif
gameBase.Name = item.ReadString(Models.Metadata.Machine.NameKey);
gameBase.SourceFile = item.ReadString(Models.Metadata.Machine.SourceFileKey);

View File

@@ -8,11 +8,7 @@ namespace SabreTools.Serialization.CrossModel
{
public partial class Logiqx : IModelSerializer<Datafile, Models.Metadata.MetadataFile>
{
#if NET48
public Models.Metadata.MetadataFile Serialize(Datafile item)
#else
public Models.Metadata.MetadataFile? Serialize(Datafile? item)
#endif
{
if (item == null)
return null;
@@ -26,9 +22,9 @@ namespace SabreTools.Serialization.CrossModel
if (item.Game != null && item.Game.Any())
{
machines.AddRange(item.Game
.Where(g => g != null)
.Select(ConvertMachineToInternalModel));
machines.AddRange(item.Game
.Where(g => g != null)
.Select(ConvertMachineToInternalModel));
}
if (item.Dir != null && item.Dir.Any())
@@ -108,7 +104,7 @@ namespace SabreTools.Serialization.CrossModel
private static Models.Metadata.Machine[] ConvertDirToInternalModel(Dir item)
{
if (item.Game == null || !item.Game.Any())
return Array.Empty<Models.Metadata.Machine>();
return [];
return item.Game
.Where(g => g != null)

View File

@@ -6,11 +6,7 @@ namespace SabreTools.Serialization.CrossModel
public partial class M1 : IModelSerializer<Models.Listxml.M1, Models.Metadata.MetadataFile>
{
/// <inheritdoc/>
#if NET48
public Models.Listxml.M1 Deserialize(Models.Metadata.MetadataFile obj)
#else
public Models.Listxml.M1? Deserialize(Models.Metadata.MetadataFile? obj)
#endif
{
if (obj == null)
return null;

View File

@@ -6,11 +6,7 @@ namespace SabreTools.Serialization.CrossModel
public partial class M1 : IModelSerializer<Models.Listxml.M1, Models.Metadata.MetadataFile>
{
/// <inheritdoc/>
#if NET48
public Models.Metadata.MetadataFile Serialize(Models.Listxml.M1 item)
#else
public Models.Metadata.MetadataFile? Serialize(Models.Listxml.M1? item)
#endif
{
if (item == null)
return null;

View File

@@ -7,11 +7,7 @@ namespace SabreTools.Serialization.CrossModel
public partial class OfflineList : IModelSerializer<Dat, Models.Metadata.MetadataFile>
{
/// <inheritdoc/>
#if NET48
public Dat Deserialize(Models.Metadata.MetadataFile obj)
#else
public Dat? Deserialize(Models.Metadata.MetadataFile? obj)
#endif
{
if (obj == null)
return null;

View File

@@ -7,11 +7,7 @@ namespace SabreTools.Serialization.CrossModel
public partial class OfflineList : IModelSerializer<Dat, Models.Metadata.MetadataFile>
{
/// <inheritdoc/>
#if NET48
public Models.Metadata.MetadataFile Serialize(Dat item)
#else
public Models.Metadata.MetadataFile? Serialize(Dat? item)
#endif
{
if (item == null)
return null;

View File

@@ -7,11 +7,7 @@ namespace SabreTools.Serialization.CrossModel
public partial class OpenMSX : IModelSerializer<SoftwareDb, Models.Metadata.MetadataFile>
{
/// <inheritdoc/>
#if NET48
public SoftwareDb Deserialize(Models.Metadata.MetadataFile obj)
#else
public SoftwareDb? Deserialize(Models.Metadata.MetadataFile? obj)
#endif
{
if (obj == null)
return null;

View File

@@ -7,11 +7,7 @@ namespace SabreTools.Serialization.CrossModel
public partial class OpenMSX : IModelSerializer<SoftwareDb, Models.Metadata.MetadataFile>
{
/// <inheritdoc/>
#if NET48
public Models.Metadata.MetadataFile Serialize(SoftwareDb item)
#else
public Models.Metadata.MetadataFile? Serialize(SoftwareDb? item)
#endif
{
if (item == null)
return null;

View File

@@ -8,11 +8,7 @@ namespace SabreTools.Serialization.CrossModel
public partial class RomCenter : IModelSerializer<MetadataFile, Models.Metadata.MetadataFile>
{
/// <inheritdoc/>
#if NET48
public MetadataFile Deserialize(Models.Metadata.MetadataFile obj)
#else
public MetadataFile? Deserialize(Models.Metadata.MetadataFile? obj)
#endif
{
if (obj == null)
return null;
@@ -95,7 +91,7 @@ namespace SabreTools.Serialization.CrossModel
{
var roms = item.Read<Models.Metadata.Rom[]>(Models.Metadata.Machine.RomKey);
if (roms == null)
return Array.Empty<Rom>();
return [];
return roms
.Where(r => r != null)

View File

@@ -7,11 +7,7 @@ namespace SabreTools.Serialization.CrossModel
public partial class RomCenter : IModelSerializer<MetadataFile, Models.Metadata.MetadataFile>
{
/// <inheritdoc/>
#if NET48
public Models.Metadata.MetadataFile Serialize(MetadataFile obj)
#else
public Models.Metadata.MetadataFile? Serialize(MetadataFile? obj)
#endif
{
if (obj == null)
return null;

View File

@@ -8,11 +8,7 @@ namespace SabreTools.Serialization.CrossModel
public partial class SeparatedValue : IModelSerializer<MetadataFile, Models.Metadata.MetadataFile>
{
/// <inheritdoc/>
#if NET48
public MetadataFile Deserialize(Models.Metadata.MetadataFile obj)
#else
public MetadataFile? Deserialize(Models.Metadata.MetadataFile? obj)
#endif
{
if (obj == null)
return null;

View File

@@ -7,11 +7,7 @@ namespace SabreTools.Serialization.CrossModel
public partial class SeparatedValue : IModelSerializer<MetadataFile, Models.Metadata.MetadataFile>
{
/// <inheritdoc/>
#if NET48
public Models.Metadata.MetadataFile Serialize(MetadataFile obj)
#else
public Models.Metadata.MetadataFile? Serialize(MetadataFile? obj)
#endif
{
if (obj == null)
return null;
@@ -78,53 +74,6 @@ namespace SabreTools.Serialization.CrossModel
return machine;
}
#if NET48
/// <summary>
/// Convert from <cref="Models.SeparatedValue.Row"/> to <cref="Models.Metadata.DatItem"/>
/// </summary>
private static Models.Metadata.DatItem ConvertToInternalModel(Row item)
{
switch (item.Type)
{
case "disk":
return new Models.Metadata.Disk
{
[Models.Metadata.Disk.NameKey] = item.DiskName,
[Models.Metadata.Disk.MD5Key] = item.MD5,
[Models.Metadata.Disk.SHA1Key] = item.SHA1,
[Models.Metadata.Disk.StatusKey] = item.Status,
};
case "media":
return new Models.Metadata.Media
{
[Models.Metadata.Media.NameKey] = item.DiskName,
[Models.Metadata.Media.MD5Key] = item.MD5,
[Models.Metadata.Media.SHA1Key] = item.SHA1,
[Models.Metadata.Media.SHA256Key] = item.SHA256,
[Models.Metadata.Media.SpamSumKey] = item.SpamSum,
};
case "rom":
return new Models.Metadata.Rom
{
[Models.Metadata.Rom.NameKey] = item.RomName,
[Models.Metadata.Rom.SizeKey] = item.Size,
[Models.Metadata.Rom.CRCKey] = item.CRC,
[Models.Metadata.Rom.MD5Key] = item.MD5,
[Models.Metadata.Rom.SHA1Key] = item.SHA1,
[Models.Metadata.Rom.SHA256Key] = item.SHA256,
[Models.Metadata.Rom.SHA384Key] = item.SHA384,
[Models.Metadata.Rom.SHA512Key] = item.SHA512,
[Models.Metadata.Rom.SpamSumKey] = item.SpamSum,
[Models.Metadata.Rom.StatusKey] = item.Status,
};
default:
return null;
}
}
#else
/// <summary>
/// Convert from <cref="Models.SeparatedValue.Row"/> to <cref="Models.Metadata.DatItem"/>
/// </summary>
@@ -163,6 +112,5 @@ namespace SabreTools.Serialization.CrossModel
_ => null,
};
}
#endif
}
}

View File

@@ -7,11 +7,7 @@ namespace SabreTools.Serialization.CrossModel
public partial class SoftwareList : IModelSerializer<Models.SoftwareList.SoftwareList, Models.Metadata.MetadataFile>
{
/// <inheritdoc/>
#if NET48
public Models.SoftwareList.SoftwareList Deserialize(Models.Metadata.MetadataFile obj)
#else
public Models.SoftwareList.SoftwareList? Deserialize(Models.Metadata.MetadataFile? obj)
#endif
{
if (obj == null)
return null;

View File

@@ -7,11 +7,7 @@ namespace SabreTools.Serialization.CrossModel
public partial class SoftwareList : IModelSerializer<Models.SoftwareList.SoftwareList, Models.Metadata.MetadataFile>
{
/// <inheritdoc/>
#if NET48
public Models.Metadata.MetadataFile Serialize(Models.SoftwareList.SoftwareList item)
#else
public Models.Metadata.MetadataFile? Serialize(Models.SoftwareList.SoftwareList? item)
#endif
{
if (item == null)
return null;

View File

@@ -17,11 +17,7 @@ namespace SabreTools.Serialization
/// <param name="rva">Relative virtual address to convert</param>
/// <param name="sections">Array of sections to check against</param>
/// <returns>Physical address, 0 on error</returns>
#if NET48
public static uint ConvertVirtualAddress(this uint rva, SectionHeader[] sections)
#else
public static uint ConvertVirtualAddress(this uint rva, SectionHeader?[]? sections)
#endif
{
// If we have an invalid section table, we can't do anything
if (sections == null || sections.Length == 0)
@@ -44,19 +40,11 @@ namespace SabreTools.Serialization
continue;
// If the section "starts" at 0, just skip it
#if NET48
if (sections[i].PointerToRawData == 0)
#else
if (sections[i]!.PointerToRawData == 0)
#endif
continue;
// Attempt to derive the physical address from the current section
#if NET48
var section = sections[i];
#else
var section = sections[i]!;
#endif
if (rva >= section.VirtualAddress && section.VirtualSize != 0 && rva <= section.VirtualAddress + section.VirtualSize)
return rva - section.VirtualAddress + section.PointerToRawData;
else if (rva >= section.VirtualAddress && section.SizeOfRawData != 0 && rva <= section.VirtualAddress + section.SizeOfRawData)
@@ -72,11 +60,7 @@ namespace SabreTools.Serialization
/// <param name="rva">Relative virtual address to convert</param>
/// <param name="sections">Array of sections to check against</param>
/// <returns>Section index, null on error</returns>
#if NET48
public static int ContainingSectionIndex(this uint rva, SectionHeader[] sections)
#else
public static int ContainingSectionIndex(this uint rva, SectionHeader?[]? sections)
#endif
{
// If we have an invalid section table, we can't do anything
if (sections == null || sections.Length == 0)
@@ -114,11 +98,7 @@ namespace SabreTools.Serialization
/// <param name="data">Data to parse into overlay data</param>
/// <param name="offset">Offset into the byte array</param>
/// <returns>A filled SecuROM AddD overlay data on success, null on error</returns>
#if NET48
public static SecuROMAddD AsSecuROMAddD(this byte[] data, ref int offset)
#else
public static SecuROMAddD? AsSecuROMAddD(this byte[]? data, ref int offset)
#endif
{
// If we have data that's invalid, we can't do anything
if (data == null)
@@ -135,15 +115,15 @@ namespace SabreTools.Serialization
addD.EntryCount = data.ReadUInt32(ref offset);
addD.Version = data.ReadString(ref offset, Encoding.ASCII);
if (string.IsNullOrWhiteSpace(addD.Version))
if (string.IsNullOrEmpty(addD.Version))
offset = originalOffset + 0x10;
addD.Build = data.ReadBytes(ref offset, 4)?.Select(b => (char)b)?.ToArray();
// Distinguish between v1 and v2
int bytesToRead = 112; // v2
if (string.IsNullOrWhiteSpace(addD.Version)
|| addD.Version.StartsWith("3")
if (string.IsNullOrEmpty(addD.Version)
|| addD.Version!.StartsWith("3")
|| addD.Version.StartsWith("4.47"))
{
bytesToRead = 44;
@@ -181,11 +161,7 @@ namespace SabreTools.Serialization
/// <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>
#if NET48
public static NB10ProgramDatabase AsNB10ProgramDatabase(this byte[] data, ref int offset)
#else
public static NB10ProgramDatabase? AsNB10ProgramDatabase(this byte[] data, ref int offset)
#endif
{
// If we have data that's invalid, we can't do anything
if (data == null)
@@ -211,11 +187,7 @@ namespace SabreTools.Serialization
/// <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>
#if NET48
public static RSDSProgramDatabase AsRSDSProgramDatabase(this byte[] data, ref int offset)
#else
public static RSDSProgramDatabase? AsRSDSProgramDatabase(this byte[]? data, ref int offset)
#endif
{
// If we have data that's invalid, we can't do anything
if (data == null)
@@ -247,11 +219,7 @@ namespace SabreTools.Serialization
/// <param name="data">Data to parse into a resource header</param>
/// <param name="offset">Offset into the byte array</param>
/// <returns>A filled resource header on success, null on error</returns>
#if NET48
public static ResourceHeader AsResourceHeader(this byte[] data, ref int offset)
#else
public static ResourceHeader? AsResourceHeader(this byte[]? data, ref int offset)
#endif
{
// If we have data that's invalid, we can't do anything
if (data == null)
@@ -277,11 +245,7 @@ namespace SabreTools.Serialization
/// </summary>
/// <param name="entry">Resource data entry to parse into an accelerator table resource</param>
/// <returns>A filled accelerator table resource on success, null on error</returns>
#if NET48
public static AcceleratorTableEntry[] AsAcceleratorTableResource(this ResourceDataEntry entry)
#else
public static AcceleratorTableEntry[]? AsAcceleratorTableResource(this ResourceDataEntry? entry)
#endif
{
// If we have data that's invalid for this resource type, we can't do anything
if (entry?.Data == null || entry.Data.Length % 8 != 0)
@@ -317,11 +281,7 @@ namespace SabreTools.Serialization
/// </summary>
/// <param name="entry">Resource data entry to parse into a side-by-side assembly manifest</param>
/// <returns>A filled side-by-side assembly manifest on success, null on error</returns>
#if NET48
public static AssemblyManifest AsAssemblyManifest(this ResourceDataEntry entry)
#else
public static AssemblyManifest? AsAssemblyManifest(this ResourceDataEntry? entry)
#endif
{
// If we have an invalid entry, just skip
if (entry?.Data == null)
@@ -329,7 +289,7 @@ namespace SabreTools.Serialization
try
{
XmlSerializer serializer = new XmlSerializer(typeof(AssemblyManifest));
var serializer = new XmlSerializer(typeof(AssemblyManifest));
return serializer.Deserialize(new MemoryStream(entry.Data)) as AssemblyManifest;
}
catch
@@ -343,11 +303,7 @@ namespace SabreTools.Serialization
/// </summary>
/// <param name="entry">Resource data entry to parse into a dialog box</param>
/// <returns>A filled dialog box on success, null on error</returns>
#if NET48
public static DialogBoxResource AsDialogBox(this ResourceDataEntry entry)
#else
public static DialogBoxResource? AsDialogBox(this ResourceDataEntry? entry)
#endif
{
// If we have an invalid entry, just skip
if (entry?.Data == null)
@@ -402,7 +358,7 @@ namespace SabreTools.Serialization
dialogTemplateExtended.MenuResource = entry.Data.ReadString(ref offset, Encoding.Unicode);
// Align to the WORD boundary if we're not at the end
if (offset != entry.Data.Length)
if (offset < entry.Data.Length)
{
while ((offset % 2) != 0)
_ = entry.Data.ReadByte(ref offset);
@@ -438,7 +394,7 @@ namespace SabreTools.Serialization
dialogTemplateExtended.ClassResource = entry.Data.ReadString(ref offset, Encoding.Unicode);
// Align to the WORD boundary if we're not at the end
if (offset != entry.Data.Length)
if (offset < entry.Data.Length)
{
while ((offset % 2) != 0)
_ = entry.Data.ReadByte(ref offset);
@@ -469,7 +425,7 @@ namespace SabreTools.Serialization
dialogTemplateExtended.TitleResource = entry.Data.ReadString(ref offset, Encoding.Unicode);
// Align to the WORD boundary if we're not at the end
if (offset != entry.Data.Length)
if (offset < entry.Data.Length)
{
while ((offset % 2) != 0)
_ = entry.Data.ReadByte(ref offset);
@@ -481,7 +437,11 @@ namespace SabreTools.Serialization
#region Point size and typeface
// Only if DS_SETFONT is set are the values here used
#if NET20 || NET35
if ((dialogTemplateExtended.Style & WindowStyles.DS_SETFONT) != 0)
#else
if (dialogTemplateExtended.Style.HasFlag(WindowStyles.DS_SETFONT))
#endif
{
dialogTemplateExtended.PointSize = entry.Data.ReadUInt16(ref offset);
dialogTemplateExtended.Weight = entry.Data.ReadUInt16(ref offset);
@@ -491,9 +451,9 @@ namespace SabreTools.Serialization
}
// Align to the DWORD boundary if we're not at the end
if (offset != entry.Data.Length)
if (offset < entry.Data.Length)
{
while ((offset % 4) != 0)
while (offset < entry.Data.Length && (offset % 4) != 0)
_ = entry.Data.ReadByte(ref offset);
}
@@ -546,7 +506,7 @@ namespace SabreTools.Serialization
dialogItemTemplate.ClassResource = entry.Data.ReadString(ref offset, Encoding.Unicode);
// Align to the WORD boundary if we're not at the end
if (offset != entry.Data.Length)
if (offset < entry.Data.Length)
{
while ((offset % 2) != 0)
_ = entry.Data.ReadByte(ref offset);
@@ -576,7 +536,7 @@ namespace SabreTools.Serialization
dialogItemTemplate.TitleResource = entry.Data.ReadString(ref offset, Encoding.Unicode);
// Align to the WORD boundary if we're not at the end
if (offset != entry.Data.Length)
if (offset < entry.Data.Length)
{
while ((offset % 2) != 0)
_ = entry.Data.ReadByte(ref offset);
@@ -594,16 +554,16 @@ namespace SabreTools.Serialization
#endregion
// Align to the DWORD boundary if we're not at the end
if (offset != entry.Data.Length)
if (offset < entry.Data.Length)
{
while ((offset % 4) != 0)
while (offset < entry.Data.Length && (offset % 4) != 0)
_ = entry.Data.ReadByte(ref offset);
}
dialogItemExtendedTemplates.Add(dialogItemTemplate);
}
dialogBoxResource.ExtendedDialogItemTemplates = dialogItemExtendedTemplates.ToArray();
dialogBoxResource.ExtendedDialogItemTemplates = [.. dialogItemExtendedTemplates];
#endregion
}
@@ -644,7 +604,7 @@ namespace SabreTools.Serialization
dialogTemplate.MenuResource = entry.Data.ReadString(ref offset, Encoding.Unicode);
// Align to the WORD boundary if we're not at the end
if (offset != entry.Data.Length)
if (offset < entry.Data.Length)
{
while ((offset % 2) != 0)
_ = entry.Data.ReadByte(ref offset);
@@ -680,7 +640,7 @@ namespace SabreTools.Serialization
dialogTemplate.ClassResource = entry.Data.ReadString(ref offset, Encoding.Unicode);
// Align to the WORD boundary if we're not at the end
if (offset != entry.Data.Length)
if (offset < entry.Data.Length)
{
while ((offset % 2) != 0)
_ = entry.Data.ReadByte(ref offset);
@@ -711,7 +671,7 @@ namespace SabreTools.Serialization
dialogTemplate.TitleResource = entry.Data.ReadString(ref offset, Encoding.Unicode);
// Align to the WORD boundary if we're not at the end
if (offset != entry.Data.Length)
if (offset < entry.Data.Length)
{
while ((offset % 2) != 0)
_ = entry.Data.ReadByte(ref offset);
@@ -723,7 +683,11 @@ namespace SabreTools.Serialization
#region Point size and typeface
// Only if DS_SETFONT is set are the values here used
#if NET20 || NET35
if ((dialogTemplate.Style & WindowStyles.DS_SETFONT) != 0)
#else
if (dialogTemplate.Style.HasFlag(WindowStyles.DS_SETFONT))
#endif
{
dialogTemplate.PointSizeValue = entry.Data.ReadUInt16(ref offset);
@@ -732,9 +696,9 @@ namespace SabreTools.Serialization
}
// Align to the DWORD boundary if we're not at the end
if (offset != entry.Data.Length)
if (offset < entry.Data.Length)
{
while ((offset % 4) != 0)
while (offset < entry.Data.Length && (offset % 4) != 0)
_ = entry.Data.ReadByte(ref offset);
}
@@ -786,7 +750,7 @@ namespace SabreTools.Serialization
dialogItemTemplate.ClassResource = entry.Data.ReadString(ref offset, Encoding.Unicode);
// Align to the WORD boundary if we're not at the end
if (offset != entry.Data.Length)
if (offset < entry.Data.Length)
{
while ((offset % 2) != 0)
_ = entry.Data.ReadByte(ref offset);
@@ -816,7 +780,7 @@ namespace SabreTools.Serialization
dialogItemTemplate.TitleResource = entry.Data.ReadString(ref offset, Encoding.Unicode);
// Align to the WORD boundary if we're not at the end
if (offset != entry.Data.Length)
if (offset < entry.Data.Length)
{
while ((offset % 2) != 0)
_ = entry.Data.ReadByte(ref offset);
@@ -834,16 +798,16 @@ namespace SabreTools.Serialization
#endregion
// Align to the DWORD boundary if we're not at the end
if (offset != entry.Data.Length)
if (offset < entry.Data.Length)
{
while ((offset % 4) != 0)
while (offset < entry.Data.Length && (offset % 4) != 0)
_ = entry.Data.ReadByte(ref offset);
}
dialogItemTemplates.Add(dialogItemTemplate);
}
dialogBoxResource.DialogItemTemplates = dialogItemTemplates.ToArray();
dialogBoxResource.DialogItemTemplates = [.. dialogItemTemplates];
#endregion
}
@@ -856,11 +820,7 @@ namespace SabreTools.Serialization
/// </summary>
/// <param name="entry">Resource data entry to parse into a font group</param>
/// <returns>A filled font group on success, null on error</returns>
#if NET48
public static FontGroupHeader AsFontGroup(this ResourceDataEntry entry)
#else
public static FontGroupHeader? AsFontGroup(this ResourceDataEntry? entry)
#endif
{
// If we have an invalid entry, just skip
if (entry?.Data == null)
@@ -929,11 +889,7 @@ namespace SabreTools.Serialization
/// </summary>
/// <param name="entry">Resource data entry to parse into a menu</param>
/// <returns>A filled menu on success, null on error</returns>
#if NET48
public static MenuResource AsMenu(this ResourceDataEntry entry)
#else
public static MenuResource? AsMenu(this ResourceDataEntry? entry)
#endif
{
// If we have an invalid entry, just skip
if (entry?.Data == null)
@@ -981,9 +937,9 @@ namespace SabreTools.Serialization
extendedMenuItem.MenuText = entry.Data.ReadString(ref offset, Encoding.Unicode);
// Align to the DWORD boundary if we're not at the end
if (offset != entry.Data.Length)
if (offset < entry.Data.Length)
{
while ((offset % 4) != 0)
while (offset < entry.Data.Length && (offset % 4) != 0)
_ = entry.Data.ReadByte(ref offset);
}
@@ -991,7 +947,7 @@ namespace SabreTools.Serialization
}
}
menuResource.ExtendedMenuItems = extendedMenuItems.ToArray();
menuResource.ExtendedMenuItems = [.. extendedMenuItems];
#endregion
}
@@ -1019,7 +975,11 @@ namespace SabreTools.Serialization
// Determine if this is a popup
int flagsOffset = offset;
var initialFlags = (MenuFlags)entry.Data.ReadUInt16(ref flagsOffset);
#if NET20 || NET35
if ((initialFlags & MenuFlags.MF_POPUP) != 0)
#else
if (initialFlags.HasFlag(MenuFlags.MF_POPUP))
#endif
{
menuItem.PopupItemType = (MenuFlags)entry.Data.ReadUInt32(ref offset);
menuItem.PopupState = (MenuFlags)entry.Data.ReadUInt32(ref offset);
@@ -1034,16 +994,16 @@ namespace SabreTools.Serialization
}
// Align to the DWORD boundary if we're not at the end
if (offset != entry.Data.Length)
if (offset < entry.Data.Length)
{
while ((offset % 4) != 0)
while (offset < entry.Data.Length && (offset % 4) != 0)
_ = entry.Data.ReadByte(ref offset);
}
menuItems.Add(menuItem);
}
menuResource.MenuItems = menuItems.ToArray();
menuResource.MenuItems = [.. menuItems];
#endregion
}
@@ -1056,11 +1016,7 @@ namespace SabreTools.Serialization
/// </summary>
/// <param name="entry">Resource data entry to parse into a message table resource</param>
/// <returns>A filled message table resource on success, null on error</returns>
#if NET48
public static MessageResourceData AsMessageResourceData(this ResourceDataEntry entry)
#else
public static MessageResourceData? AsMessageResourceData(this ResourceDataEntry? entry)
#endif
{
// If we have an invalid entry, just skip
if (entry?.Data == null)
@@ -1089,17 +1045,13 @@ namespace SabreTools.Serialization
messageResourceBlocks.Add(messageResourceBlock);
}
messageResourceData.Blocks = messageResourceBlocks.ToArray();
messageResourceData.Blocks = [.. messageResourceBlocks];
}
// Message resource entries
if (messageResourceData.Blocks != null && messageResourceData.Blocks.Length != 0)
{
#if NET48
var messageResourceEntries = new Dictionary<uint, MessageResourceEntry>();
#else
var messageResourceEntries = new Dictionary<uint, MessageResourceEntry?>();
#endif
for (int i = 0; i < messageResourceData.Blocks.Length; i++)
{
@@ -1117,11 +1069,7 @@ namespace SabreTools.Serialization
messageResourceEntry.Flags = entry.Data.ReadUInt16(ref offset);
Encoding textEncoding = messageResourceEntry.Flags == 0x0001 ? Encoding.Unicode : Encoding.ASCII;
#if NET48
byte[] textArray = entry.Data.ReadBytes(ref offset, messageResourceEntry.Length - 4);
#else
byte[]? textArray = entry.Data.ReadBytes(ref offset, messageResourceEntry.Length - 4);
#endif
if (textArray != null)
messageResourceEntry.Text = textEncoding.GetString(textArray);
@@ -1140,11 +1088,7 @@ namespace SabreTools.Serialization
/// </summary>
/// <param name="entry">Resource data entry to parse into a string table resource</param>
/// <returns>A filled string table resource on success, null on error</returns>
#if NET48
public static Dictionary<int, string> AsStringTable(this ResourceDataEntry entry)
#else
public static Dictionary<int, string?>? AsStringTable(this ResourceDataEntry? entry)
#endif
{
// If we have an invalid entry, just skip
if (entry?.Data == null)
@@ -1154,11 +1098,7 @@ namespace SabreTools.Serialization
int offset = 0, stringIndex = 0;
// Create the output table
#if NET48
var stringTable = new Dictionary<int, string>();
#else
var stringTable = new Dictionary<int, string?>();
#endif
// Loop through and add
while (offset < entry.Data.Length)
@@ -1191,11 +1131,7 @@ namespace SabreTools.Serialization
/// </summary>
/// <param name="entry">Resource data entry to parse into a version info resource</param>
/// <returns>A filled version info resource on success, null on error</returns>
#if NET48
public static VersionInfo AsVersionInfo(this ResourceDataEntry entry)
#else
public static VersionInfo? AsVersionInfo(this ResourceDataEntry? entry)
#endif
{
// If we have an invalid entry, just skip
if (entry?.Data == null)
@@ -1214,7 +1150,7 @@ namespace SabreTools.Serialization
if (versionInfo.Key != "VS_VERSION_INFO")
return null;
while ((offset % 4) != 0)
while (offset < entry.Data.Length && (offset % 4) != 0)
versionInfo.Padding1 = entry.Data.ReadUInt16(ref offset);
// Read fixed file info
@@ -1240,7 +1176,7 @@ namespace SabreTools.Serialization
versionInfo.Value = fixedFileInfo;
}
while ((offset % 4) != 0)
while (offset < entry.Data.Length && (offset % 4) != 0)
versionInfo.Padding2 = entry.Data.ReadUInt16(ref offset);
// TODO: Make the following block a private helper method
@@ -1252,11 +1188,7 @@ namespace SabreTools.Serialization
int currentOffset = offset;
offset += 6;
#if NET48
string nextKey = entry.Data.ReadString(ref offset, Encoding.Unicode);
#else
string? nextKey = entry.Data.ReadString(ref offset, Encoding.Unicode);
#endif
offset = currentOffset;
if (nextKey == "StringFileInfo")
@@ -1278,11 +1210,7 @@ namespace SabreTools.Serialization
int currentOffset = offset;
offset += 6;
#if NET48
string nextKey = entry.Data.ReadString(ref offset, Encoding.Unicode);
#else
string? nextKey = entry.Data.ReadString(ref offset, Encoding.Unicode);
#endif
offset = currentOffset;
if (nextKey == "StringFileInfo")
@@ -1306,11 +1234,7 @@ namespace SabreTools.Serialization
/// <param name="data">Data to parse into a string file info</param>
/// <param name="offset">Offset into the byte array</param>
/// <returns>A filled string file info resource on success, null on error</returns>
#if NET48
private static StringFileInfo AsStringFileInfo(byte[] data, ref int offset)
#else
private static StringFileInfo? AsStringFileInfo(byte[] data, ref int offset)
#endif
{
var stringFileInfo = new StringFileInfo();
@@ -1328,9 +1252,9 @@ namespace SabreTools.Serialization
}
// Align to the DWORD boundary if we're not at the end
if (offset != data.Length)
if (offset < data.Length)
{
while ((offset % 4) != 0)
while (offset < data.Length && (offset % 4) != 0)
stringFileInfo.Padding = data.ReadByte(ref offset);
}
@@ -1345,9 +1269,9 @@ namespace SabreTools.Serialization
stringTable.Key = data.ReadString(ref offset, Encoding.Unicode);
// Align to the DWORD boundary if we're not at the end
if (offset != data.Length)
if (offset < data.Length)
{
while ((offset % 4) != 0)
while (offset < data.Length && (offset % 4) != 0)
stringTable.Padding = data.ReadByte(ref offset);
}
@@ -1362,39 +1286,35 @@ namespace SabreTools.Serialization
stringData.Key = data.ReadString(ref offset, Encoding.Unicode);
// Align to the DWORD boundary if we're not at the end
if (offset != data.Length)
if (offset < data.Length)
{
while ((offset % 4) != 0)
while (offset < data.Length && (offset % 4) != 0)
stringData.Padding = data.ReadByte(ref offset);
}
if (stringData.ValueLength > 0)
{
#if NET48
byte[] valueBytes = data.ReadBytes(ref offset, stringData.ValueLength * sizeof(ushort));
#else
byte[]? valueBytes = data.ReadBytes(ref offset, stringData.ValueLength * sizeof(ushort));
#endif
if (valueBytes != null)
stringData.Value = Encoding.Unicode.GetString(valueBytes);
}
// Align to the DWORD boundary if we're not at the end
if (offset != data.Length)
if (offset < data.Length)
{
while ((offset % 4) != 0)
while (offset < data.Length && (offset % 4) != 0)
_ = data.ReadByte(ref offset);
}
stringTableChildren.Add(stringData);
}
stringTable.Children = stringTableChildren.ToArray();
stringTable.Children = [.. stringTableChildren];
stringFileInfoChildren.Add(stringTable);
}
stringFileInfo.Children = stringFileInfoChildren.ToArray();
stringFileInfo.Children = [.. stringFileInfoChildren];
return stringFileInfo;
}
@@ -1405,11 +1325,7 @@ namespace SabreTools.Serialization
/// <param name="data">Data to parse into a var file info</param>
/// <param name="offset">Offset into the byte array</param>
/// <returns>A filled var file info resource on success, null on error</returns>
#if NET48
private static VarFileInfo AsVarFileInfo(byte[] data, ref int offset)
#else
private static VarFileInfo? AsVarFileInfo(byte[] data, ref int offset)
#endif
{
var varFileInfo = new VarFileInfo();
@@ -1424,9 +1340,9 @@ namespace SabreTools.Serialization
return null;
// Align to the DWORD boundary if we're not at the end
if (offset != data.Length)
if (offset < data.Length)
{
while ((offset % 4) != 0)
while (offset < data.Length && (offset % 4) != 0)
varFileInfo.Padding = data.ReadByte(ref offset);
}
@@ -1446,9 +1362,9 @@ namespace SabreTools.Serialization
}
// Align to the DWORD boundary if we're not at the end
if (offset != data.Length)
if (offset < data.Length)
{
while ((offset % 4) != 0)
while (offset < data.Length && (offset % 4) != 0)
varData.Padding = data.ReadByte(ref offset);
}
@@ -1462,12 +1378,12 @@ namespace SabreTools.Serialization
varDataValue.Add(languageAndCodeIdentifierPair);
}
varData.Value = varDataValue.ToArray();
varData.Value = [.. varDataValue];
varFileInfoChildren.Add(varData);
}
varFileInfo.Children = varFileInfoChildren.ToArray();
varFileInfo.Children = [.. varFileInfoChildren];
return varFileInfo;
}

View File

@@ -6,11 +6,7 @@ namespace SabreTools.Serialization.Files
public partial class AttractMode : IFileSerializer<MetadataFile>
{
/// <inheritdoc/>
#if NET48
public MetadataFile Deserialize(string path)
#else
public MetadataFile? Deserialize(string? path)
#endif
{
using (var stream = PathProcessor.OpenStream(path))
{

View File

@@ -7,26 +7,18 @@ namespace SabreTools.Serialization.Files
public partial class AttractMode : IFileSerializer<MetadataFile>
{
/// <inheritdoc/>
#if NET48
public bool Serialize(MetadataFile obj, string path)
#else
public bool Serialize(MetadataFile? obj, string? path)
#endif
{
if (string.IsNullOrWhiteSpace(path))
if (string.IsNullOrEmpty(path))
return false;
using (var stream = new Streams.AttractMode().Serialize(obj))
{
if (stream == null)
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;
}
}
using var fs = File.OpenWrite(path);
stream.CopyTo(fs);
return true;
}
}
}

View File

@@ -6,18 +6,10 @@ namespace SabreTools.Serialization.Files
public partial class ClrMamePro : IFileSerializer<MetadataFile>
{
/// <inheritdoc/>
#if NET48
public MetadataFile Deserialize(string path) => Deserialize(path, true);
#else
public MetadataFile? Deserialize(string? path) => Deserialize(path, true);
#endif
/// <inheritdoc/>
#if NET48
public MetadataFile Deserialize(string path, bool quotes)
#else
public MetadataFile? Deserialize(string? path, bool quotes)
#endif
{
using (var stream = PathProcessor.OpenStream(path))
{

View File

@@ -7,33 +7,21 @@ namespace SabreTools.Serialization.Files
public partial class ClrMamePro : IFileSerializer<MetadataFile>
{
/// <inheritdoc/>
#if NET48
public bool Serialize(MetadataFile obj, string path) => Serialize(obj, path, true);
#else
public bool Serialize(MetadataFile? obj, string? path) => Serialize(obj, path, true);
#endif
/// <inheritdoc cref="Serialize(MetadataFile, string)"/>
#if NET48
public bool Serialize(MetadataFile obj, string path, bool quotes)
#else
public bool Serialize(MetadataFile? obj, string? path, bool quotes)
#endif
{
if (string.IsNullOrWhiteSpace(path))
if (string.IsNullOrEmpty(path))
return false;
using (var stream = new Streams.ClrMamePro().Serialize(obj, quotes))
{
if (stream == null)
return false;
using var stream = new Streams.ClrMamePro().Serialize(obj, quotes);
if (stream == null)
return false;
using (var fs = File.OpenWrite(path))
{
stream.CopyTo(fs);
return true;
}
}
using var fs = File.OpenWrite(path);
stream.CopyTo(fs);
return true;
}
}
}

View File

@@ -11,14 +11,10 @@ namespace SabreTools.Serialization.Files
public partial class CueSheet : IFileSerializer<Models.CueSheets.CueSheet>
{
/// <inheritdoc/>
#if NET48
public Models.CueSheets.CueSheet Deserialize(string path)
#else
public Models.CueSheets.CueSheet? Deserialize(string? path)
#endif
{
// Check that the file exists
if (string.IsNullOrWhiteSpace(path) || !File.Exists(path))
if (string.IsNullOrEmpty(path) || !File.Exists(path))
return null;
// Check the extension
@@ -47,7 +43,7 @@ namespace SabreTools.Serialization.Files
.ToArray();
// If we have an empty line, we skip
if (string.IsNullOrWhiteSpace(line))
if (string.IsNullOrEmpty(line))
continue;
switch (splitLine[0])
@@ -122,11 +118,7 @@ namespace SabreTools.Serialization.Files
/// <param name="fileType">File type to set</param>
/// <param name="cueLines">Lines array to pull from</param>
/// <param name="i">Reference to index in array</param>
#if NET48
private static CueFile CreateCueFile(string fileName, string fileType, string[] cueLines, ref int i)
#else
private static CueFile? CreateCueFile(string fileName, string fileType, string[]? cueLines, ref int i)
#endif
{
// Check the required parameters
if (cueLines == null)
@@ -151,7 +143,7 @@ namespace SabreTools.Serialization.Files
string[] splitLine = line.Split(' ');
// If we have an empty line, we skip
if (string.IsNullOrWhiteSpace(line))
if (string.IsNullOrEmpty(line))
continue;
switch (splitLine[0])
@@ -191,11 +183,7 @@ namespace SabreTools.Serialization.Files
/// <param name="dataType">Data type to set</param>
/// <param name="cueLines">Lines array to pull from</param>
/// <param name="i">Reference to index in array</param>
#if NET48
private static CueTrack CreateCueTrack(string number, string dataType, string[] cueLines, ref int i)
#else
private static CueTrack? CreateCueTrack(string number, string dataType, string[]? cueLines, ref int i)
#endif
{
// Check the required parameters
if (cueLines == null)
@@ -225,7 +213,7 @@ namespace SabreTools.Serialization.Files
string[] splitLine = line.Split(' ');
// If we have an empty line, we skip
if (string.IsNullOrWhiteSpace(line))
if (string.IsNullOrEmpty(line))
continue;
switch (splitLine[0])
@@ -326,18 +314,14 @@ namespace SabreTools.Serialization.Files
/// Create a PREGAP from a mm:ss:ff length
/// </summary>
/// <param name="length">String to get length information from</param>
#if NET48
private static PreGap CreatePreGap(string length)
#else
private static PreGap CreatePreGap(string? length)
#endif
{
// Ignore empty lines
if (string.IsNullOrWhiteSpace(length))
if (string.IsNullOrEmpty(length))
throw new ArgumentException("Length was null or whitespace");
// Ignore lines that don't contain the correct information
if (length.Length != 8 || length.Count(c => c == ':') != 2)
if (length!.Length != 8 || length.Count(c => c == ':') != 2)
throw new FormatException($"Length was not in a recognized format: {length}");
// Split the line
@@ -381,11 +365,7 @@ namespace SabreTools.Serialization.Files
/// </summary>
/// <param name="index">Index to set</param>
/// <param name="startTime">Start time to set</param>
#if NET48
private static CueIndex CreateCueIndex(string index, string startTime)
#else
private static CueIndex CreateCueIndex(string? index, string? startTime)
#endif
{
// Set the current fields
if (!int.TryParse(index, out int parsedIndex))
@@ -394,11 +374,11 @@ namespace SabreTools.Serialization.Files
throw new IndexOutOfRangeException($"Index must be between 0 and 99: {parsedIndex}");
// Ignore empty lines
if (string.IsNullOrWhiteSpace(startTime))
if (string.IsNullOrEmpty(startTime))
throw new ArgumentException("Start time was null or whitespace");
// Ignore lines that don't contain the correct information
if (startTime.Length != 8 || startTime.Count(c => c == ':') != 2)
if (startTime!.Length != 8 || startTime.Count(c => c == ':') != 2)
throw new FormatException($"Start time was not in a recognized format: {startTime}");
// Split the line
@@ -442,18 +422,14 @@ namespace SabreTools.Serialization.Files
/// Create a POSTGAP from a mm:ss:ff length
/// </summary>
/// <param name="length">String to get length information from</param>
#if NET48
private static PostGap CreatePostGap(string length)
#else
private static PostGap CreatePostGap(string? length)
#endif
{
// Ignore empty lines
if (string.IsNullOrWhiteSpace(length))
if (string.IsNullOrEmpty(length))
throw new ArgumentException("Length was null or whitespace");
// Ignore lines that don't contain the correct information
if (length.Length != 8 || length.Count(c => c == ':') != 2)
if (length!.Length != 8 || length.Count(c => c == ':') != 2)
throw new FormatException($"Length was not in a recognized format: {length}");
// Split the line
@@ -499,11 +475,7 @@ namespace SabreTools.Serialization.Files
/// </summary>
/// <param name="fileType">String to get value from</param>
/// <returns>CueFileType, if possible</returns>
#if NET48
private static CueFileType GetFileType(string fileType)
#else
private static CueFileType GetFileType(string? fileType)
#endif
{
switch (fileType?.ToLowerInvariant())
{
@@ -532,11 +504,7 @@ namespace SabreTools.Serialization.Files
/// </summary>
/// <param name="dataType">String to get value from</param>
/// <returns>CueTrackDataType, if possible (default AUDIO)</returns>
#if NET48
private static CueTrackDataType GetDataType(string dataType)
#else
private static CueTrackDataType GetDataType(string? dataType)
#endif
{
switch (dataType?.ToLowerInvariant())
{
@@ -574,21 +542,13 @@ namespace SabreTools.Serialization.Files
/// </summary>
/// <param name="flagStrings">Possible flags as strings</param>
/// <returns>CueTrackFlag value representing the strings, if possible</returns>
#if NET48
private static CueTrackFlag GetFlags(string[] flagStrings)
#else
private static CueTrackFlag GetFlags(string?[]? flagStrings)
#endif
{
CueTrackFlag flag = 0;
if (flagStrings == null)
return flag;
#if NET48
foreach (string flagString in flagStrings)
#else
foreach (string? flagString in flagStrings)
#endif
{
switch (flagString?.ToLowerInvariant())
{

View File

@@ -6,26 +6,18 @@ namespace SabreTools.Serialization.Files
public partial class CueSheet : IFileSerializer<Models.CueSheets.CueSheet>
{
/// <inheritdoc/>
#if NET48
public bool Serialize(Models.CueSheets.CueSheet obj, string path)
#else
public bool Serialize(Models.CueSheets.CueSheet? obj, string? path)
#endif
{
if (string.IsNullOrWhiteSpace(path))
if (string.IsNullOrEmpty(path))
return false;
using (var stream = new Streams.CueSheet().Serialize(obj))
{
if (stream == null)
return false;
using var stream = new Streams.CueSheet().Serialize(obj);
if (stream == null)
return false;
using (var fs = File.OpenWrite(path))
{
stream.CopyTo(fs);
return true;
}
}
using var fs = File.OpenWrite(path);
stream.CopyTo(fs);
return true;
}
}
}

View File

@@ -6,11 +6,7 @@ namespace SabreTools.Serialization.Files
public partial class DosCenter : IFileSerializer<MetadataFile>
{
/// <inheritdoc/>
#if NET48
public MetadataFile Deserialize(string path)
#else
public MetadataFile? Deserialize(string? path)
#endif
{
using (var stream = PathProcessor.OpenStream(path))
{

View File

@@ -6,26 +6,18 @@ namespace SabreTools.Serialization.Files
public partial class DosCenter : IFileSerializer<MetadataFile>
{
/// <inheritdoc/>
#if NET48
public bool Serialize(MetadataFile obj, string path)
#else
public bool Serialize(MetadataFile? obj, string? path)
#endif
{
if (string.IsNullOrWhiteSpace(path))
if (string.IsNullOrEmpty(path))
return false;
using (var stream = new Streams.DosCenter().Serialize(obj))
{
if (stream == null)
return false;
using var stream = new Streams.DosCenter().Serialize(obj);
if (stream == null)
return false;
using (var fs = System.IO.File.OpenWrite(path))
{
stream.CopyTo(fs);
return true;
}
}
using var fs = System.IO.File.OpenWrite(path);
stream.CopyTo(fs);
return true;
}
}
}

View File

@@ -6,11 +6,7 @@ namespace SabreTools.Serialization.Files
public partial class EverdriveSMDB : IFileSerializer<MetadataFile>
{
/// <inheritdoc/>
#if NET48
public MetadataFile Deserialize(string path)
#else
public MetadataFile? Deserialize(string? path)
#endif
{
using (var stream = PathProcessor.OpenStream(path))
{

View File

@@ -6,26 +6,18 @@ namespace SabreTools.Serialization.Files
public partial class EverdriveSMDB : IFileSerializer<MetadataFile>
{
/// <inheritdoc/>
#if NET48
public bool Serialize(MetadataFile obj, string path)
#else
public bool Serialize(MetadataFile? obj, string? path)
#endif
{
if (string.IsNullOrWhiteSpace(path))
if (string.IsNullOrEmpty(path))
return false;
using (var stream = new Streams.EverdriveSMDB().Serialize(obj))
{
if (stream == null)
return false;
using var stream = new Streams.EverdriveSMDB().Serialize(obj);
if (stream == null)
return false;
using (var fs = System.IO.File.OpenWrite(path))
{
stream.CopyTo(fs);
return true;
}
}
using var fs = System.IO.File.OpenWrite(path);
stream.CopyTo(fs);
return true;
}
}
}

View File

@@ -5,18 +5,10 @@ namespace SabreTools.Serialization.Files
public partial class Hashfile : IFileSerializer<Models.Hashfile.Hashfile>
{
/// <inheritdoc/>
#if NET48
public Models.Hashfile.Hashfile Deserialize(string path) => Deserialize(path, Hash.CRC);
#else
public Models.Hashfile.Hashfile? Deserialize(string? path) => Deserialize(path, Hash.CRC);
#endif
/// <inheritdoc/>
#if NET48
public Models.Hashfile.Hashfile Deserialize(string path, Hash hash)
#else
public Models.Hashfile.Hashfile? Deserialize(string? path, Hash hash)
#endif
{
using (var stream = PathProcessor.OpenStream(path))
{

View File

@@ -5,33 +5,21 @@ namespace SabreTools.Serialization.Files
public partial class Hashfile : IFileSerializer<Models.Hashfile.Hashfile>
{
/// <inheritdoc/>
#if NET48
public bool Serialize(Models.Hashfile.Hashfile obj, string path) => Serialize(obj, path, Hash.CRC);
#else
public bool Serialize(Models.Hashfile.Hashfile? obj, string? path) => Serialize(obj, path, Hash.CRC);
#endif
/// <inheritdoc/>
#if NET48
public bool Serialize(Models.Hashfile.Hashfile obj, string path, Hash hash)
#else
public bool Serialize(Models.Hashfile.Hashfile? obj, string? path, Hash hash)
#endif
{
if (string.IsNullOrWhiteSpace(path))
if (string.IsNullOrEmpty(path))
return false;
using (var stream = new Streams.Hashfile().Serialize(obj, hash))
{
if (stream == null)
return false;
using var stream = new Streams.Hashfile().Serialize(obj, hash);
if (stream == null)
return false;
using (var fs = System.IO.File.OpenWrite(path))
{
stream.CopyTo(fs);
return true;
}
}
using var fs = System.IO.File.OpenWrite(path);
stream.CopyTo(fs);
return true;
}
}
}

16
Files/IRD.Deserializer.cs Normal file
View File

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

22
Files/IRD.Serializer.cs Normal file
View File

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

View File

@@ -6,11 +6,7 @@ namespace SabreTools.Serialization.Files
public partial class Listrom : IFileSerializer<MetadataFile>
{
/// <inheritdoc/>
#if NET48
public MetadataFile Deserialize(string path)
#else
public MetadataFile? Deserialize(string? path)
#endif
{
using (var stream = PathProcessor.OpenStream(path))
{

View File

@@ -6,26 +6,18 @@ namespace SabreTools.Serialization.Files
public partial class Listrom : IFileSerializer<MetadataFile>
{
/// <inheritdoc/>
#if NET48
public bool Serialize(MetadataFile obj, string path)
#else
public bool Serialize(MetadataFile? obj, string? path)
#endif
{
if (string.IsNullOrWhiteSpace(path))
if (string.IsNullOrEmpty(path))
return false;
using (var stream = new Streams.Listrom().Serialize(obj))
{
if (stream == null)
return false;
using var stream = new Streams.Listrom().Serialize(obj);
if (stream == null)
return false;
using (var fs = System.IO.File.OpenWrite(path))
{
stream.CopyTo(fs);
return true;
}
}
using var fs = System.IO.File.OpenWrite(path);
stream.CopyTo(fs);
return true;
}
}
}

View File

@@ -6,11 +6,7 @@ namespace SabreTools.Serialization.Files
public partial class PIC : IFileSerializer<DiscInformation>
{
/// <inheritdoc/>
#if NET48
public DiscInformation Deserialize(string path)
#else
public DiscInformation? Deserialize(string? path)
#endif
{
using (var stream = PathProcessor.OpenStream(path))
{

View File

@@ -6,26 +6,18 @@ namespace SabreTools.Serialization.Files
public partial class PIC : IFileSerializer<DiscInformation>
{
/// <inheritdoc/>
#if NET48
public bool Serialize(DiscInformation obj, string path)
#else
public bool Serialize(DiscInformation? obj, string? path)
#endif
{
if (string.IsNullOrWhiteSpace(path))
if (string.IsNullOrEmpty(path))
return false;
using (var stream = new Streams.PIC().Serialize(obj))
{
if (stream == null)
return false;
using var stream = new Streams.PIC().Serialize(obj);
if (stream == null)
return false;
using (var fs = System.IO.File.OpenWrite(path))
{
stream.CopyTo(fs);
return true;
}
}
using var fs = System.IO.File.OpenWrite(path);
stream.CopyTo(fs);
return true;
}
}
}

View File

@@ -6,11 +6,7 @@ namespace SabreTools.Serialization.Files
public partial class RomCenter : IFileSerializer<MetadataFile>
{
/// <inheritdoc/>
#if NET48
public MetadataFile Deserialize(string path)
#else
public MetadataFile? Deserialize(string? path)
#endif
{
using (var stream = PathProcessor.OpenStream(path))
{

View File

@@ -6,26 +6,18 @@ namespace SabreTools.Serialization.Files
public partial class RomCenter : IFileSerializer<MetadataFile>
{
/// <inheritdoc/>
#if NET48
public bool Serialize(MetadataFile obj, string path)
#else
public bool Serialize(MetadataFile? obj, string? path)
#endif
{
if (string.IsNullOrWhiteSpace(path))
if (string.IsNullOrEmpty(path))
return false;
using (var stream = new Streams.RomCenter().Serialize(obj))
{
if (stream == null)
return false;
using var stream = new Streams.RomCenter().Serialize(obj);
if (stream == null)
return false;
using (var fs = System.IO.File.OpenWrite(path))
{
stream.CopyTo(fs);
return true;
}
}
using var fs = System.IO.File.OpenWrite(path);
stream.CopyTo(fs);
return true;
}
}
}

View File

@@ -6,18 +6,10 @@ namespace SabreTools.Serialization.Files
public partial class SeparatedValue : IFileSerializer<MetadataFile>
{
/// <inheritdoc/>
#if NET48
public MetadataFile Deserialize(string path) => Deserialize(path, ',');
#else
public MetadataFile? Deserialize(string? path) => Deserialize(path, ',');
#endif
/// <inheritdoc/>
#if NET48
public MetadataFile Deserialize(string path, char delim)
#else
public MetadataFile? Deserialize(string? path, char delim)
#endif
{
using (var stream = PathProcessor.OpenStream(path))
{

View File

@@ -6,33 +6,21 @@ namespace SabreTools.Serialization.Files
public partial class SeparatedValue : IFileSerializer<MetadataFile>
{
/// <inheritdoc/>
#if NET48
public bool Serialize(MetadataFile obj, string path) => Serialize(obj, path, ',');
#else
public bool Serialize(MetadataFile? obj, string? path) => Serialize(obj, path, ',');
#endif
/// <inheritdoc/>
#if NET48
public bool Serialize(MetadataFile obj, string path, char delim)
#else
public bool Serialize(MetadataFile? obj, string? path, char delim)
#endif
{
if (string.IsNullOrWhiteSpace(path))
if (string.IsNullOrEmpty(path))
return false;
using (var stream = new Streams.SeparatedValue().Serialize(obj, delim))
{
if (stream == null)
return false;
using var stream = new Streams.SeparatedValue().Serialize(obj, delim);
if (stream == null)
return false;
using (var fs = System.IO.File.OpenWrite(path))
{
stream.CopyTo(fs);
return true;
}
}
using var fs = System.IO.File.OpenWrite(path);
stream.CopyTo(fs);
return true;
}
}
}

View File

@@ -1,216 +0,0 @@
using SabreTools.Serialization.Interfaces;
namespace SabreTools.Serialization.Files
{
public partial class XMID : IFileSerializer<Models.Xbox.XMID>
{
/// <inheritdoc/>
/// <remarks>This treats the input path like a parseable string</remarks>
#if NET48
public Models.Xbox.XMID Deserialize(string path)
#else
public Models.Xbox.XMID? Deserialize(string? path)
#endif
{
if (string.IsNullOrWhiteSpace(path))
return null;
string xmid = path.TrimEnd('\0');
if (string.IsNullOrWhiteSpace(xmid))
return null;
return ParseXMID(xmid);
}
/// <summary>
/// Parse an XGD2/3 XMID string
/// </summary>
/// <param name="xmidString">XMID string to attempt to parse</param>
/// <returns>Filled XMID on success, null on error</returns>
#if NET48
private static Models.Xbox.XMID ParseXMID(string xmidString)
#else
private static Models.Xbox.XMID? ParseXMID(string? xmidString)
#endif
{
if (xmidString == null || xmidString.Length != 8)
return null;
var xmid = new Models.Xbox.XMID();
xmid.PublisherIdentifier = xmidString.Substring(0, 2);
if (string.IsNullOrEmpty(PublisherName(xmid)))
return null;
xmid.GameID = xmidString.Substring(2, 3);
xmid.VersionNumber = xmidString.Substring(5, 2);
xmid.RegionIdentifier = xmidString[7];
if (InternalRegion(xmid) == null)
return null;
return xmid;
}
#region Helpers
/// <summary>
/// Human-readable name derived from the publisher identifier
/// </summary>
#if NET48
public static string PublisherName(Models.Xbox.XMID xmid) => GetPublisher(xmid.PublisherIdentifier);
#else
public static string? PublisherName(Models.Xbox.XMID xmid) => GetPublisher(xmid.PublisherIdentifier);
#endif
/// <summary>
/// Internally represented region
/// </summary>
#if NET48
public static string InternalRegion(Models.Xbox.XMID xmid) => GetRegion(xmid.RegionIdentifier);
#else
public static string? InternalRegion(Models.Xbox.XMID xmid) => GetRegion(xmid.RegionIdentifier);
#endif
/// <summary>
/// Get the full name of the publisher from the 2-character identifier
/// </summary>
/// <param name="publisherIdentifier">Case-sensitive 2-character identifier</param>
/// <returns>Publisher name, if possible</returns>
/// <see cref="https://xboxdevwiki.net/Xbe#Title_ID"/>
#if NET48
private static string GetPublisher(string publisherIdentifier)
#else
private static string? GetPublisher(string? publisherIdentifier)
#endif
{
switch (publisherIdentifier)
{
case "AC": return "Acclaim Entertainment";
case "AH": return "ARUSH Entertainment";
case "AQ": return "Aqua System";
case "AS": return "ASK";
case "AT": return "Atlus";
case "AV": return "Activision";
case "AY": return "Aspyr Media";
case "BA": return "Bandai";
case "BL": return "Black Box";
case "BM": return "BAM! Entertainment";
case "BR": return "Broccoli Co.";
case "BS": return "Bethesda Softworks";
case "BU": return "Bunkasha Co.";
case "BV": return "Buena Vista Games";
case "BW": return "BBC Multimedia";
case "BZ": return "Blizzard";
case "CC": return "Capcom";
case "CK": return "Kemco Corporation"; // TODO: Confirm
case "CM": return "Codemasters";
case "CV": return "Crave Entertainment";
case "DC": return "DreamCatcher Interactive";
case "DX": return "Davilex";
case "EA": return "Electronic Arts (EA)";
case "EC": return "Encore inc";
case "EL": return "Enlight Software";
case "EM": return "Empire Interactive";
case "ES": return "Eidos Interactive";
case "FI": return "Fox Interactive";
case "FS": return "From Software";
case "GE": return "Genki Co.";
case "GV": return "Groove Games";
case "HE": return "Tru Blu (Entertainment division of Home Entertainment Suppliers)";
case "HP": return "Hip games";
case "HU": return "Hudson Soft";
case "HW": return "Highwaystar";
case "IA": return "Mad Catz Interactive";
case "IF": return "Idea Factory";
case "IG": return "Infogrames";
case "IL": return "Interlex Corporation";
case "IM": return "Imagine Media";
case "IO": return "Ignition Entertainment";
case "IP": return "Interplay Entertainment";
case "IX": return "InXile Entertainment"; // TODO: Confirm
case "JA": return "Jaleco";
case "JW": return "JoWooD";
case "KB": return "Kemco"; // TODO: Confirm
case "KI": return "Kids Station Inc."; // TODO: Confirm
case "KN": return "Konami";
case "KO": return "KOEI";
case "KU": return "Kobi and / or GAE (formerly Global A Entertainment)"; // TODO: Confirm
case "LA": return "LucasArts";
case "LS": return "Black Bean Games (publishing arm of Leader S.p.A.)";
case "MD": return "Metro3D";
case "ME": return "Medix";
case "MI": return "Microïds";
case "MJ": return "Majesco Entertainment";
case "MM": return "Myelin Media";
case "MP": return "MediaQuest"; // TODO: Confirm
case "MS": return "Microsoft Game Studios";
case "MW": return "Midway Games";
case "MX": return "Empire Interactive"; // TODO: Confirm
case "NK": return "NewKidCo";
case "NL": return "NovaLogic";
case "NM": return "Namco";
case "OX": return "Oxygen Interactive";
case "PC": return "Playlogic Entertainment";
case "PL": return "Phantagram Co., Ltd.";
case "RA": return "Rage";
case "SA": return "Sammy";
case "SC": return "SCi Games";
case "SE": return "SEGA";
case "SN": return "SNK";
case "SS": return "Simon & Schuster";
case "SU": return "Success Corporation";
case "SW": return "Swing! Deutschland";
case "TA": return "Takara";
case "TC": return "Tecmo";
case "TD": return "The 3DO Company (or just 3DO)";
case "TK": return "Takuyo";
case "TM": return "TDK Mediactive";
case "TQ": return "THQ";
case "TS": return "Titus Interactive";
case "TT": return "Take-Two Interactive Software";
case "US": return "Ubisoft";
case "VC": return "Victor Interactive Software";
case "VN": return "Vivendi Universal (just took Interplays publishing rights)"; // TODO: Confirm
case "VU": return "Vivendi Universal Games";
case "VV": return "Vivendi Universal Games"; // TODO: Confirm
case "WE": return "Wanadoo Edition";
case "WR": return "Warner Bros. Interactive Entertainment"; // TODO: Confirm
case "XI": return "XPEC Entertainment and Idea Factory";
case "XK": return "Xbox kiosk disk?"; // TODO: Confirm
case "XL": return "Xbox special bundled or live demo disk?"; // TODO: Confirm
case "XM": return "Evolved Games"; // TODO: Confirm
case "XP": return "XPEC Entertainment";
case "XR": return "Panorama";
case "YB": return "YBM Sisa (South-Korea)";
case "ZD": return "Zushi Games (formerly Zoo Digital Publishing)";
default: return null;
}
}
/// <summary>
/// Determine the region based on the XGD serial character
/// </summary>
/// <param name="region">Character denoting the region</param>
/// <returns>Region, if possible</returns>
#if NET48
private static string GetRegion(char region)
#else
private static string? GetRegion(char region)
#endif
{
switch (region)
{
case 'W': return "World";
case 'A': return "USA";
case 'J': return "Japan / Asia";
case 'E': return "Europe";
case 'K': return "USA / Japan";
case 'L': return "USA / Europe";
case 'H': return "Japan / Europe";
default: return null;
}
}
#endregion
}
}

View File

@@ -1,15 +0,0 @@
using System;
using SabreTools.Serialization.Interfaces;
namespace SabreTools.Serialization.Files
{
public partial class XMID : IFileSerializer<Models.Xbox.XMID>
{
/// <inheritdoc/>
#if NET48
public bool Serialize(Models.Xbox.XMID obj, string path) => throw new NotImplementedException();
#else
public bool Serialize(Models.Xbox.XMID? obj, string? path) => throw new NotImplementedException();
#endif
}
}

View File

@@ -1,275 +0,0 @@
using SabreTools.Serialization.Interfaces;
namespace SabreTools.Serialization.Files
{
public partial class XeMID : IFileSerializer<Models.Xbox.XeMID>
{
/// <inheritdoc/>
/// <remarks>This treats the input path like a parseable string</remarks>
#if NET48
public Models.Xbox.XeMID Deserialize(string path)
#else
public Models.Xbox.XeMID? Deserialize(string? path)
#endif
{
if (string.IsNullOrWhiteSpace(path))
return null;
string xemid = path.TrimEnd('\0');
if (string.IsNullOrWhiteSpace(xemid))
return null;
return ParseXeMID(xemid);
}
/// <summary>
/// Parse an XGD2/3 XeMID string
/// </summary>
/// <param name="xemidString">XeMID string to attempt to parse</param>
/// <returns>Filled XeMID on success, null on error</returns>
#if NET48
private static Models.Xbox.XeMID ParseXeMID(string xemidString)
#else
private static Models.Xbox.XeMID? ParseXeMID(string? xemidString)
#endif
{
if (xemidString == null
|| (xemidString.Length != 13 && xemidString.Length != 14
&& xemidString.Length != 21 && xemidString.Length != 22))
return null;
var xemid = new Models.Xbox.XeMID();
xemid.PublisherIdentifier = xemidString.Substring(0, 2);
if (string.IsNullOrEmpty(PublisherName(xemid)))
return null;
xemid.PlatformIdentifier = xemidString[2];
if (xemid.PlatformIdentifier != '2')
return null;
xemid.GameID = xemidString.Substring(3, 3);
xemid.SKU = xemidString.Substring(6, 2);
xemid.RegionIdentifier = xemidString[8];
if (InternalRegion(xemid) == null)
return null;
if (xemidString.Length == 13 || xemidString.Length == 21)
{
xemid.BaseVersion = xemidString.Substring(9, 1);
xemid.MediaSubtypeIdentifier = xemidString[10];
if (string.IsNullOrEmpty(MediaSubtype(xemid)))
return null;
xemid.DiscNumberIdentifier = xemidString.Substring(11, 2);
}
else if (xemidString.Length == 14 || xemidString.Length == 22)
{
xemid.BaseVersion = xemidString.Substring(9, 2);
xemid.MediaSubtypeIdentifier = xemidString[11];
if (string.IsNullOrEmpty(MediaSubtype(xemid)))
return null;
xemid.DiscNumberIdentifier = xemidString.Substring(12, 2);
}
if (xemidString.Length == 21)
xemid.CertificationSubmissionIdentifier = xemidString.Substring(13);
else if (xemidString.Length == 22)
xemid.CertificationSubmissionIdentifier = xemidString.Substring(14);
return xemid;
}
#region Helpers
/// <summary>
/// Human-readable name derived from the publisher identifier
/// </summary>
#if NET48
public static string PublisherName(Models.Xbox.XeMID xemid) => GetPublisher(xemid.PublisherIdentifier);
#else
public static string? PublisherName(Models.Xbox.XeMID xemid) => GetPublisher(xemid.PublisherIdentifier);
#endif
/// <summary>
/// Internally represented region
/// </summary>
#if NET48
public static string InternalRegion(Models.Xbox.XeMID xemid) => GetRegion(xemid.RegionIdentifier);
#else
public static string? InternalRegion(Models.Xbox.XeMID xemid) => GetRegion(xemid.RegionIdentifier);
#endif
/// <summary>
/// Human-readable subtype derived from the media identifier
/// </summary>
#if NET48
public static string MediaSubtype(Models.Xbox.XeMID xemid) => GetMediaSubtype(xemid.MediaSubtypeIdentifier);
#else
public static string? MediaSubtype(Models.Xbox.XeMID xemid) => GetMediaSubtype(xemid.MediaSubtypeIdentifier);
#endif
/// <summary>
/// Determine the XGD type based on the XGD2/3 media type identifier character
/// </summary>
/// <param name="mediaTypeIdentifier">Character denoting the media type</param>
/// <returns>Media subtype as a string, if possible</returns>
#if NET48
private static string GetMediaSubtype(char mediaTypeIdentifier)
#else
private static string? GetMediaSubtype(char mediaTypeIdentifier)
#endif
{
switch (mediaTypeIdentifier)
{
case 'F': return "XGD3";
case 'X': return "XGD2";
case 'Z': return "Games on Demand / Marketplace Demo";
default: return null;
}
}
/// <summary>
/// Get the full name of the publisher from the 2-character identifier
/// </summary>
/// <param name="publisherIdentifier">Case-sensitive 2-character identifier</param>
/// <returns>Publisher name, if possible</returns>
/// <see cref="https://xboxdevwiki.net/Xbe#Title_ID"/>
#if NET48
private static string GetPublisher(string publisherIdentifier)
#else
private static string? GetPublisher(string? publisherIdentifier)
#endif
{
switch (publisherIdentifier)
{
case "AC": return "Acclaim Entertainment";
case "AH": return "ARUSH Entertainment";
case "AQ": return "Aqua System";
case "AS": return "ASK";
case "AT": return "Atlus";
case "AV": return "Activision";
case "AY": return "Aspyr Media";
case "BA": return "Bandai";
case "BL": return "Black Box";
case "BM": return "BAM! Entertainment";
case "BR": return "Broccoli Co.";
case "BS": return "Bethesda Softworks";
case "BU": return "Bunkasha Co.";
case "BV": return "Buena Vista Games";
case "BW": return "BBC Multimedia";
case "BZ": return "Blizzard";
case "CC": return "Capcom";
case "CK": return "Kemco Corporation"; // TODO: Confirm
case "CM": return "Codemasters";
case "CV": return "Crave Entertainment";
case "DC": return "DreamCatcher Interactive";
case "DX": return "Davilex";
case "EA": return "Electronic Arts (EA)";
case "EC": return "Encore inc";
case "EL": return "Enlight Software";
case "EM": return "Empire Interactive";
case "ES": return "Eidos Interactive";
case "FI": return "Fox Interactive";
case "FS": return "From Software";
case "GE": return "Genki Co.";
case "GV": return "Groove Games";
case "HE": return "Tru Blu (Entertainment division of Home Entertainment Suppliers)";
case "HP": return "Hip games";
case "HU": return "Hudson Soft";
case "HW": return "Highwaystar";
case "IA": return "Mad Catz Interactive";
case "IF": return "Idea Factory";
case "IG": return "Infogrames";
case "IL": return "Interlex Corporation";
case "IM": return "Imagine Media";
case "IO": return "Ignition Entertainment";
case "IP": return "Interplay Entertainment";
case "IX": return "InXile Entertainment"; // TODO: Confirm
case "JA": return "Jaleco";
case "JW": return "JoWooD";
case "KB": return "Kemco"; // TODO: Confirm
case "KI": return "Kids Station Inc."; // TODO: Confirm
case "KN": return "Konami";
case "KO": return "KOEI";
case "KU": return "Kobi and / or GAE (formerly Global A Entertainment)"; // TODO: Confirm
case "LA": return "LucasArts";
case "LS": return "Black Bean Games (publishing arm of Leader S.p.A.)";
case "MD": return "Metro3D";
case "ME": return "Medix";
case "MI": return "Microïds";
case "MJ": return "Majesco Entertainment";
case "MM": return "Myelin Media";
case "MP": return "MediaQuest"; // TODO: Confirm
case "MS": return "Microsoft Game Studios";
case "MW": return "Midway Games";
case "MX": return "Empire Interactive"; // TODO: Confirm
case "NK": return "NewKidCo";
case "NL": return "NovaLogic";
case "NM": return "Namco";
case "OX": return "Oxygen Interactive";
case "PC": return "Playlogic Entertainment";
case "PL": return "Phantagram Co., Ltd.";
case "RA": return "Rage";
case "SA": return "Sammy";
case "SC": return "SCi Games";
case "SE": return "SEGA";
case "SN": return "SNK";
case "SS": return "Simon & Schuster";
case "SU": return "Success Corporation";
case "SW": return "Swing! Deutschland";
case "TA": return "Takara";
case "TC": return "Tecmo";
case "TD": return "The 3DO Company (or just 3DO)";
case "TK": return "Takuyo";
case "TM": return "TDK Mediactive";
case "TQ": return "THQ";
case "TS": return "Titus Interactive";
case "TT": return "Take-Two Interactive Software";
case "US": return "Ubisoft";
case "VC": return "Victor Interactive Software";
case "VN": return "Vivendi Universal (just took Interplays publishing rights)"; // TODO: Confirm
case "VU": return "Vivendi Universal Games";
case "VV": return "Vivendi Universal Games"; // TODO: Confirm
case "WE": return "Wanadoo Edition";
case "WR": return "Warner Bros. Interactive Entertainment"; // TODO: Confirm
case "XI": return "XPEC Entertainment and Idea Factory";
case "XK": return "Xbox kiosk disk?"; // TODO: Confirm
case "XL": return "Xbox special bundled or live demo disk?"; // TODO: Confirm
case "XM": return "Evolved Games"; // TODO: Confirm
case "XP": return "XPEC Entertainment";
case "XR": return "Panorama";
case "YB": return "YBM Sisa (South-Korea)";
case "ZD": return "Zushi Games (formerly Zoo Digital Publishing)";
default: return null;
}
}
/// <summary>
/// Determine the region based on the XGD serial character
/// </summary>
/// <param name="region">Character denoting the region</param>
/// <returns>Region, if possible</returns>
#if NET48
private static string GetRegion(char region)
#else
private static string? GetRegion(char region)
#endif
{
switch (region)
{
case 'W': return "World";
case 'A': return "USA";
case 'J': return "Japan / Asia";
case 'E': return "Europe";
case 'K': return "USA / Japan";
case 'L': return "USA / Europe";
case 'H': return "Japan / Europe";
default: return null;
}
}
#endregion
}
}

View File

@@ -1,15 +0,0 @@
using System;
using SabreTools.Serialization.Interfaces;
namespace SabreTools.Serialization.Files
{
public partial class XeMID : IFileSerializer<Models.Xbox.XeMID>
{
/// <inheritdoc/>
#if NET48
public bool Serialize(Models.Xbox.XeMID obj, string path) => throw new NotImplementedException();
#else
public bool Serialize(Models.Xbox.XeMID? obj, string? path) => throw new NotImplementedException();
#endif
}
}

View File

@@ -9,11 +9,7 @@ namespace SabreTools.Serialization.Files
public partial class XmlFile<T> : IFileSerializer<T>
{
/// <inheritdoc/>
#if NET48
public T Deserialize(string path)
#else
public T? Deserialize(string? path)
#endif
{
using (var data = PathProcessor.OpenStream(path))
{

View File

@@ -10,11 +10,7 @@ namespace SabreTools.Serialization.Files
public partial class XmlFile<T> : IFileSerializer<T>
{
/// <inheritdoc/>
#if NET48
public bool Serialize(T obj, string path)
#else
public bool Serialize(T? obj, string? path)
#endif
=> Serialize(obj, path, null, null, null, null);
/// <summary>
@@ -28,27 +24,19 @@ namespace SabreTools.Serialization.Files
/// <param name="sysid">Optional DOCTYPE sysid</param>
/// <param name="subset">Optional DOCTYPE name</param>
/// <returns>True on successful serialization, false otherwise</returns>
#if NET48
public bool Serialize(T obj, string path, string name = null, string pubid = null, string sysid = null, string subset = null)
#else
public bool Serialize(T? obj, string? path, string? name = null, string? pubid = null, string? sysid = null, string? subset = null)
#endif
{
if (string.IsNullOrWhiteSpace(path))
if (string.IsNullOrEmpty(path))
return false;
using (var stream = new Streams.XmlFile<T>().Serialize(obj, name, pubid, sysid, subset))
{
if (stream == null)
return false;
using var stream = new Streams.XmlFile<T>().Serialize(obj, name, pubid, sysid, subset);
if (stream == null)
return false;
using (var fs = File.OpenWrite(path))
{
stream.CopyTo(fs);
}
using var fs = File.OpenWrite(path);
stream.CopyTo(fs);
return true;
}
return true;
}
}
}

View File

@@ -12,11 +12,7 @@ namespace SabreTools.Serialization.Interfaces
/// <param name="data">Byte array to parse</param>
/// <param name="offset">Offset into the byte array</param>
/// <returns>Filled object on success, null on error</returns>
#if NET48
T Deserialize(byte[] data, int offset);
#else
T? Deserialize(byte[]? data, int offset);
#endif
// TODO: Add serialization method
}

View File

@@ -11,23 +11,15 @@ namespace SabreTools.Serialization.Interfaces
/// <typeparam name="T">Type of object to deserialize to</typeparam>
/// <param name="path">Path to deserialize from</param>
/// <returns>Filled object on success, null on error</returns>
#if NET48
T Deserialize(string path);
#else
T? Deserialize(string? path);
#endif
/// <summary>
/// Sserialize a <typeparamref name="T"/> into a file
/// Serialize a <typeparamref name="T"/> into a file
/// </summary>
/// <typeparam name="T">Type of object to serialize from</typeparam>
/// <param name="obj">Data to serialize</param>
/// <param name="path">Path to the file to serialize to</param>
/// <returns>True on successful serialization, false otherwise</returns>
#if NET48
bool Serialize(T obj, string path);
#else
bool Serialize(T? obj, string? path);
#endif
}
}

View File

@@ -12,11 +12,7 @@ namespace SabreTools.Serialization.Interfaces
/// <typeparam name="U">Type of object to deserialize from</typeparam>
/// <param name="obj">Object to deserialize from</param>
/// <returns>Filled object on success, null on error</returns>
#if NET48
T Deserialize(U obj);
#else
T? Deserialize(U? obj);
#endif
/// <summary>
/// Serialize a <typeparamref name="T"/> into <typeparamref name="U"/>
@@ -25,10 +21,6 @@ namespace SabreTools.Serialization.Interfaces
/// <typeparam name="U">Type of object to serialize to</typeparam>
/// <param name="obj">Object to serialize from</param>
/// <returns>Filled object on success, null on error</returns>
#if NET48
U Serialize(T obj);
#else
U? Serialize(T? obj);
#endif
}
}

View File

@@ -13,11 +13,7 @@ namespace SabreTools.Serialization.Interfaces
/// <typeparam name="T">Type of object to deserialize to</typeparam>
/// <param name="data">Stream to parse</param>
/// <returns>Filled object on success, null on error</returns>
#if NET48
T Deserialize(Stream data);
#else
T? Deserialize(Stream? data);
#endif
/// <summary>
/// Serialize a <typeparamref name="T"/> into a Stream
@@ -25,10 +21,6 @@ namespace SabreTools.Serialization.Interfaces
/// <typeparam name="T">Type of object to serialize from</typeparam>
/// <param name="obj">Data to serialize</param>
/// <returns>Filled object on success, null on error</returns>
#if NET48
Stream Serialize(T obj);
#else
Stream? Serialize(T? obj);
#endif
}
}

View File

@@ -0,0 +1,24 @@
namespace SabreTools.Serialization.Interfaces
{
/// <summary>
/// Defines how to serialize to and from strings
/// </summary>
public interface IStringSerializer<T>
{
/// <summary>
/// Deserialize a string into <typeparamref name="T"/>
/// </summary>
/// <typeparam name="T">Type of object to deserialize to</typeparam>
/// <param name="str">String to deserialize from</param>
/// <returns>Filled object on success, null on error</returns>
T? Deserialize(string? str);
/// <summary>
/// Serialize a <typeparamref name="T"/> into a string
/// </summary>
/// <typeparam name="T">Type of object to serialize from</typeparam>
/// <param name="obj">Data to serialize</param>
/// <returns>Filled string on successful serialization, null otherwise</returns>
string? Serialize(T? obj);
}
}

View File

@@ -7,7 +7,7 @@ namespace SabreTools.Serialization.Interfaces
/// </summary>
string Description();
#if NET6_0_OR_GREATER
#if !NETFRAMEWORK
/// <summary>
/// Export the item information as JSON
/// </summary>

View File

@@ -10,11 +10,7 @@ namespace SabreTools.Serialization
/// <summary>
/// Extract nested items from a Dump
/// </summary>
#if NET48
public static DatItem[] ExtractItems(Dump item)
#else
public static DatItem[]? ExtractItems(Dump? item)
#endif
{
if (item == null)
return null;
@@ -33,17 +29,13 @@ namespace SabreTools.Serialization
if (sccPlusCart != null)
datItems.Add(sccPlusCart);
return datItems.ToArray();
return [.. datItems];
}
/// <summary>
/// Extract nested items from a Part
/// </summary>
#if NET48
public static DatItem[] ExtractItems(Part item)
#else
public static DatItem[]? ExtractItems(Part? item)
#endif
{
if (item == null)
return null;
@@ -59,7 +51,8 @@ namespace SabreTools.Serialization
{
datItems.AddRange(dataAreas
.Where(d => d != null)
.SelectMany(ExtractItems));
.SelectMany(ExtractItems)
.Select(d => d as DatItem));
}
var diskAreas = item.Read<DiskArea[]>(Part.DiskAreaKey);
@@ -67,17 +60,19 @@ namespace SabreTools.Serialization
{
datItems.AddRange(diskAreas
.Where(d => d != null)
.SelectMany(ExtractItems));
.SelectMany(ExtractItems)
.Select(d => d as DatItem));
}
var dipSwitches = item.Read<DipSwitch[]>(Part.DipSwitchKey);
if (dipSwitches != null && dipSwitches.Any())
{
datItems.AddRange(dipSwitches
.Where(d => d != null));
.Where(d => d != null)
.Select(d => d as DatItem));
}
return datItems.ToArray();
return [.. datItems];
}
/// <summary>
@@ -87,9 +82,9 @@ namespace SabreTools.Serialization
{
var roms = item.Read<Rom[]>(DataArea.RomKey);
if (roms == null || !roms.Any())
return Array.Empty<Rom>();
return [];
return roms.ToArray();
return [.. roms];
}
/// <summary>
@@ -99,9 +94,9 @@ namespace SabreTools.Serialization
{
var roms = item.Read<Disk[]>(DiskArea.DiskKey);
if (roms == null || !roms.Any())
return Array.Empty<Disk>();
return [];
return roms.ToArray();
return [.. roms];
}
}
}

View File

@@ -23,10 +23,6 @@ namespace SabreTools.Serialization
/// <summary>
/// subset field for DOCTYPE
/// </summary>
#if NET48
public const string DocTypeSubset = null;
#else
public const string? DocTypeSubset = null;
#endif
}
}

50
OldDotNet.cs Normal file
View File

@@ -0,0 +1,50 @@
#if NET20 || NET35
using System;
using System.IO;
namespace SabreTools.Serialization
{
/// <summary>
/// Derived from the mscorlib code from .NET Framework 4.0
/// </summary>
internal static class OldDotNet
{
public static void CopyTo(this Stream source, Stream destination)
{
if (destination == null)
{
throw new ArgumentNullException("destination");
}
if (!source.CanRead && !source.CanWrite)
{
throw new ObjectDisposedException(null);
}
if (!destination.CanRead && !destination.CanWrite)
{
throw new ObjectDisposedException("destination");
}
if (!source.CanRead)
{
throw new NotSupportedException();
}
if (!destination.CanWrite)
{
throw new NotSupportedException();
}
byte[] array = new byte[81920];
int count;
while ((count = source.Read(array, 0, array.Length)) != 0)
{
destination.Write(array, 0, count);
}
}
}
}
#endif

View File

@@ -13,11 +13,7 @@ namespace SabreTools.Serialization
/// <summary>
/// pubid field for DOCTYPE
/// </summary>
#if NET48
public const string DocTypePubId = null;
#else
public const string? DocTypePubId = null;
#endif
/// <summary>
/// sysid field for DOCTYPE
@@ -27,10 +23,6 @@ namespace SabreTools.Serialization
/// <summary>
/// subset field for DOCTYPE
/// </summary>
#if NET48
public const string DocTypeSubset = null;
#else
public const string? DocTypeSubset = null;
#endif
}
}

View File

@@ -11,16 +11,12 @@ namespace SabreTools.Serialization
/// </summary>
/// <param name="path">Path to open as a stream</param>
/// <returns>Stream representing the file, null on error</returns>
#if NET48
public static Stream OpenStream(string path)
#else
public static Stream? OpenStream(string? path)
#endif
{
try
{
// If we don't have a file
if (string.IsNullOrWhiteSpace(path) || !File.Exists(path))
if (string.IsNullOrEmpty(path) || !File.Exists(path))
return null;
// Open the file for deserialization

View File

@@ -20,6 +20,10 @@ This namespace comprises of serializers and deserializers that can convert to an
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.

View File

@@ -2,10 +2,13 @@
<PropertyGroup>
<!-- Assembly Properties -->
<TargetFrameworks>net48;net6.0;net7.0;net8.0</TargetFrameworks>
<RuntimeIdentifiers>win-x86;win-x64;linux-x64;osx-x64</RuntimeIdentifiers>
<Version>1.1.6</Version>
<TargetFrameworks>net20;net35;net40;net452;net462;net472;net48;netcoreapp3.1;net5.0;net6.0;net7.0;net8.0</TargetFrameworks>
<RuntimeIdentifiers>win-x86;win-x64;win-arm64;linux-x64;linux-arm64;osx-x64;osx-arm64</RuntimeIdentifiers>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<LangVersion>latest</LangVersion>
<Nullable>enable</Nullable>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
<Version>1.3.0</Version>
<!-- Package Properties -->
<Authors>Matt Nadareski</Authors>
@@ -19,17 +22,13 @@
<PackageLicenseExpression>MIT</PackageLicenseExpression>
</PropertyGroup>
<PropertyGroup Condition="'$(TargetFramework)'!='net48'">
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<None Include="README.md" Pack="true" PackagePath=""/>
<None Include="README.md" Pack="true" PackagePath="" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="SabreTools.IO" Version="1.1.1" />
<PackageReference Include="SabreTools.Models" Version="1.1.4" />
<PackageReference Include="SabreTools.IO" Version="1.3.0" />
<PackageReference Include="SabreTools.Models" Version="1.3.0" />
</ItemGroup>
</Project>

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