mirror of
https://github.com/SabreTools/SabreTools.Serialization.git
synced 2026-04-05 22:01:33 +00:00
Add No-Intro database export reader and writer
This commit is contained in:
480
SabreTools.Serialization.Readers.Test/NoIntroDatabaseTests.cs
Normal file
480
SabreTools.Serialization.Readers.Test/NoIntroDatabaseTests.cs
Normal file
@@ -0,0 +1,480 @@
|
|||||||
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
using Xunit;
|
||||||
|
|
||||||
|
namespace SabreTools.Serialization.Readers.Test
|
||||||
|
{
|
||||||
|
public class NoIntroDatabaseTests
|
||||||
|
{
|
||||||
|
[Fact]
|
||||||
|
public void NullArray_Null()
|
||||||
|
{
|
||||||
|
byte[]? data = null;
|
||||||
|
int offset = 0;
|
||||||
|
var deserializer = new NoIntroDatabase();
|
||||||
|
|
||||||
|
var actual = deserializer.Deserialize(data, offset);
|
||||||
|
Assert.Null(actual);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void EmptyArray_Null()
|
||||||
|
{
|
||||||
|
byte[]? data = [];
|
||||||
|
int offset = 0;
|
||||||
|
var deserializer = new NoIntroDatabase();
|
||||||
|
|
||||||
|
var actual = deserializer.Deserialize(data, offset);
|
||||||
|
Assert.Null(actual);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void InvalidArray_Null()
|
||||||
|
{
|
||||||
|
byte[]? data = [.. Enumerable.Repeat<byte>(0xFF, 1024)];
|
||||||
|
int offset = 0;
|
||||||
|
var deserializer = new NoIntroDatabase();
|
||||||
|
|
||||||
|
var actual = deserializer.Deserialize(data, offset);
|
||||||
|
Assert.Null(actual);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void NullStream_Null()
|
||||||
|
{
|
||||||
|
Stream? data = null;
|
||||||
|
var deserializer = new NoIntroDatabase();
|
||||||
|
|
||||||
|
var actual = deserializer.Deserialize(data);
|
||||||
|
Assert.Null(actual);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void EmptyStream_Null()
|
||||||
|
{
|
||||||
|
Stream? data = new MemoryStream([]);
|
||||||
|
var deserializer = new NoIntroDatabase();
|
||||||
|
|
||||||
|
var actual = deserializer.Deserialize(data);
|
||||||
|
Assert.Null(actual);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void InvalidStream_Null()
|
||||||
|
{
|
||||||
|
Stream? data = new MemoryStream([.. Enumerable.Repeat<byte>(0xFF, 1024)]);
|
||||||
|
var deserializer = new NoIntroDatabase();
|
||||||
|
|
||||||
|
var actual = deserializer.Deserialize(data);
|
||||||
|
Assert.Null(actual);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void RoundTripTest()
|
||||||
|
{
|
||||||
|
// Get the serializer and deserializer
|
||||||
|
var deserializer = new NoIntroDatabase();
|
||||||
|
var serializer = new Writers.NoIntroDatabase();
|
||||||
|
|
||||||
|
// Build the data
|
||||||
|
Data.Models.NoIntroDatabase.Datafile df = Build();
|
||||||
|
|
||||||
|
// Serialize to stream
|
||||||
|
Stream? metadata = serializer.SerializeStream(df);
|
||||||
|
Assert.NotNull(metadata);
|
||||||
|
|
||||||
|
// Serialize back to original model
|
||||||
|
Data.Models.NoIntroDatabase.Datafile? newDf = deserializer.Deserialize(metadata);
|
||||||
|
|
||||||
|
// Validate the data
|
||||||
|
Assert.NotNull(newDf);
|
||||||
|
|
||||||
|
Assert.NotNull(newDf.Game);
|
||||||
|
var newGame = Assert.Single(newDf.Game);
|
||||||
|
Validate(newGame);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Build model for serialization and deserialization
|
||||||
|
/// </summary>
|
||||||
|
private static Data.Models.NoIntroDatabase.Datafile Build()
|
||||||
|
{
|
||||||
|
var archive = new Data.Models.NoIntroDatabase.Archive
|
||||||
|
{
|
||||||
|
Number = "XXXXXX",
|
||||||
|
Clone = "XXXXXX",
|
||||||
|
RegParent = "XXXXXX",
|
||||||
|
MergeOf = "XXXXXX",
|
||||||
|
MergeName = "XXXXXX",
|
||||||
|
Name = "XXXXXX",
|
||||||
|
NameAlt = "XXXXXX",
|
||||||
|
Region = "XXXXXX",
|
||||||
|
Languages = "XXXXXX",
|
||||||
|
ShowLang = "XXXXXX",
|
||||||
|
LangChecked = "XXXXXX",
|
||||||
|
Version1 = "XXXXXX",
|
||||||
|
Version2 = "XXXXXX",
|
||||||
|
DevStatus = "XXXXXX",
|
||||||
|
Additional = "XXXXXX",
|
||||||
|
Special1 = "XXXXXX",
|
||||||
|
Special2 = "XXXXXX",
|
||||||
|
Alt = "XXXXXX",
|
||||||
|
GameId1 = "XXXXXX",
|
||||||
|
GameId2 = "XXXXXX",
|
||||||
|
Description = "XXXXXX",
|
||||||
|
Bios = "XXXXXX",
|
||||||
|
Licensed = "XXXXXX",
|
||||||
|
Pirate = "XXXXXX",
|
||||||
|
Physical = "XXXXXX",
|
||||||
|
Complete = "XXXXXX",
|
||||||
|
Adult = "XXXXXX",
|
||||||
|
Dat = "XXXXXX",
|
||||||
|
Listed = "XXXXXX",
|
||||||
|
Private = "XXXXXX",
|
||||||
|
StickyNote = "XXXXXX",
|
||||||
|
DatterNote = "XXXXXX",
|
||||||
|
Categories = "XXXXXX",
|
||||||
|
};
|
||||||
|
|
||||||
|
var media = new Data.Models.NoIntroDatabase.Media();
|
||||||
|
|
||||||
|
var sourceDetails = new Data.Models.NoIntroDatabase.SourceDetails
|
||||||
|
{
|
||||||
|
Id = "XXXXXX",
|
||||||
|
AppendToNumber = "XXXXXX",
|
||||||
|
Section = "XXXXXX",
|
||||||
|
RomInfo = "XXXXXX",
|
||||||
|
DumpDate = "XXXXXX",
|
||||||
|
DumpDateInfo = "XXXXXX",
|
||||||
|
ReleaseDate = "XXXXXX",
|
||||||
|
ReleaseDateInfo = "XXXXXX",
|
||||||
|
Dumper = "XXXXXX",
|
||||||
|
Project = "XXXXXX",
|
||||||
|
OriginalFormat = "XXXXXX",
|
||||||
|
Nodump = "XXXXXX",
|
||||||
|
Tool = "XXXXXX",
|
||||||
|
Origin = "XXXXXX",
|
||||||
|
Comment1 = "XXXXXX",
|
||||||
|
Comment2 = "XXXXXX",
|
||||||
|
Link1 = "XXXXXX",
|
||||||
|
Link1Public = "XXXXXX",
|
||||||
|
Link2 = "XXXXXX",
|
||||||
|
Link2Public = "XXXXXX",
|
||||||
|
Link3 = "XXXXXX",
|
||||||
|
Link3Public = "XXXXXX",
|
||||||
|
Region = "XXXXXX",
|
||||||
|
MediaTitle = "XXXXXX",
|
||||||
|
};
|
||||||
|
|
||||||
|
var serials = new Data.Models.NoIntroDatabase.Serials
|
||||||
|
{
|
||||||
|
MediaSerial1 = "XXXXXX",
|
||||||
|
MediaSerial2 = "XXXXXX",
|
||||||
|
MediaSerial3 = "XXXXXX",
|
||||||
|
PCBSerial = "XXXXXX",
|
||||||
|
RomChipSerial1 = "XXXXXX",
|
||||||
|
RomChipSerial2 = "XXXXXX",
|
||||||
|
LockoutSerial = "XXXXXX",
|
||||||
|
SaveChipSerial = "XXXXXX",
|
||||||
|
ChipSerial = "XXXXXX",
|
||||||
|
BoxSerial = "XXXXXX",
|
||||||
|
MediaStamp = "XXXXXX",
|
||||||
|
BoxBarcode = "XXXXXX",
|
||||||
|
DigitalSerial1 = "XXXXXX",
|
||||||
|
DigitalSerial2 = "XXXXXX",
|
||||||
|
};
|
||||||
|
|
||||||
|
var file = new Data.Models.NoIntroDatabase.File
|
||||||
|
{
|
||||||
|
Id = "XXXXXX",
|
||||||
|
AppendToSourceId = "XXXXXX",
|
||||||
|
ForceName = "XXXXXX",
|
||||||
|
ForceSceneName = "XXXXXX",
|
||||||
|
EmptyDir = "XXXXXX",
|
||||||
|
Extension = "XXXXXX",
|
||||||
|
Item = "XXXXXX",
|
||||||
|
Date = "XXXXXX",
|
||||||
|
Format = "XXXXXX",
|
||||||
|
Note = "XXXXXX",
|
||||||
|
Filter = "XXXXXX",
|
||||||
|
Version = "XXXXXX",
|
||||||
|
UpdateType = "XXXXXX",
|
||||||
|
Size = "XXXXXX",
|
||||||
|
CRC32 = "XXXXXX",
|
||||||
|
MD5 = "XXXXXX",
|
||||||
|
SHA1 = "XXXXXX",
|
||||||
|
SHA256 = "XXXXXX",
|
||||||
|
Serial = "XXXXXX",
|
||||||
|
Header = "XXXXXX",
|
||||||
|
Bad = "XXXXXX",
|
||||||
|
MIA = "XXXXXX",
|
||||||
|
Unique = "XXXXXX",
|
||||||
|
MergeName = "XXXXXX",
|
||||||
|
UniqueAttachment = "XXXXXX",
|
||||||
|
};
|
||||||
|
|
||||||
|
var source = new Data.Models.NoIntroDatabase.Source
|
||||||
|
{
|
||||||
|
Details = sourceDetails,
|
||||||
|
Serials = serials,
|
||||||
|
File = [file],
|
||||||
|
};
|
||||||
|
|
||||||
|
var releaseDetails = new Data.Models.NoIntroDatabase.ReleaseDetails
|
||||||
|
{
|
||||||
|
Id = "XXXXXX",
|
||||||
|
AppendToNumber = "XXXXXX",
|
||||||
|
Date = "XXXXXX",
|
||||||
|
OriginalFormat = "XXXXXX",
|
||||||
|
Group = "XXXXXX",
|
||||||
|
DirName = "XXXXXX",
|
||||||
|
NfoName = "XXXXXX",
|
||||||
|
NfoSize = "XXXXXX",
|
||||||
|
NfoCRC = "XXXXXX",
|
||||||
|
ArchiveName = "XXXXXX",
|
||||||
|
RomInfo = "XXXXXX",
|
||||||
|
Category = "XXXXXX",
|
||||||
|
Comment = "XXXXXX",
|
||||||
|
Tool = "XXXXXX",
|
||||||
|
Region = "XXXXXX",
|
||||||
|
Origin = "XXXXXX",
|
||||||
|
};
|
||||||
|
|
||||||
|
var release = new Data.Models.NoIntroDatabase.Release
|
||||||
|
{
|
||||||
|
Details = releaseDetails,
|
||||||
|
Serials = serials,
|
||||||
|
File = [file],
|
||||||
|
};
|
||||||
|
|
||||||
|
var game = new Data.Models.NoIntroDatabase.Game
|
||||||
|
{
|
||||||
|
Name = "XXXXXX",
|
||||||
|
Archive = archive,
|
||||||
|
Media = [media],
|
||||||
|
Source = [source],
|
||||||
|
Release = [release],
|
||||||
|
};
|
||||||
|
|
||||||
|
return new Data.Models.NoIntroDatabase.Datafile
|
||||||
|
{
|
||||||
|
Game = [game],
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Validate a Game
|
||||||
|
/// </summary>
|
||||||
|
private static void Validate(Data.Models.NoIntroDatabase.Game? game)
|
||||||
|
{
|
||||||
|
Assert.NotNull(game);
|
||||||
|
Assert.Equal("XXXXXX", game.Name);
|
||||||
|
|
||||||
|
Validate(game.Archive);
|
||||||
|
|
||||||
|
Assert.NotNull(game.Media);
|
||||||
|
Data.Models.NoIntroDatabase.Media media = Assert.Single(game.Media);
|
||||||
|
Validate(media);
|
||||||
|
|
||||||
|
Assert.NotNull(game.Source);
|
||||||
|
Data.Models.NoIntroDatabase.Source source = Assert.Single(game.Source);
|
||||||
|
Validate(source);
|
||||||
|
|
||||||
|
Assert.NotNull(game.Release);
|
||||||
|
Data.Models.NoIntroDatabase.Release release = Assert.Single(game.Release);
|
||||||
|
Validate(release);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Validate a Archive
|
||||||
|
/// </summary>
|
||||||
|
private static void Validate(Data.Models.NoIntroDatabase.Archive? archive)
|
||||||
|
{
|
||||||
|
Assert.NotNull(archive);
|
||||||
|
Assert.Equal("XXXXXX", archive.Number);
|
||||||
|
Assert.Equal("XXXXXX", archive.Clone);
|
||||||
|
Assert.Equal("XXXXXX", archive.RegParent);
|
||||||
|
Assert.Equal("XXXXXX", archive.MergeOf);
|
||||||
|
Assert.Equal("XXXXXX", archive.MergeName);
|
||||||
|
Assert.Equal("XXXXXX", archive.Name);
|
||||||
|
Assert.Equal("XXXXXX", archive.NameAlt);
|
||||||
|
Assert.Equal("XXXXXX", archive.Region);
|
||||||
|
Assert.Equal("XXXXXX", archive.Languages);
|
||||||
|
Assert.Equal("XXXXXX", archive.ShowLang);
|
||||||
|
Assert.Equal("XXXXXX", archive.LangChecked);
|
||||||
|
Assert.Equal("XXXXXX", archive.Version1);
|
||||||
|
Assert.Equal("XXXXXX", archive.Version2);
|
||||||
|
Assert.Equal("XXXXXX", archive.DevStatus);
|
||||||
|
Assert.Equal("XXXXXX", archive.Additional);
|
||||||
|
Assert.Equal("XXXXXX", archive.Special1);
|
||||||
|
Assert.Equal("XXXXXX", archive.Special2);
|
||||||
|
Assert.Equal("XXXXXX", archive.Alt);
|
||||||
|
Assert.Equal("XXXXXX", archive.GameId1);
|
||||||
|
Assert.Equal("XXXXXX", archive.GameId2);
|
||||||
|
Assert.Equal("XXXXXX", archive.Description);
|
||||||
|
Assert.Equal("XXXXXX", archive.Bios);
|
||||||
|
Assert.Equal("XXXXXX", archive.Licensed);
|
||||||
|
Assert.Equal("XXXXXX", archive.Pirate);
|
||||||
|
Assert.Equal("XXXXXX", archive.Physical);
|
||||||
|
Assert.Equal("XXXXXX", archive.Complete);
|
||||||
|
Assert.Equal("XXXXXX", archive.Adult);
|
||||||
|
Assert.Equal("XXXXXX", archive.Dat);
|
||||||
|
Assert.Equal("XXXXXX", archive.Listed);
|
||||||
|
Assert.Equal("XXXXXX", archive.Private);
|
||||||
|
Assert.Equal("XXXXXX", archive.StickyNote);
|
||||||
|
Assert.Equal("XXXXXX", archive.DatterNote);
|
||||||
|
Assert.Equal("XXXXXX", archive.Categories);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Validate a Media
|
||||||
|
/// </summary>
|
||||||
|
private static void Validate(Data.Models.NoIntroDatabase.Media? media)
|
||||||
|
{
|
||||||
|
Assert.NotNull(media);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Validate a Source
|
||||||
|
/// </summary>
|
||||||
|
private static void Validate(Data.Models.NoIntroDatabase.Source? source)
|
||||||
|
{
|
||||||
|
Assert.NotNull(source);
|
||||||
|
|
||||||
|
Validate(source.Details);
|
||||||
|
|
||||||
|
Validate(source.Serials);
|
||||||
|
|
||||||
|
Assert.NotNull(source.File);
|
||||||
|
Data.Models.NoIntroDatabase.File file = Assert.Single(source.File);
|
||||||
|
Validate(file);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Validate a Rom
|
||||||
|
/// </summary>
|
||||||
|
private static void Validate(Data.Models.NoIntroDatabase.SourceDetails? sourceDetails)
|
||||||
|
{
|
||||||
|
Assert.NotNull(sourceDetails);
|
||||||
|
Assert.Equal("XXXXXX", sourceDetails.Id);
|
||||||
|
Assert.Equal("XXXXXX", sourceDetails.AppendToNumber);
|
||||||
|
Assert.Equal("XXXXXX", sourceDetails.Section);
|
||||||
|
Assert.Equal("XXXXXX", sourceDetails.RomInfo);
|
||||||
|
Assert.Equal("XXXXXX", sourceDetails.DumpDate);
|
||||||
|
Assert.Equal("XXXXXX", sourceDetails.DumpDateInfo);
|
||||||
|
Assert.Equal("XXXXXX", sourceDetails.ReleaseDate);
|
||||||
|
Assert.Equal("XXXXXX", sourceDetails.ReleaseDateInfo);
|
||||||
|
Assert.Equal("XXXXXX", sourceDetails.Dumper);
|
||||||
|
Assert.Equal("XXXXXX", sourceDetails.Project);
|
||||||
|
Assert.Equal("XXXXXX", sourceDetails.OriginalFormat);
|
||||||
|
Assert.Equal("XXXXXX", sourceDetails.Nodump);
|
||||||
|
Assert.Equal("XXXXXX", sourceDetails.Tool);
|
||||||
|
Assert.Equal("XXXXXX", sourceDetails.Origin);
|
||||||
|
Assert.Equal("XXXXXX", sourceDetails.Comment1);
|
||||||
|
Assert.Equal("XXXXXX", sourceDetails.Comment2);
|
||||||
|
Assert.Equal("XXXXXX", sourceDetails.Link1);
|
||||||
|
Assert.Equal("XXXXXX", sourceDetails.Link1Public);
|
||||||
|
Assert.Equal("XXXXXX", sourceDetails.Link2);
|
||||||
|
Assert.Equal("XXXXXX", sourceDetails.Link2Public);
|
||||||
|
Assert.Equal("XXXXXX", sourceDetails.Link3);
|
||||||
|
Assert.Equal("XXXXXX", sourceDetails.Link3Public);
|
||||||
|
Assert.Equal("XXXXXX", sourceDetails.Region);
|
||||||
|
Assert.Equal("XXXXXX", sourceDetails.MediaTitle);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Validate a Serials
|
||||||
|
/// </summary>
|
||||||
|
private static void Validate(Data.Models.NoIntroDatabase.Serials? serials)
|
||||||
|
{
|
||||||
|
Assert.NotNull(serials);
|
||||||
|
Assert.Equal("XXXXXX", serials.MediaSerial1);
|
||||||
|
Assert.Equal("XXXXXX", serials.MediaSerial2);
|
||||||
|
Assert.Equal("XXXXXX", serials.MediaSerial3);
|
||||||
|
Assert.Equal("XXXXXX", serials.PCBSerial);
|
||||||
|
Assert.Equal("XXXXXX", serials.RomChipSerial1);
|
||||||
|
Assert.Equal("XXXXXX", serials.RomChipSerial2);
|
||||||
|
Assert.Equal("XXXXXX", serials.LockoutSerial);
|
||||||
|
Assert.Equal("XXXXXX", serials.SaveChipSerial);
|
||||||
|
Assert.Equal("XXXXXX", serials.ChipSerial);
|
||||||
|
Assert.Equal("XXXXXX", serials.BoxSerial);
|
||||||
|
Assert.Equal("XXXXXX", serials.MediaStamp);
|
||||||
|
Assert.Equal("XXXXXX", serials.BoxBarcode);
|
||||||
|
Assert.Equal("XXXXXX", serials.DigitalSerial1);
|
||||||
|
Assert.Equal("XXXXXX", serials.DigitalSerial2);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Validate a File
|
||||||
|
/// </summary>
|
||||||
|
private static void Validate(Data.Models.NoIntroDatabase.File? file)
|
||||||
|
{
|
||||||
|
Assert.NotNull(file);
|
||||||
|
Assert.Equal("XXXXXX", file.Id);
|
||||||
|
Assert.Equal("XXXXXX", file.AppendToSourceId);
|
||||||
|
Assert.Equal("XXXXXX", file.ForceName);
|
||||||
|
Assert.Equal("XXXXXX", file.ForceSceneName);
|
||||||
|
Assert.Equal("XXXXXX", file.EmptyDir);
|
||||||
|
Assert.Equal("XXXXXX", file.Extension);
|
||||||
|
Assert.Equal("XXXXXX", file.Item);
|
||||||
|
Assert.Equal("XXXXXX", file.Date);
|
||||||
|
Assert.Equal("XXXXXX", file.Format);
|
||||||
|
Assert.Equal("XXXXXX", file.Note);
|
||||||
|
Assert.Equal("XXXXXX", file.Filter);
|
||||||
|
Assert.Equal("XXXXXX", file.Version);
|
||||||
|
Assert.Equal("XXXXXX", file.UpdateType);
|
||||||
|
Assert.Equal("XXXXXX", file.Size);
|
||||||
|
Assert.Equal("XXXXXX", file.CRC32);
|
||||||
|
Assert.Equal("XXXXXX", file.MD5);
|
||||||
|
Assert.Equal("XXXXXX", file.SHA1);
|
||||||
|
Assert.Equal("XXXXXX", file.SHA256);
|
||||||
|
Assert.Equal("XXXXXX", file.Serial);
|
||||||
|
Assert.Equal("XXXXXX", file.Header);
|
||||||
|
Assert.Equal("XXXXXX", file.Bad);
|
||||||
|
Assert.Equal("XXXXXX", file.MIA);
|
||||||
|
Assert.Equal("XXXXXX", file.Unique);
|
||||||
|
Assert.Equal("XXXXXX", file.MergeName);
|
||||||
|
Assert.Equal("XXXXXX", file.UniqueAttachment);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Validate a Release
|
||||||
|
/// </summary>
|
||||||
|
private static void Validate(Data.Models.NoIntroDatabase.Release? release)
|
||||||
|
{
|
||||||
|
Assert.NotNull(release);
|
||||||
|
|
||||||
|
Validate(release.Details);
|
||||||
|
|
||||||
|
Validate(release.Serials);
|
||||||
|
|
||||||
|
Assert.NotNull(release.File);
|
||||||
|
Data.Models.NoIntroDatabase.File file = Assert.Single(release.File);
|
||||||
|
Validate(file);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Validate a ReleaseDetails
|
||||||
|
/// </summary>
|
||||||
|
private static void Validate(Data.Models.NoIntroDatabase.ReleaseDetails? releaseDetails)
|
||||||
|
{
|
||||||
|
Assert.NotNull(releaseDetails);
|
||||||
|
Assert.Equal("XXXXXX", releaseDetails.Id);
|
||||||
|
Assert.Equal("XXXXXX", releaseDetails.AppendToNumber);
|
||||||
|
Assert.Equal("XXXXXX", releaseDetails.Date);
|
||||||
|
Assert.Equal("XXXXXX", releaseDetails.OriginalFormat);
|
||||||
|
Assert.Equal("XXXXXX", releaseDetails.Group);
|
||||||
|
Assert.Equal("XXXXXX", releaseDetails.DirName);
|
||||||
|
Assert.Equal("XXXXXX", releaseDetails.NfoName);
|
||||||
|
Assert.Equal("XXXXXX", releaseDetails.NfoSize);
|
||||||
|
Assert.Equal("XXXXXX", releaseDetails.NfoCRC);
|
||||||
|
Assert.Equal("XXXXXX", releaseDetails.ArchiveName);
|
||||||
|
Assert.Equal("XXXXXX", releaseDetails.RomInfo);
|
||||||
|
Assert.Equal("XXXXXX", releaseDetails.Category);
|
||||||
|
Assert.Equal("XXXXXX", releaseDetails.Comment);
|
||||||
|
Assert.Equal("XXXXXX", releaseDetails.Tool);
|
||||||
|
Assert.Equal("XXXXXX", releaseDetails.Region);
|
||||||
|
Assert.Equal("XXXXXX", releaseDetails.Origin);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
491
SabreTools.Serialization.Readers/NoIntroDatabase.cs
Normal file
491
SabreTools.Serialization.Readers/NoIntroDatabase.cs
Normal file
@@ -0,0 +1,491 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using System.Xml;
|
||||||
|
using SabreTools.Data.Models.NoIntroDatabase;
|
||||||
|
|
||||||
|
namespace SabreTools.Serialization.Readers
|
||||||
|
{
|
||||||
|
public class NoIntroDatabase : BaseBinaryReader<Datafile>
|
||||||
|
{
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public override Datafile? Deserialize(Stream? data)
|
||||||
|
{
|
||||||
|
// If the data is invalid
|
||||||
|
if (data is null || !data.CanRead)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// Cache the current offset
|
||||||
|
long initialOffset = data.Position;
|
||||||
|
|
||||||
|
// Create the XmlTextReader
|
||||||
|
var reader = new XmlTextReader(data);
|
||||||
|
reader.WhitespaceHandling = WhitespaceHandling.None;
|
||||||
|
|
||||||
|
// Parse the XML, if possible
|
||||||
|
Datafile? datafile = null;
|
||||||
|
while (reader.Read())
|
||||||
|
{
|
||||||
|
// An ending element means exit
|
||||||
|
if (reader.NodeType == XmlNodeType.EndElement)
|
||||||
|
break;
|
||||||
|
|
||||||
|
// Only process starting elements
|
||||||
|
if (!reader.IsStartElement())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
switch (reader.Name)
|
||||||
|
{
|
||||||
|
case "datafile":
|
||||||
|
if (datafile is not null && Debug)
|
||||||
|
Console.WriteLine($"'{reader.Name}' element already found, overwriting");
|
||||||
|
|
||||||
|
datafile = ParseDatafile(reader);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
if (Debug) Console.Error.WriteLine($"Element '{reader.Name}' is not recognized");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return datafile;
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
// Ignore the actual error
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Parse from an XmlTextReader into a Datafile
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="reader">XmlTextReader to read from</param>
|
||||||
|
/// <returns>Filled Datafile on success, null on error</returns>
|
||||||
|
public Datafile ParseDatafile(XmlTextReader reader)
|
||||||
|
{
|
||||||
|
var obj = new Datafile();
|
||||||
|
|
||||||
|
List<Game> games = [];
|
||||||
|
while (reader.Read())
|
||||||
|
{
|
||||||
|
// An ending element means exit
|
||||||
|
if (reader.NodeType == XmlNodeType.EndElement)
|
||||||
|
break;
|
||||||
|
|
||||||
|
// Only process starting elements
|
||||||
|
if (!reader.IsStartElement())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
switch (reader.Name)
|
||||||
|
{
|
||||||
|
case "game":
|
||||||
|
var game = ParseGame(reader);
|
||||||
|
if (game is not null)
|
||||||
|
games.Add(game);
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
if (Debug) Console.Error.WriteLine($"Element '{reader.Name}' is not recognized");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (games.Count > 0)
|
||||||
|
obj.Game = [.. games];
|
||||||
|
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
#region Items
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Parse from an XmlTextReader into a Archive
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="reader">XmlTextReader to read from</param>
|
||||||
|
/// <returns>Filled Archive on success, null on error</returns>
|
||||||
|
public Archive ParseArchive(XmlTextReader reader)
|
||||||
|
{
|
||||||
|
var obj = new Archive();
|
||||||
|
|
||||||
|
obj.Number = reader.GetAttribute("number");
|
||||||
|
obj.Clone = reader.GetAttribute("clone");
|
||||||
|
obj.RegParent = reader.GetAttribute("regparent");
|
||||||
|
obj.MergeOf = reader.GetAttribute("mergeof");
|
||||||
|
obj.MergeName = reader.GetAttribute("mergename");
|
||||||
|
obj.Name = reader.GetAttribute("name");
|
||||||
|
obj.NameAlt = reader.GetAttribute("name_alt");
|
||||||
|
obj.Region = reader.GetAttribute("region");
|
||||||
|
obj.Languages = reader.GetAttribute("languages");
|
||||||
|
obj.ShowLang = reader.GetAttribute("showlang");
|
||||||
|
obj.LangChecked = reader.GetAttribute("langchecked");
|
||||||
|
obj.Version1 = reader.GetAttribute("version1");
|
||||||
|
obj.Version2 = reader.GetAttribute("version2");
|
||||||
|
obj.DevStatus = reader.GetAttribute("devstatus");
|
||||||
|
obj.Additional = reader.GetAttribute("additional");
|
||||||
|
obj.Special1 = reader.GetAttribute("special1");
|
||||||
|
obj.Special2 = reader.GetAttribute("special2");
|
||||||
|
obj.Alt = reader.GetAttribute("alt");
|
||||||
|
obj.GameId1 = reader.GetAttribute("gameid1");
|
||||||
|
obj.GameId2 = reader.GetAttribute("gameid2");
|
||||||
|
obj.Description = reader.GetAttribute("description");
|
||||||
|
obj.Bios = reader.GetAttribute("bios");
|
||||||
|
obj.Licensed = reader.GetAttribute("licensed");
|
||||||
|
obj.Pirate = reader.GetAttribute("pirate");
|
||||||
|
obj.Physical = reader.GetAttribute("physical");
|
||||||
|
obj.Complete = reader.GetAttribute("complete");
|
||||||
|
obj.Adult = reader.GetAttribute("adult");
|
||||||
|
obj.Dat = reader.GetAttribute("dat");
|
||||||
|
obj.Listed = reader.GetAttribute("listed");
|
||||||
|
obj.Private = reader.GetAttribute("private");
|
||||||
|
obj.StickyNote = reader.GetAttribute("sticky_note");
|
||||||
|
obj.DatterNote = reader.GetAttribute("datter_note");
|
||||||
|
obj.Categories = reader.GetAttribute("categories");
|
||||||
|
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Parse from an XmlTextReader into a File
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="reader">XmlTextReader to read from</param>
|
||||||
|
/// <returns>Filled File on success, null on error</returns>
|
||||||
|
public Data.Models.NoIntroDatabase.File ParseFile(XmlTextReader reader)
|
||||||
|
{
|
||||||
|
var obj = new Data.Models.NoIntroDatabase.File();
|
||||||
|
|
||||||
|
obj.Id = reader.GetAttribute("id");
|
||||||
|
obj.AppendToSourceId = reader.GetAttribute("append_to_source_id");
|
||||||
|
obj.ForceName = reader.GetAttribute("forcename");
|
||||||
|
obj.ForceSceneName = reader.GetAttribute("forcescenename");
|
||||||
|
obj.EmptyDir = reader.GetAttribute("emptydir");
|
||||||
|
obj.Extension = reader.GetAttribute("extension");
|
||||||
|
obj.Item = reader.GetAttribute("item");
|
||||||
|
obj.Date = reader.GetAttribute("date");
|
||||||
|
obj.Format = reader.GetAttribute("format");
|
||||||
|
obj.Note = reader.GetAttribute("note");
|
||||||
|
obj.Filter = reader.GetAttribute("filter");
|
||||||
|
obj.Version = reader.GetAttribute("version");
|
||||||
|
obj.UpdateType = reader.GetAttribute("update_type");
|
||||||
|
obj.Size = reader.GetAttribute("size");
|
||||||
|
obj.CRC32 = reader.GetAttribute("crc32");
|
||||||
|
obj.MD5 = reader.GetAttribute("md5");
|
||||||
|
obj.SHA1 = reader.GetAttribute("sha1");
|
||||||
|
obj.SHA256 = reader.GetAttribute("sha256");
|
||||||
|
obj.Serial = reader.GetAttribute("serial");
|
||||||
|
obj.Header = reader.GetAttribute("header");
|
||||||
|
obj.Bad = reader.GetAttribute("bad");
|
||||||
|
obj.MIA = reader.GetAttribute("mia");
|
||||||
|
obj.Unique = reader.GetAttribute("unique");
|
||||||
|
obj.MergeName = reader.GetAttribute("mergename");
|
||||||
|
obj.UniqueAttachment = reader.GetAttribute("unique_attachment");
|
||||||
|
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Parse from an XmlTextReader into a Game
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="reader">XmlTextReader to read from</param>
|
||||||
|
/// <returns>Filled Game on success, null on error</returns>
|
||||||
|
public Game ParseGame(XmlTextReader reader)
|
||||||
|
{
|
||||||
|
var obj = new Game();
|
||||||
|
|
||||||
|
obj.Name = reader.GetAttribute("name");
|
||||||
|
|
||||||
|
List<Media> medias = [];
|
||||||
|
List<Source> sources = [];
|
||||||
|
List<Release> releases = [];
|
||||||
|
|
||||||
|
reader.Read();
|
||||||
|
while (!reader.EOF)
|
||||||
|
{
|
||||||
|
// An ending element means exit
|
||||||
|
if (reader.NodeType == XmlNodeType.EndElement)
|
||||||
|
break;
|
||||||
|
|
||||||
|
// Only process starting elements
|
||||||
|
if (!reader.IsStartElement())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
switch (reader.Name)
|
||||||
|
{
|
||||||
|
case "archive":
|
||||||
|
if (obj.Archive is not null && Debug)
|
||||||
|
Console.WriteLine($"'{reader.Name}' element already found, overwriting");
|
||||||
|
|
||||||
|
obj.Archive = ParseArchive(reader);
|
||||||
|
reader.Skip();
|
||||||
|
break;
|
||||||
|
case "media":
|
||||||
|
var media = ParseMedia(reader);
|
||||||
|
if (media is not null)
|
||||||
|
medias.Add(media);
|
||||||
|
|
||||||
|
reader.Skip();
|
||||||
|
break;
|
||||||
|
case "source":
|
||||||
|
var source = ParseSource(reader);
|
||||||
|
if (source is not null)
|
||||||
|
sources.Add(source);
|
||||||
|
|
||||||
|
reader.Skip();
|
||||||
|
break;
|
||||||
|
case "release":
|
||||||
|
var release = ParseRelease(reader);
|
||||||
|
if (release is not null)
|
||||||
|
releases.Add(release);
|
||||||
|
|
||||||
|
reader.Skip();
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
if (Debug) Console.Error.WriteLine($"Element '{reader.Name}' is not recognized");
|
||||||
|
reader.Skip();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (medias.Count > 0)
|
||||||
|
obj.Media = [.. medias];
|
||||||
|
if (sources.Count > 0)
|
||||||
|
obj.Source = [.. sources];
|
||||||
|
if (releases.Count > 0)
|
||||||
|
obj.Release = [.. releases];
|
||||||
|
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Parse from an XmlTextReader into a Media
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="reader">XmlTextReader to read from</param>
|
||||||
|
/// <returns>Filled Media on success, null on error</returns>
|
||||||
|
public Media ParseMedia(XmlTextReader reader)
|
||||||
|
{
|
||||||
|
var obj = new Media();
|
||||||
|
|
||||||
|
// This item is empty
|
||||||
|
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Parse from an XmlTextReader into a Release
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="reader">XmlTextReader to read from</param>
|
||||||
|
/// <returns>Filled Release on success, null on error</returns>
|
||||||
|
public Release ParseRelease(XmlTextReader reader)
|
||||||
|
{
|
||||||
|
var obj = new Release();
|
||||||
|
|
||||||
|
List<Data.Models.NoIntroDatabase.File> files = [];
|
||||||
|
|
||||||
|
reader.Read();
|
||||||
|
while (!reader.EOF)
|
||||||
|
{
|
||||||
|
// An ending element means exit
|
||||||
|
if (reader.NodeType == XmlNodeType.EndElement)
|
||||||
|
break;
|
||||||
|
|
||||||
|
// Only process starting elements
|
||||||
|
if (!reader.IsStartElement())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
switch (reader.Name)
|
||||||
|
{
|
||||||
|
case "details":
|
||||||
|
if (obj.Details is not null && Debug)
|
||||||
|
Console.WriteLine($"'{reader.Name}' element already found, overwriting");
|
||||||
|
|
||||||
|
obj.Details = ParseReleaseDetails(reader);
|
||||||
|
reader.Skip();
|
||||||
|
break;
|
||||||
|
case "serials":
|
||||||
|
if (obj.Serials is not null && Debug)
|
||||||
|
Console.WriteLine($"'{reader.Name}' element already found, overwriting");
|
||||||
|
|
||||||
|
obj.Serials = ParseSerials(reader);
|
||||||
|
reader.Skip();
|
||||||
|
break;
|
||||||
|
case "file":
|
||||||
|
var file = ParseFile(reader);
|
||||||
|
if (file is not null)
|
||||||
|
files.Add(file);
|
||||||
|
|
||||||
|
reader.Skip();
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
if (Debug) Console.Error.WriteLine($"Element '{reader.Name}' is not recognized");
|
||||||
|
reader.Skip();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (files.Count > 0)
|
||||||
|
obj.File = [.. files];
|
||||||
|
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Parse from an XmlTextReader into a ReleaseDetails
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="reader">XmlTextReader to read from</param>
|
||||||
|
/// <returns>Filled ReleaseDetails on success, null on error</returns>
|
||||||
|
public ReleaseDetails ParseReleaseDetails(XmlTextReader reader)
|
||||||
|
{
|
||||||
|
var obj = new ReleaseDetails();
|
||||||
|
|
||||||
|
obj.Id = reader.GetAttribute("id");
|
||||||
|
obj.AppendToNumber = reader.GetAttribute("append_to_number");
|
||||||
|
obj.Date = reader.GetAttribute("date");
|
||||||
|
obj.OriginalFormat = reader.GetAttribute("originalformat");
|
||||||
|
obj.Group = reader.GetAttribute("group");
|
||||||
|
obj.DirName = reader.GetAttribute("dirname");
|
||||||
|
obj.NfoName = reader.GetAttribute("nfoname");
|
||||||
|
obj.NfoSize = reader.GetAttribute("nfosize");
|
||||||
|
obj.NfoCRC = reader.GetAttribute("nfocrc");
|
||||||
|
obj.ArchiveName = reader.GetAttribute("archivename");
|
||||||
|
obj.RomInfo = reader.GetAttribute("rominfo");
|
||||||
|
obj.Category = reader.GetAttribute("category");
|
||||||
|
obj.Comment = reader.GetAttribute("comment");
|
||||||
|
obj.Tool = reader.GetAttribute("tool");
|
||||||
|
obj.Region = reader.GetAttribute("region");
|
||||||
|
obj.Origin = reader.GetAttribute("origin");
|
||||||
|
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Parse from an XmlTextReader into a Serials
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="reader">XmlTextReader to read from</param>
|
||||||
|
/// <returns>Filled Serials on success, null on error</returns>
|
||||||
|
public Serials ParseSerials(XmlTextReader reader)
|
||||||
|
{
|
||||||
|
var obj = new Serials();
|
||||||
|
|
||||||
|
obj.MediaSerial1 = reader.GetAttribute("media_serial1");
|
||||||
|
obj.MediaSerial2 = reader.GetAttribute("media_serial2");
|
||||||
|
obj.MediaSerial3 = reader.GetAttribute("media_serial3");
|
||||||
|
obj.PCBSerial = reader.GetAttribute("pcb_serial");
|
||||||
|
obj.RomChipSerial1 = reader.GetAttribute("romchip_serial1");
|
||||||
|
obj.RomChipSerial2 = reader.GetAttribute("romchip_serial2");
|
||||||
|
obj.LockoutSerial = reader.GetAttribute("lockout_serial");
|
||||||
|
obj.SaveChipSerial = reader.GetAttribute("savechip_serial");
|
||||||
|
obj.ChipSerial = reader.GetAttribute("chip_serial");
|
||||||
|
obj.BoxSerial = reader.GetAttribute("box_serial");
|
||||||
|
obj.MediaStamp = reader.GetAttribute("mediastamp");
|
||||||
|
obj.BoxBarcode = reader.GetAttribute("box_barcode");
|
||||||
|
obj.DigitalSerial1 = reader.GetAttribute("digital_serial1");
|
||||||
|
obj.DigitalSerial2 = reader.GetAttribute("digital_serial2");
|
||||||
|
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Parse from an XmlTextReader into a Source
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="reader">XmlTextReader to read from</param>
|
||||||
|
/// <returns>Filled Source on success, null on error</returns>
|
||||||
|
public Source ParseSource(XmlTextReader reader)
|
||||||
|
{
|
||||||
|
var obj = new Source();
|
||||||
|
|
||||||
|
List<Data.Models.NoIntroDatabase.File> files = [];
|
||||||
|
|
||||||
|
reader.Read();
|
||||||
|
while (!reader.EOF)
|
||||||
|
{
|
||||||
|
// An ending element means exit
|
||||||
|
if (reader.NodeType == XmlNodeType.EndElement)
|
||||||
|
break;
|
||||||
|
|
||||||
|
// Only process starting elements
|
||||||
|
if (!reader.IsStartElement())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
switch (reader.Name)
|
||||||
|
{
|
||||||
|
case "details":
|
||||||
|
if (obj.Details is not null && Debug)
|
||||||
|
Console.WriteLine($"'{reader.Name}' element already found, overwriting");
|
||||||
|
|
||||||
|
obj.Details = ParseSourceDetails(reader);
|
||||||
|
reader.Skip();
|
||||||
|
break;
|
||||||
|
case "serials":
|
||||||
|
if (obj.Serials is not null && Debug)
|
||||||
|
Console.WriteLine($"'{reader.Name}' element already found, overwriting");
|
||||||
|
|
||||||
|
obj.Serials = ParseSerials(reader);
|
||||||
|
reader.Skip();
|
||||||
|
break;
|
||||||
|
case "file":
|
||||||
|
var file = ParseFile(reader);
|
||||||
|
if (file is not null)
|
||||||
|
files.Add(file);
|
||||||
|
|
||||||
|
reader.Skip();
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
if (Debug) Console.Error.WriteLine($"Element '{reader.Name}' is not recognized");
|
||||||
|
reader.Skip();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (files.Count > 0)
|
||||||
|
obj.File = [.. files];
|
||||||
|
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Parse from an XmlTextReader into a SourceDetails
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="reader">XmlTextReader to read from</param>
|
||||||
|
/// <returns>Filled SourceDetails on success, null on error</returns>
|
||||||
|
public SourceDetails ParseSourceDetails(XmlTextReader reader)
|
||||||
|
{
|
||||||
|
var obj = new SourceDetails();
|
||||||
|
|
||||||
|
obj.Id = reader.GetAttribute("id");
|
||||||
|
obj.AppendToNumber = reader.GetAttribute("append_to_number");
|
||||||
|
obj.Section = reader.GetAttribute("section");
|
||||||
|
obj.RomInfo = reader.GetAttribute("rominfo");
|
||||||
|
obj.DumpDate = reader.GetAttribute("d_date");
|
||||||
|
obj.DumpDateInfo = reader.GetAttribute("d_date_info");
|
||||||
|
obj.ReleaseDate = reader.GetAttribute("r_date");
|
||||||
|
obj.ReleaseDateInfo = reader.GetAttribute("r_date_info");
|
||||||
|
obj.Dumper = reader.GetAttribute("dumper");
|
||||||
|
obj.Project = reader.GetAttribute("project");
|
||||||
|
obj.OriginalFormat = reader.GetAttribute("originalformat");
|
||||||
|
obj.Nodump = reader.GetAttribute("nodump");
|
||||||
|
obj.Tool = reader.GetAttribute("tool");
|
||||||
|
obj.Origin = reader.GetAttribute("origin");
|
||||||
|
obj.Comment1 = reader.GetAttribute("comment1");
|
||||||
|
obj.Comment2 = reader.GetAttribute("comment2");
|
||||||
|
obj.Link1 = reader.GetAttribute("link1");
|
||||||
|
obj.Link1Public = reader.GetAttribute("link1_public");
|
||||||
|
obj.Link2 = reader.GetAttribute("link2");
|
||||||
|
obj.Link2Public = reader.GetAttribute("link2_public");
|
||||||
|
obj.Link3 = reader.GetAttribute("link3");
|
||||||
|
obj.Link3Public = reader.GetAttribute("link3_public");
|
||||||
|
obj.Region = reader.GetAttribute("region");
|
||||||
|
obj.MediaTitle = reader.GetAttribute("media_title");
|
||||||
|
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
using System.IO;
|
||||||
|
using Xunit;
|
||||||
|
|
||||||
|
namespace SabreTools.Serialization.Writers.Test
|
||||||
|
{
|
||||||
|
public class NoIntroDatabaseTests
|
||||||
|
{
|
||||||
|
[Fact]
|
||||||
|
public void SerializeArray_Null_Null()
|
||||||
|
{
|
||||||
|
var serializer = new NoIntroDatabase();
|
||||||
|
byte[]? actual = serializer.SerializeArray(null);
|
||||||
|
Assert.Null(actual);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void SerializeStream_Null_Null()
|
||||||
|
{
|
||||||
|
var serializer = new NoIntroDatabase();
|
||||||
|
Stream? actual = serializer.SerializeStream(null);
|
||||||
|
Assert.Null(actual);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
350
SabreTools.Serialization.Writers/NoIntroDatabase.cs
Normal file
350
SabreTools.Serialization.Writers/NoIntroDatabase.cs
Normal file
@@ -0,0 +1,350 @@
|
|||||||
|
using System.IO;
|
||||||
|
using System.Text;
|
||||||
|
using System.Xml;
|
||||||
|
using SabreTools.Data.Models.NoIntroDatabase;
|
||||||
|
using SabreTools.IO.Extensions;
|
||||||
|
using SabreTools.Text.Extensions;
|
||||||
|
|
||||||
|
namespace SabreTools.Serialization.Writers
|
||||||
|
{
|
||||||
|
public class NoIntroDatabase : BaseBinaryWriter<Datafile>
|
||||||
|
{
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public override Stream? SerializeStream(Datafile? obj)
|
||||||
|
{
|
||||||
|
// If the metadata file is null
|
||||||
|
if (obj is null)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
// Setup the writer and output
|
||||||
|
var stream = new MemoryStream();
|
||||||
|
var writer = new XmlTextWriter(stream, Encoding.UTF8)
|
||||||
|
{
|
||||||
|
Formatting = Formatting.Indented,
|
||||||
|
IndentChar = '\t',
|
||||||
|
Indentation = 1
|
||||||
|
};
|
||||||
|
writer.Settings?.CheckCharacters = false;
|
||||||
|
writer.Settings?.NewLineChars = "\n";
|
||||||
|
|
||||||
|
// Write document start
|
||||||
|
writer.WriteStartDocument();
|
||||||
|
|
||||||
|
// Write the SoftwareDb, if it exists
|
||||||
|
WriteDatafile(obj, writer);
|
||||||
|
writer.Flush();
|
||||||
|
|
||||||
|
// Return the stream
|
||||||
|
stream.SeekIfPossible(0, SeekOrigin.Begin);
|
||||||
|
return stream;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Write a Datafile to an XmlTextWriter
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="obj">Datafile to write</param>
|
||||||
|
/// <param name="writer">XmlTextReader to write to</param>
|
||||||
|
private static void WriteDatafile(Datafile obj, XmlTextWriter writer)
|
||||||
|
{
|
||||||
|
writer.WriteStartElement("datafile");
|
||||||
|
|
||||||
|
if (obj.Game is not null && obj.Game.Length > 0)
|
||||||
|
{
|
||||||
|
foreach (var game in obj.Game)
|
||||||
|
{
|
||||||
|
WriteGame(game, writer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
writer.WriteEndElement();
|
||||||
|
}
|
||||||
|
|
||||||
|
#region Items
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Write a Archive to an XmlTextWriter
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="obj">Archive to write</param>
|
||||||
|
/// <param name="writer">XmlTextReader to write to</param>
|
||||||
|
private static void WriteArchive(Archive obj, XmlTextWriter writer)
|
||||||
|
{
|
||||||
|
writer.WriteStartElement("archive");
|
||||||
|
|
||||||
|
writer.WriteOptionalAttributeString("number", obj.Number);
|
||||||
|
writer.WriteOptionalAttributeString("clone", obj.Clone);
|
||||||
|
writer.WriteOptionalAttributeString("regparent", obj.RegParent);
|
||||||
|
writer.WriteOptionalAttributeString("mergeof", obj.MergeOf);
|
||||||
|
writer.WriteOptionalAttributeString("mergename", obj.MergeName);
|
||||||
|
writer.WriteOptionalAttributeString("name", obj.Name);
|
||||||
|
writer.WriteOptionalAttributeString("name_alt", obj.NameAlt);
|
||||||
|
writer.WriteOptionalAttributeString("region", obj.Region);
|
||||||
|
writer.WriteOptionalAttributeString("languages", obj.Languages);
|
||||||
|
writer.WriteOptionalAttributeString("showlang", obj.ShowLang);
|
||||||
|
writer.WriteOptionalAttributeString("langchecked", obj.LangChecked);
|
||||||
|
writer.WriteOptionalAttributeString("version1", obj.Version1);
|
||||||
|
writer.WriteOptionalAttributeString("version2", obj.Version2);
|
||||||
|
writer.WriteOptionalAttributeString("devstatus", obj.DevStatus);
|
||||||
|
writer.WriteOptionalAttributeString("additional", obj.Additional);
|
||||||
|
writer.WriteOptionalAttributeString("special1", obj.Special1);
|
||||||
|
writer.WriteOptionalAttributeString("special2", obj.Special2);
|
||||||
|
writer.WriteOptionalAttributeString("alt", obj.Alt);
|
||||||
|
writer.WriteOptionalAttributeString("gameid1", obj.GameId1);
|
||||||
|
writer.WriteOptionalAttributeString("gameid2", obj.GameId2);
|
||||||
|
writer.WriteOptionalAttributeString("description", obj.Description);
|
||||||
|
writer.WriteOptionalAttributeString("bios", obj.Bios);
|
||||||
|
writer.WriteOptionalAttributeString("licensed", obj.Licensed);
|
||||||
|
writer.WriteOptionalAttributeString("pirate", obj.Pirate);
|
||||||
|
writer.WriteOptionalAttributeString("physical", obj.Physical);
|
||||||
|
writer.WriteOptionalAttributeString("complete", obj.Complete);
|
||||||
|
writer.WriteOptionalAttributeString("adult", obj.Adult);
|
||||||
|
writer.WriteOptionalAttributeString("dat", obj.Dat);
|
||||||
|
writer.WriteOptionalAttributeString("listed", obj.Listed);
|
||||||
|
writer.WriteOptionalAttributeString("private", obj.Private);
|
||||||
|
writer.WriteOptionalAttributeString("sticky_note", obj.StickyNote);
|
||||||
|
writer.WriteOptionalAttributeString("datter_note", obj.DatterNote);
|
||||||
|
writer.WriteOptionalAttributeString("categories", obj.Categories);
|
||||||
|
|
||||||
|
writer.WriteEndElement();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Write a File to an XmlTextWriter
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="obj">File to write</param>
|
||||||
|
/// <param name="writer">XmlTextReader to write to</param>
|
||||||
|
private static void WriteFile(Data.Models.NoIntroDatabase.File obj, XmlTextWriter writer)
|
||||||
|
{
|
||||||
|
writer.WriteStartElement("file");
|
||||||
|
|
||||||
|
writer.WriteOptionalAttributeString("id", obj.Id);
|
||||||
|
writer.WriteOptionalAttributeString("append_to_source_id", obj.AppendToSourceId);
|
||||||
|
writer.WriteOptionalAttributeString("forcename", obj.ForceName);
|
||||||
|
writer.WriteOptionalAttributeString("forcescenename", obj.ForceSceneName);
|
||||||
|
writer.WriteOptionalAttributeString("emptydir", obj.EmptyDir);
|
||||||
|
writer.WriteOptionalAttributeString("extension", obj.Extension);
|
||||||
|
writer.WriteOptionalAttributeString("item", obj.Item);
|
||||||
|
writer.WriteOptionalAttributeString("date", obj.Date);
|
||||||
|
writer.WriteOptionalAttributeString("format", obj.Format);
|
||||||
|
writer.WriteOptionalAttributeString("note", obj.Note);
|
||||||
|
writer.WriteOptionalAttributeString("filter", obj.Filter);
|
||||||
|
writer.WriteOptionalAttributeString("version", obj.Version);
|
||||||
|
writer.WriteOptionalAttributeString("update_type", obj.UpdateType);
|
||||||
|
writer.WriteOptionalAttributeString("size", obj.Size);
|
||||||
|
writer.WriteOptionalAttributeString("crc32", obj.CRC32);
|
||||||
|
writer.WriteOptionalAttributeString("md5", obj.MD5);
|
||||||
|
writer.WriteOptionalAttributeString("sha1", obj.SHA1);
|
||||||
|
writer.WriteOptionalAttributeString("sha256", obj.SHA256);
|
||||||
|
writer.WriteOptionalAttributeString("serial", obj.Serial);
|
||||||
|
writer.WriteOptionalAttributeString("header", obj.Header);
|
||||||
|
writer.WriteOptionalAttributeString("bad", obj.Bad);
|
||||||
|
writer.WriteOptionalAttributeString("mia", obj.MIA);
|
||||||
|
writer.WriteOptionalAttributeString("unique", obj.Unique);
|
||||||
|
writer.WriteOptionalAttributeString("mergename", obj.MergeName);
|
||||||
|
writer.WriteOptionalAttributeString("unique_attachment", obj.UniqueAttachment);
|
||||||
|
|
||||||
|
writer.WriteEndElement();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Write a Game to an XmlTextWriter
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="obj">Game to write</param>
|
||||||
|
/// <param name="writer">XmlTextReader to write to</param>
|
||||||
|
private static void WriteGame(Game obj, XmlTextWriter writer)
|
||||||
|
{
|
||||||
|
writer.WriteStartElement("game");
|
||||||
|
|
||||||
|
writer.WriteOptionalAttributeString("name", obj.Name);
|
||||||
|
|
||||||
|
if (obj.Archive is not null)
|
||||||
|
WriteArchive(obj.Archive, writer);
|
||||||
|
|
||||||
|
if (obj.Media is not null && obj.Media.Length > 0)
|
||||||
|
{
|
||||||
|
foreach (var media in obj.Media)
|
||||||
|
{
|
||||||
|
WriteMedia(media, writer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (obj.Source is not null && obj.Source.Length > 0)
|
||||||
|
{
|
||||||
|
foreach (var source in obj.Source)
|
||||||
|
{
|
||||||
|
WriteSource(source, writer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (obj.Release is not null && obj.Release.Length > 0)
|
||||||
|
{
|
||||||
|
foreach (var release in obj.Release)
|
||||||
|
{
|
||||||
|
WriteRelease(release, writer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
writer.WriteEndElement();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Write a Media to an XmlTextWriter
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="obj">Media to write</param>
|
||||||
|
/// <param name="writer">XmlTextReader to write to</param>
|
||||||
|
private static void WriteMedia(Media obj, XmlTextWriter writer)
|
||||||
|
{
|
||||||
|
writer.WriteStartElement("media");
|
||||||
|
|
||||||
|
// This item is empty
|
||||||
|
|
||||||
|
writer.WriteEndElement();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Write a Release to an XmlTextWriter
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="obj">Release to write</param>
|
||||||
|
/// <param name="writer">XmlTextReader to write to</param>
|
||||||
|
private static void WriteRelease(Release obj, XmlTextWriter writer)
|
||||||
|
{
|
||||||
|
writer.WriteStartElement("release");
|
||||||
|
|
||||||
|
if (obj.Details is not null)
|
||||||
|
WriteReleaseDetails(obj.Details, writer);
|
||||||
|
|
||||||
|
if (obj.Serials is not null)
|
||||||
|
WriteSerials(obj.Serials, writer);
|
||||||
|
|
||||||
|
if (obj.File is not null && obj.File.Length > 0)
|
||||||
|
{
|
||||||
|
foreach (var file in obj.File)
|
||||||
|
{
|
||||||
|
WriteFile(file, writer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
writer.WriteEndElement();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Write a ReleaseDetails to an XmlTextWriter
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="obj">ReleaseDetails to write</param>
|
||||||
|
/// <param name="writer">XmlTextReader to write to</param>
|
||||||
|
private static void WriteReleaseDetails(ReleaseDetails obj, XmlTextWriter writer)
|
||||||
|
{
|
||||||
|
writer.WriteStartElement("details");
|
||||||
|
|
||||||
|
writer.WriteOptionalAttributeString("id", obj.Id);
|
||||||
|
writer.WriteOptionalAttributeString("append_to_number", obj.AppendToNumber);
|
||||||
|
writer.WriteOptionalAttributeString("date", obj.Date);
|
||||||
|
writer.WriteOptionalAttributeString("originalformat", obj.OriginalFormat);
|
||||||
|
writer.WriteOptionalAttributeString("group", obj.Group);
|
||||||
|
writer.WriteOptionalAttributeString("dirname", obj.DirName);
|
||||||
|
writer.WriteOptionalAttributeString("nfoname", obj.NfoName);
|
||||||
|
writer.WriteOptionalAttributeString("nfosize", obj.NfoSize);
|
||||||
|
writer.WriteOptionalAttributeString("nfocrc", obj.NfoCRC);
|
||||||
|
writer.WriteOptionalAttributeString("archivename", obj.ArchiveName);
|
||||||
|
writer.WriteOptionalAttributeString("rominfo", obj.RomInfo);
|
||||||
|
writer.WriteOptionalAttributeString("category", obj.Category);
|
||||||
|
writer.WriteOptionalAttributeString("comment", obj.Comment);
|
||||||
|
writer.WriteOptionalAttributeString("tool", obj.Tool);
|
||||||
|
writer.WriteOptionalAttributeString("region", obj.Region);
|
||||||
|
writer.WriteOptionalAttributeString("origin", obj.Origin);
|
||||||
|
|
||||||
|
writer.WriteEndElement();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Write a Serials to an XmlTextWriter
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="obj">Serials to write</param>
|
||||||
|
/// <param name="writer">XmlTextReader to write to</param>
|
||||||
|
private static void WriteSerials(Serials obj, XmlTextWriter writer)
|
||||||
|
{
|
||||||
|
writer.WriteStartElement("serials");
|
||||||
|
|
||||||
|
writer.WriteOptionalAttributeString("media_serial1", obj.MediaSerial1);
|
||||||
|
writer.WriteOptionalAttributeString("media_serial2", obj.MediaSerial2);
|
||||||
|
writer.WriteOptionalAttributeString("media_serial3", obj.MediaSerial3);
|
||||||
|
writer.WriteOptionalAttributeString("pcb_serial", obj.PCBSerial);
|
||||||
|
writer.WriteOptionalAttributeString("romchip_serial1", obj.RomChipSerial1);
|
||||||
|
writer.WriteOptionalAttributeString("romchip_serial2", obj.RomChipSerial2);
|
||||||
|
writer.WriteOptionalAttributeString("lockout_serial", obj.LockoutSerial);
|
||||||
|
writer.WriteOptionalAttributeString("savechip_serial", obj.SaveChipSerial);
|
||||||
|
writer.WriteOptionalAttributeString("chip_serial", obj.ChipSerial);
|
||||||
|
writer.WriteOptionalAttributeString("box_serial", obj.BoxSerial);
|
||||||
|
writer.WriteOptionalAttributeString("mediastamp", obj.MediaStamp);
|
||||||
|
writer.WriteOptionalAttributeString("box_barcode", obj.BoxBarcode);
|
||||||
|
writer.WriteOptionalAttributeString("digital_serial1", obj.DigitalSerial1);
|
||||||
|
writer.WriteOptionalAttributeString("digital_serial2", obj.DigitalSerial2);
|
||||||
|
|
||||||
|
writer.WriteEndElement();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Write a Source to an XmlTextWriter
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="obj">Source to write</param>
|
||||||
|
/// <param name="writer">XmlTextReader to write to</param>
|
||||||
|
private static void WriteSource(Source obj, XmlTextWriter writer)
|
||||||
|
{
|
||||||
|
writer.WriteStartElement("source");
|
||||||
|
|
||||||
|
if (obj.Details is not null)
|
||||||
|
WriteSourceDetails(obj.Details, writer);
|
||||||
|
|
||||||
|
if (obj.Serials is not null)
|
||||||
|
WriteSerials(obj.Serials, writer);
|
||||||
|
|
||||||
|
if (obj.File is not null && obj.File.Length > 0)
|
||||||
|
{
|
||||||
|
foreach (var file in obj.File)
|
||||||
|
{
|
||||||
|
WriteFile(file, writer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
writer.WriteEndElement();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Write a SourceDetails to an XmlTextWriter
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="obj">SourceDetails to write</param>
|
||||||
|
/// <param name="writer">XmlTextReader to write to</param>
|
||||||
|
private static void WriteSourceDetails(SourceDetails obj, XmlTextWriter writer)
|
||||||
|
{
|
||||||
|
writer.WriteStartElement("details");
|
||||||
|
|
||||||
|
writer.WriteOptionalAttributeString("id", obj.Id);
|
||||||
|
writer.WriteOptionalAttributeString("append_to_number", obj.AppendToNumber);
|
||||||
|
writer.WriteOptionalAttributeString("section", obj.Section);
|
||||||
|
writer.WriteOptionalAttributeString("rominfo", obj.RomInfo);
|
||||||
|
writer.WriteOptionalAttributeString("d_date", obj.DumpDate);
|
||||||
|
writer.WriteOptionalAttributeString("d_date_info", obj.DumpDateInfo);
|
||||||
|
writer.WriteOptionalAttributeString("r_date", obj.ReleaseDate);
|
||||||
|
writer.WriteOptionalAttributeString("r_date_info", obj.ReleaseDateInfo);
|
||||||
|
writer.WriteOptionalAttributeString("dumper", obj.Dumper);
|
||||||
|
writer.WriteOptionalAttributeString("project", obj.Project);
|
||||||
|
writer.WriteOptionalAttributeString("originalformat", obj.OriginalFormat);
|
||||||
|
writer.WriteOptionalAttributeString("nodump", obj.Nodump);
|
||||||
|
writer.WriteOptionalAttributeString("tool", obj.Tool);
|
||||||
|
writer.WriteOptionalAttributeString("origin", obj.Origin);
|
||||||
|
writer.WriteOptionalAttributeString("comment1", obj.Comment1);
|
||||||
|
writer.WriteOptionalAttributeString("comment2", obj.Comment2);
|
||||||
|
writer.WriteOptionalAttributeString("link1", obj.Link1);
|
||||||
|
writer.WriteOptionalAttributeString("link1_public", obj.Link1Public);
|
||||||
|
writer.WriteOptionalAttributeString("link2", obj.Link2);
|
||||||
|
writer.WriteOptionalAttributeString("link2_public", obj.Link2Public);
|
||||||
|
writer.WriteOptionalAttributeString("link3", obj.Link3);
|
||||||
|
writer.WriteOptionalAttributeString("link3_public", obj.Link3Public);
|
||||||
|
writer.WriteOptionalAttributeString("region", obj.Region);
|
||||||
|
writer.WriteOptionalAttributeString("media_title", obj.MediaTitle);
|
||||||
|
|
||||||
|
writer.WriteEndElement();
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user