mirror of
https://github.com/SabreTools/SabreTools.Serialization.git
synced 2026-04-05 22:01:33 +00:00
492 lines
19 KiB
C#
492 lines
19 KiB
C#
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
|
|
}
|
|
}
|