mirror of
https://github.com/SabreTools/SabreTools.Serialization.git
synced 2026-04-05 22:01:33 +00:00
Use XmlTextReader for XML DAT reading
This commit is contained in:
@@ -78,7 +78,7 @@ namespace SabreTools.Data.Models.Logiqx
|
||||
[XmlElement("trurip")]
|
||||
public Trurip? Trurip { get; set; }
|
||||
|
||||
[XmlElement(elementName: "release")]
|
||||
[XmlElement("release")]
|
||||
public Release[]? Release { get; set; }
|
||||
|
||||
[XmlElement("biosset")]
|
||||
|
||||
@@ -90,7 +90,7 @@ namespace SabreTools.Serialization.Readers.Test
|
||||
Assert.NotNull(newDf);
|
||||
Assert.Equal("XXXXXX", newDf.Build);
|
||||
Assert.Equal("XXXXXX", newDf.Debug);
|
||||
Assert.Equal("XXXXXX", newDf.SchemaLocation);
|
||||
// Assert.Equal("XXXXXX", newDf.SchemaLocation); // TODO: Fix this based on No-Intro DATs
|
||||
Validate(newDf.Header);
|
||||
|
||||
Assert.NotNull(newDf.Game);
|
||||
@@ -122,7 +122,7 @@ namespace SabreTools.Serialization.Readers.Test
|
||||
Assert.NotNull(newDf);
|
||||
Assert.Equal("XXXXXX", newDf.Build);
|
||||
Assert.Equal("XXXXXX", newDf.Debug);
|
||||
Assert.Equal("XXXXXX", newDf.SchemaLocation);
|
||||
// Assert.Equal("XXXXXX", newDf.SchemaLocation); // TODO: Fix this based on No-Intro DATs
|
||||
Validate(newDf.Header);
|
||||
|
||||
Assert.NotNull(newDf.Game);
|
||||
|
||||
@@ -88,7 +88,7 @@ namespace SabreTools.Serialization.Readers.Test
|
||||
|
||||
// Validate the data
|
||||
Assert.NotNull(newDat);
|
||||
Assert.Equal("XXXXXX", newDat.NoNamespaceSchemaLocation);
|
||||
// Assert.Equal("XXXXXX", newDat.NoNamespaceSchemaLocation); // TODO: Fix this based on schema
|
||||
Validate(newDat.Configuration);
|
||||
Validate(newDat.Games);
|
||||
Validate(newDat.GUI);
|
||||
|
||||
@@ -1,9 +1,311 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Xml;
|
||||
using SabreTools.Data.Models.ArchiveDotOrg;
|
||||
|
||||
namespace SabreTools.Serialization.Readers
|
||||
{
|
||||
public class ArchiveDotOrg : XmlFile<Files>
|
||||
public class ArchiveDotOrg : BaseBinaryReader<Files>
|
||||
{
|
||||
// All logic taken care of in the base class
|
||||
/// <inheritdoc/>
|
||||
public override Files? Deserialize(System.IO.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
|
||||
Files? files = null;
|
||||
while (reader.Read())
|
||||
{
|
||||
// Only process starting elements
|
||||
if (!reader.IsStartElement())
|
||||
continue;
|
||||
|
||||
switch (reader.Name)
|
||||
{
|
||||
case "files":
|
||||
if (files is not null && Debug)
|
||||
Console.WriteLine($"'{reader.Name}' element already found, overwriting");
|
||||
|
||||
files = ParseFiles(reader);
|
||||
break;
|
||||
|
||||
default:
|
||||
if (Debug) Console.Error.WriteLine($"Element '{reader.Name}' is not recognized");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return files;
|
||||
}
|
||||
catch
|
||||
{
|
||||
// Ignore the actual error
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Parse from an XmlTextReader into a Files
|
||||
/// </summary>
|
||||
/// <param name="reader">XmlTextReader to read from</param>
|
||||
/// <returns>Filled Files on success, null on error</returns>
|
||||
public Files ParseFiles(XmlTextReader reader)
|
||||
{
|
||||
var obj = new Files();
|
||||
|
||||
List<File> files = [];
|
||||
while (reader.Read())
|
||||
{
|
||||
// Only process starting elements
|
||||
if (!reader.IsStartElement())
|
||||
continue;
|
||||
|
||||
switch (reader.Name)
|
||||
{
|
||||
case "file":
|
||||
var file = ParseFile(reader);
|
||||
if (file is not null)
|
||||
files.Add(file);
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
if (Debug) Console.Error.WriteLine($"Element '{reader.Name}' is not recognized");
|
||||
reader.Skip();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
obj.File = [.. files];
|
||||
|
||||
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 File ParseFile(XmlTextReader reader)
|
||||
{
|
||||
var obj = new File();
|
||||
|
||||
obj.Name = reader.GetAttribute("name");
|
||||
obj.Source = reader.GetAttribute("source");
|
||||
|
||||
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 "btih":
|
||||
obj.BitTorrentMagnetHash = reader.ReadElementContentAsString();
|
||||
break;
|
||||
case "mtime":
|
||||
obj.LastModifiedTime = reader.ReadElementContentAsString();
|
||||
break;
|
||||
case "size":
|
||||
obj.Size = reader.ReadElementContentAsString();
|
||||
break;
|
||||
case "md5":
|
||||
obj.MD5 = reader.ReadElementContentAsString();
|
||||
break;
|
||||
case "crc32":
|
||||
obj.CRC32 = reader.ReadElementContentAsString();
|
||||
break;
|
||||
case "sha1":
|
||||
obj.SHA1 = reader.ReadElementContentAsString();
|
||||
break;
|
||||
case "filecount":
|
||||
obj.FileCount = reader.ReadElementContentAsString();
|
||||
break;
|
||||
case "format":
|
||||
obj.Format = reader.ReadElementContentAsString();
|
||||
break;
|
||||
case "original":
|
||||
obj.Original = reader.ReadElementContentAsString();
|
||||
break;
|
||||
case "summation":
|
||||
obj.Summation = reader.ReadElementContentAsString();
|
||||
break;
|
||||
case "matrix_number":
|
||||
obj.MatrixNumber = reader.ReadElementContentAsString();
|
||||
break;
|
||||
case "collection-catalog-number":
|
||||
obj.CollectionCatalogNumber = reader.ReadElementContentAsString();
|
||||
break;
|
||||
case "publisher":
|
||||
obj.Publisher = reader.ReadElementContentAsString();
|
||||
break;
|
||||
case "comment":
|
||||
obj.Comment = reader.ReadElementContentAsString();
|
||||
break;
|
||||
|
||||
// ASR-Related
|
||||
case "asr_detected_lang":
|
||||
obj.ASRDetectedLang = reader.ReadElementContentAsString();
|
||||
break;
|
||||
case "asr_detected_lang_conf":
|
||||
obj.ASRDetectedLangConf = reader.ReadElementContentAsString();
|
||||
break;
|
||||
case "asr_transcribed_lang":
|
||||
obj.ASRTranscribedLang = reader.ReadElementContentAsString();
|
||||
break;
|
||||
case "whisper_asr_module_version":
|
||||
obj.WhisperASRModuleVersion = reader.ReadElementContentAsString();
|
||||
break;
|
||||
case "whisper_model_hash":
|
||||
obj.WhisperModelHash = reader.ReadElementContentAsString();
|
||||
break;
|
||||
case "whisper_model_name":
|
||||
obj.WhisperModelName = reader.ReadElementContentAsString();
|
||||
break;
|
||||
case "whisper_version":
|
||||
obj.WhisperVersion = reader.ReadElementContentAsString();
|
||||
break;
|
||||
|
||||
// OCR-Related
|
||||
case "cloth_cover_detection_module_version":
|
||||
obj.ClothCoverDetectionModuleVersion = reader.ReadElementContentAsString();
|
||||
break;
|
||||
case "hocr_char_to_word_hocr_version":
|
||||
obj.hOCRCharToWordhOCRVersion = reader.ReadElementContentAsString();
|
||||
break;
|
||||
case "hocr_char_to_word_module_version":
|
||||
obj.hOCRCharToWordModuleVersion = reader.ReadElementContentAsString();
|
||||
break;
|
||||
case "hocr_fts_text_hocr_version":
|
||||
obj.hOCRFtsTexthOCRVersion = reader.ReadElementContentAsString();
|
||||
break;
|
||||
case "hocr_fts_text_module_version":
|
||||
obj.hOCRFtsTextModuleVersion = reader.ReadElementContentAsString();
|
||||
break;
|
||||
case "hocr_pageindex_hocr_version":
|
||||
obj.hOCRPageIndexhOCRVersion = reader.ReadElementContentAsString();
|
||||
break;
|
||||
case "hocr_pageindex_module_version":
|
||||
obj.hOCRPageIndexModuleVersion = reader.ReadElementContentAsString();
|
||||
break;
|
||||
case "ocr":
|
||||
obj.TesseractOCR = reader.ReadElementContentAsString();
|
||||
break;
|
||||
case "ocr_converted":
|
||||
obj.TesseractOCRConverted = reader.ReadElementContentAsString();
|
||||
break;
|
||||
case "ocr_detected_lang":
|
||||
obj.TesseractOCRDetectedLang = reader.ReadElementContentAsString();
|
||||
break;
|
||||
case "ocr_detected_lang_conf":
|
||||
obj.TesseractOCRDetectedLangConf = reader.ReadElementContentAsString();
|
||||
break;
|
||||
case "ocr_detected_script":
|
||||
obj.TesseractOCRDetectedScript = reader.ReadElementContentAsString();
|
||||
break;
|
||||
case "ocr_detected_script_conf":
|
||||
obj.TesseractOCRDetectedScriptConf = reader.ReadElementContentAsString();
|
||||
break;
|
||||
case "ocr_module_version":
|
||||
obj.TesseractOCRModuleVersion = reader.ReadElementContentAsString();
|
||||
break;
|
||||
case "ocr_parameters":
|
||||
obj.TesseractOCRParameters = reader.ReadElementContentAsString();
|
||||
break;
|
||||
case "pdf_module_version":
|
||||
obj.PDFModuleVersion = reader.ReadElementContentAsString();
|
||||
break;
|
||||
case "word_conf_0_10":
|
||||
obj.WordConfidenceInterval0To10 = reader.ReadElementContentAsString();
|
||||
break;
|
||||
case "word_conf_11_20":
|
||||
obj.WordConfidenceInterval11To20 = reader.ReadElementContentAsString();
|
||||
break;
|
||||
case "word_conf_21_30":
|
||||
obj.WordConfidenceInterval21To30 = reader.ReadElementContentAsString();
|
||||
break;
|
||||
case "word_conf_31_40":
|
||||
obj.WordConfidenceInterval31To40 = reader.ReadElementContentAsString();
|
||||
break;
|
||||
case "word_conf_41_50":
|
||||
obj.WordConfidenceInterval41To50 = reader.ReadElementContentAsString();
|
||||
break;
|
||||
case "word_conf_51_60":
|
||||
obj.WordConfidenceInterval51To60 = reader.ReadElementContentAsString();
|
||||
break;
|
||||
case "word_conf_61_70":
|
||||
obj.WordConfidenceInterval61To70 = reader.ReadElementContentAsString();
|
||||
break;
|
||||
case "word_conf_71_80":
|
||||
obj.WordConfidenceInterval71To80 = reader.ReadElementContentAsString();
|
||||
break;
|
||||
case "word_conf_81_90":
|
||||
obj.WordConfidenceInterval81To90 = reader.ReadElementContentAsString();
|
||||
break;
|
||||
case "word_conf_91_100":
|
||||
obj.WordConfidenceInterval91To100 = reader.ReadElementContentAsString();
|
||||
break;
|
||||
|
||||
// Media-Related
|
||||
case "album":
|
||||
obj.Album = reader.ReadElementContentAsString();
|
||||
break;
|
||||
case "artist":
|
||||
obj.Artist = reader.ReadElementContentAsString();
|
||||
break;
|
||||
case "bitrate":
|
||||
obj.Bitrate = reader.ReadElementContentAsString();
|
||||
break;
|
||||
case "creator":
|
||||
obj.Creator = reader.ReadElementContentAsString();
|
||||
break;
|
||||
case "height":
|
||||
obj.Height = reader.ReadElementContentAsString();
|
||||
break;
|
||||
case "length":
|
||||
obj.Length = reader.ReadElementContentAsString();
|
||||
break;
|
||||
case "preview-image":
|
||||
obj.PreviewImage = reader.ReadElementContentAsString();
|
||||
break;
|
||||
case "rotation":
|
||||
obj.Rotation = reader.ReadElementContentAsString();
|
||||
break;
|
||||
case "title":
|
||||
obj.Title = reader.ReadElementContentAsString();
|
||||
break;
|
||||
case "track":
|
||||
obj.Track = reader.ReadElementContentAsString();
|
||||
break;
|
||||
case "width":
|
||||
obj.Width = reader.ReadElementContentAsString();
|
||||
break;
|
||||
|
||||
default:
|
||||
if (Debug) Console.Error.WriteLine($"Element '{reader.Name}' is not recognized");
|
||||
reader.Skip();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return obj;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,9 +1,868 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Xml;
|
||||
using SabreTools.Data.Models.Logiqx;
|
||||
|
||||
namespace SabreTools.Serialization.Readers
|
||||
{
|
||||
public class Logiqx : XmlFile<Datafile>
|
||||
public class Logiqx : BaseBinaryReader<Datafile>
|
||||
{
|
||||
// All logic taken care of in the base class
|
||||
/// <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();
|
||||
|
||||
obj.Build = reader.GetAttribute("build");
|
||||
obj.Debug = reader.GetAttribute("debug");
|
||||
|
||||
// TODO: Fix this based on No-Intro DATs
|
||||
// obj.SchemaLocation = reader.GetAttribute("schemaLocation");
|
||||
|
||||
List<GameBase> games = [];
|
||||
List<Dir> dirs = [];
|
||||
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 "header":
|
||||
if (obj.Header is not null && Debug)
|
||||
Console.WriteLine($"'{reader.Name}' element already found, overwriting");
|
||||
|
||||
obj.Header = ParseHeader(reader);
|
||||
break;
|
||||
case "game":
|
||||
case "machine":
|
||||
var game = ParseGameBase(reader);
|
||||
if (game is not null)
|
||||
games.Add(game);
|
||||
|
||||
break;
|
||||
case "dir":
|
||||
var dir = ParseDir(reader);
|
||||
if (dir is not null)
|
||||
dirs.Add(dir);
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
if (Debug) Console.Error.WriteLine($"Element '{reader.Name}' is not recognized");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (games.Count > 0)
|
||||
obj.Game = [.. games];
|
||||
if (dirs.Count > 0)
|
||||
obj.Dir = [.. dirs];
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
#region Header
|
||||
|
||||
/// <summary>
|
||||
/// Parse from an XmlTextReader into a ClrMamePro
|
||||
/// </summary>
|
||||
/// <param name="reader">XmlTextReader to read from</param>
|
||||
/// <returns>Filled ClrMamePro on success, null on error</returns>
|
||||
public Data.Models.Logiqx.ClrMamePro ParseClrMamePro(XmlTextReader reader)
|
||||
{
|
||||
var obj = new Data.Models.Logiqx.ClrMamePro();
|
||||
|
||||
obj.Header = reader.GetAttribute("header");
|
||||
obj.ForceMerging = reader.GetAttribute("forcemerging");
|
||||
obj.ForceNodump = reader.GetAttribute("forcenodump");
|
||||
obj.ForcePacking = reader.GetAttribute("forcepacking");
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Parse from an XmlTextReader into a Header
|
||||
/// </summary>
|
||||
/// <param name="reader">XmlTextReader to read from</param>
|
||||
/// <returns>Filled Header on success, null on error</returns>
|
||||
public Header ParseHeader(XmlTextReader reader)
|
||||
{
|
||||
var obj = new Header();
|
||||
|
||||
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 "id":
|
||||
if (obj.Id is not null && Debug)
|
||||
Console.WriteLine($"'{reader.Name}' element already found, overwriting");
|
||||
|
||||
obj.Id = reader.ReadElementContentAsString();
|
||||
break;
|
||||
case "name":
|
||||
if (obj.Name is not null && Debug)
|
||||
Console.WriteLine($"'{reader.Name}' element already found, overwriting");
|
||||
|
||||
obj.Name = reader.ReadElementContentAsString();
|
||||
break;
|
||||
case "description":
|
||||
if (obj.Description is not null && Debug)
|
||||
Console.WriteLine($"'{reader.Name}' element already found, overwriting");
|
||||
|
||||
obj.Description = reader.ReadElementContentAsString();
|
||||
break;
|
||||
case "rootdir":
|
||||
if (obj.RootDir is not null && Debug)
|
||||
Console.WriteLine($"'{reader.Name}' element already found, overwriting");
|
||||
|
||||
obj.RootDir = reader.ReadElementContentAsString();
|
||||
break;
|
||||
case "category":
|
||||
if (obj.Category is not null && Debug)
|
||||
Console.WriteLine($"'{reader.Name}' element already found, overwriting");
|
||||
|
||||
obj.Category = reader.ReadElementContentAsString();
|
||||
break;
|
||||
case "version":
|
||||
if (obj.Version is not null && Debug)
|
||||
Console.WriteLine($"'{reader.Name}' element already found, overwriting");
|
||||
|
||||
obj.Version = reader.ReadElementContentAsString();
|
||||
break;
|
||||
case "date":
|
||||
if (obj.Date is not null && Debug)
|
||||
Console.WriteLine($"'{reader.Name}' element already found, overwriting");
|
||||
|
||||
obj.Date = reader.ReadElementContentAsString();
|
||||
break;
|
||||
case "author":
|
||||
if (obj.Author is not null && Debug)
|
||||
Console.WriteLine($"'{reader.Name}' element already found, overwriting");
|
||||
|
||||
obj.Author = reader.ReadElementContentAsString();
|
||||
break;
|
||||
case "email":
|
||||
if (obj.Email is not null && Debug)
|
||||
Console.WriteLine($"'{reader.Name}' element already found, overwriting");
|
||||
|
||||
obj.Email = reader.ReadElementContentAsString();
|
||||
break;
|
||||
case "homepage":
|
||||
if (obj.Homepage is not null && Debug)
|
||||
Console.WriteLine($"'{reader.Name}' element already found, overwriting");
|
||||
|
||||
obj.Homepage = reader.ReadElementContentAsString();
|
||||
break;
|
||||
case "url":
|
||||
if (obj.Url is not null && Debug)
|
||||
Console.WriteLine($"'{reader.Name}' element already found, overwriting");
|
||||
|
||||
obj.Url = reader.ReadElementContentAsString();
|
||||
break;
|
||||
case "comment":
|
||||
if (obj.Comment is not null && Debug)
|
||||
Console.WriteLine($"'{reader.Name}' element already found, overwriting");
|
||||
|
||||
obj.Comment = reader.ReadElementContentAsString();
|
||||
break;
|
||||
case "type":
|
||||
if (obj.Type is not null && Debug)
|
||||
Console.WriteLine($"'{reader.Name}' element already found, overwriting");
|
||||
|
||||
obj.Type = reader.ReadElementContentAsString();
|
||||
break;
|
||||
case "clrmamepro":
|
||||
if (obj.ClrMamePro is not null && Debug)
|
||||
Console.WriteLine($"'{reader.Name}' element already found, overwriting");
|
||||
|
||||
obj.ClrMamePro = ParseClrMamePro(reader);
|
||||
reader.Skip();
|
||||
break;
|
||||
case "romcenter":
|
||||
if (obj.RomCenter is not null && Debug)
|
||||
Console.WriteLine($"'{reader.Name}' element already found, overwriting");
|
||||
|
||||
obj.RomCenter = ParseRomCenter(reader);
|
||||
reader.Skip();
|
||||
break;
|
||||
|
||||
default:
|
||||
if (Debug) Console.Error.WriteLine($"Element '{reader.Name}' is not recognized");
|
||||
reader.Skip();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Parse from an XmlTextReader into a RomCenter
|
||||
/// </summary>
|
||||
/// <param name="reader">XmlTextReader to read from</param>
|
||||
/// <returns>Filled RomCenter on success, null on error</returns>
|
||||
public Data.Models.Logiqx.RomCenter ParseRomCenter(XmlTextReader reader)
|
||||
{
|
||||
var obj = new Data.Models.Logiqx.RomCenter();
|
||||
|
||||
obj.Plugin = reader.GetAttribute("plugin");
|
||||
obj.RomMode = reader.GetAttribute("rommode");
|
||||
obj.BiosMode = reader.GetAttribute("biosmode");
|
||||
obj.SampleMode = reader.GetAttribute("samplemode");
|
||||
obj.LockRomMode = reader.GetAttribute("lockrommode");
|
||||
obj.LockBiosMode = reader.GetAttribute("lockbiosmode");
|
||||
obj.LockSampleMode = reader.GetAttribute("locksamplemode");
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#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.Name = reader.GetAttribute("name");
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Parse from an XmlTextReader into a BiosSet
|
||||
/// </summary>
|
||||
/// <param name="reader">XmlTextReader to read from</param>
|
||||
/// <returns>Filled BiosSet on success, null on error</returns>
|
||||
public BiosSet ParseBiosSet(XmlTextReader reader)
|
||||
{
|
||||
var obj = new BiosSet();
|
||||
|
||||
obj.Name = reader.GetAttribute("name");
|
||||
obj.Description = reader.GetAttribute("description");
|
||||
obj.Default = reader.GetAttribute("default");
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Parse from an XmlTextReader into a DeviceRef
|
||||
/// </summary>
|
||||
/// <param name="reader">XmlTextReader to read from</param>
|
||||
/// <returns>Filled DeviceRef on success, null on error</returns>
|
||||
public DeviceRef ParseDeviceRef(XmlTextReader reader)
|
||||
{
|
||||
var obj = new DeviceRef();
|
||||
|
||||
obj.Name = reader.GetAttribute("name");
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Parse from an XmlTextReader into a Dir
|
||||
/// </summary>
|
||||
/// <param name="reader">XmlTextReader to read from</param>
|
||||
/// <returns>Filled Dir on success, null on error</returns>
|
||||
public Dir ParseDir(XmlTextReader reader)
|
||||
{
|
||||
var obj = new Dir();
|
||||
|
||||
obj.Name = reader.GetAttribute("name");
|
||||
|
||||
List<Dir> subdirs = [];
|
||||
List<GameBase> 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 "dir":
|
||||
var dir = ParseDir(reader);
|
||||
if (dir is not null)
|
||||
subdirs.Add(dir);
|
||||
|
||||
break;
|
||||
case "game":
|
||||
case "machine":
|
||||
var game = ParseGameBase(reader);
|
||||
if (game is not null)
|
||||
games.Add(game);
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
if (Debug) Console.Error.WriteLine($"Element '{reader.Name}' is not recognized");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (subdirs.Count > 0)
|
||||
obj.Subdir = [.. subdirs];
|
||||
if (games.Count > 0)
|
||||
obj.Game = [.. games];
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Parse from an XmlTextReader into a Disk
|
||||
/// </summary>
|
||||
/// <param name="reader">XmlTextReader to read from</param>
|
||||
/// <returns>Filled Disk on success, null on error</returns>
|
||||
public Disk ParseDisk(XmlTextReader reader)
|
||||
{
|
||||
var obj = new Disk();
|
||||
|
||||
obj.Name = reader.GetAttribute("name");
|
||||
obj.MD5 = reader.GetAttribute("md5");
|
||||
obj.SHA1 = reader.GetAttribute("sha1");
|
||||
obj.Merge = reader.GetAttribute("merge");
|
||||
obj.Status = reader.GetAttribute("status");
|
||||
obj.Region = reader.GetAttribute("region");
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Parse from an XmlTextReader into a Driver
|
||||
/// </summary>
|
||||
/// <param name="reader">XmlTextReader to read from</param>
|
||||
/// <returns>Filled Driver on success, null on error</returns>
|
||||
public Driver ParseDriver(XmlTextReader reader)
|
||||
{
|
||||
var obj = new Driver();
|
||||
|
||||
obj.Status = reader.GetAttribute("status");
|
||||
obj.Emulation = reader.GetAttribute("emulation");
|
||||
obj.Cocktail = reader.GetAttribute("cocktail");
|
||||
obj.SaveState = reader.GetAttribute("savestate");
|
||||
obj.RequiresArtwork = reader.GetAttribute("requiresartwork");
|
||||
obj.Unofficial = reader.GetAttribute("unofficial");
|
||||
obj.NoSoundHardware = reader.GetAttribute("nosoundhardware");
|
||||
obj.Incomplete = reader.GetAttribute("incomplete");
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Parse from an XmlTextReader into a GameBase
|
||||
/// </summary>
|
||||
/// <param name="reader">XmlTextReader to read from</param>
|
||||
/// <returns>Filled GameBase on success, null on error</returns>
|
||||
public GameBase? ParseGameBase(XmlTextReader reader)
|
||||
{
|
||||
GameBase obj;
|
||||
if (reader.Name == "game")
|
||||
obj = new Game();
|
||||
else if (reader.Name == "machine")
|
||||
obj = new Machine();
|
||||
else
|
||||
return null;
|
||||
|
||||
obj.Name = reader.GetAttribute("name");
|
||||
obj.SourceFile = reader.GetAttribute("sourcefile");
|
||||
obj.IsBios = reader.GetAttribute("isbios");
|
||||
obj.IsDevice = reader.GetAttribute("isdevice");
|
||||
obj.IsMechanical = reader.GetAttribute("ismechanical");
|
||||
obj.CloneOf = reader.GetAttribute("cloneof");
|
||||
obj.RomOf = reader.GetAttribute("romof");
|
||||
obj.SampleOf = reader.GetAttribute("sampleof");
|
||||
obj.Board = reader.GetAttribute("board");
|
||||
obj.RebuildTo = reader.GetAttribute("rebuildto");
|
||||
obj.Id = reader.GetAttribute("id");
|
||||
obj.CloneOfId = reader.GetAttribute("cloneofid");
|
||||
obj.Runnable = reader.GetAttribute("runnable");
|
||||
|
||||
List<string> comments = [];
|
||||
List<string> categories = [];
|
||||
List<Release> releases = [];
|
||||
List<BiosSet> biosSets = [];
|
||||
List<Rom> roms = [];
|
||||
List<Disk> disks = [];
|
||||
List<Media> medias = [];
|
||||
List<DeviceRef> deviceRefs = [];
|
||||
List<Sample> samples = [];
|
||||
List<Archive> archives = [];
|
||||
List<Data.Models.Logiqx.SoftwareList> softwareLists = [];
|
||||
|
||||
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 "comment":
|
||||
var comment = reader.ReadElementContentAsString();
|
||||
if (comment is not null)
|
||||
comments.Add(comment);
|
||||
|
||||
break;
|
||||
case "description":
|
||||
if (obj.Description is not null && Debug)
|
||||
Console.WriteLine($"'{reader.Name}' element already found, overwriting");
|
||||
|
||||
obj.Description = reader.ReadElementContentAsString();
|
||||
break;
|
||||
case "year":
|
||||
if (obj.Year is not null && Debug)
|
||||
Console.WriteLine($"'{reader.Name}' element already found, overwriting");
|
||||
|
||||
obj.Year = reader.ReadElementContentAsString();
|
||||
break;
|
||||
case "manufacturer":
|
||||
if (obj.Manufacturer is not null && Debug)
|
||||
Console.WriteLine($"'{reader.Name}' element already found, overwriting");
|
||||
|
||||
obj.Manufacturer = reader.ReadElementContentAsString();
|
||||
break;
|
||||
case "publisher":
|
||||
if (obj.Publisher is not null && Debug)
|
||||
Console.WriteLine($"'{reader.Name}' element already found, overwriting");
|
||||
|
||||
obj.Publisher = reader.ReadElementContentAsString();
|
||||
break;
|
||||
case "category":
|
||||
var category = reader.ReadElementContentAsString();
|
||||
if (category is not null)
|
||||
categories.Add(category);
|
||||
|
||||
break;
|
||||
case "trurip":
|
||||
if (obj.Trurip is not null && Debug)
|
||||
Console.WriteLine($"'{reader.Name}' element already found, overwriting");
|
||||
|
||||
obj.Trurip = ParseTrurip(reader);
|
||||
reader.Skip();
|
||||
break;
|
||||
case "release":
|
||||
var release = ParseRelease(reader);
|
||||
if (release is not null)
|
||||
releases.Add(release);
|
||||
|
||||
reader.Skip();
|
||||
break;
|
||||
case "biosset":
|
||||
var biosSet = ParseBiosSet(reader);
|
||||
if (biosSet is not null)
|
||||
biosSets.Add(biosSet);
|
||||
|
||||
reader.Skip();
|
||||
break;
|
||||
case "rom":
|
||||
var rom = ParseRom(reader);
|
||||
if (rom is not null)
|
||||
roms.Add(rom);
|
||||
|
||||
reader.Skip();
|
||||
break;
|
||||
case "disk":
|
||||
var disk = ParseDisk(reader);
|
||||
if (disk is not null)
|
||||
disks.Add(disk);
|
||||
|
||||
reader.Skip();
|
||||
break;
|
||||
case "media":
|
||||
var media = ParseMedia(reader);
|
||||
if (media is not null)
|
||||
medias.Add(media);
|
||||
|
||||
reader.Skip();
|
||||
break;
|
||||
case "device_ref":
|
||||
var deviceRef = ParseDeviceRef(reader);
|
||||
if (deviceRef is not null)
|
||||
deviceRefs.Add(deviceRef);
|
||||
|
||||
reader.Skip();
|
||||
break;
|
||||
case "sample":
|
||||
var sample = ParseSample(reader);
|
||||
if (sample is not null)
|
||||
samples.Add(sample);
|
||||
|
||||
reader.Skip();
|
||||
break;
|
||||
case "archive":
|
||||
var archive = ParseArchive(reader);
|
||||
if (archive is not null)
|
||||
archives.Add(archive);
|
||||
|
||||
reader.Skip();
|
||||
break;
|
||||
case "driver":
|
||||
if (obj.Driver is not null && Debug)
|
||||
Console.WriteLine($"'{reader.Name}' element already found, overwriting");
|
||||
|
||||
obj.Driver = ParseDriver(reader);
|
||||
reader.Skip();
|
||||
break;
|
||||
case "softwarelist":
|
||||
var softwareList = ParseSoftwareList(reader);
|
||||
if (softwareList is not null)
|
||||
softwareLists.Add(softwareList);
|
||||
|
||||
reader.Skip();
|
||||
break;
|
||||
case "url":
|
||||
if (obj.Url is not null && Debug)
|
||||
Console.WriteLine($"'{reader.Name}' element already found, overwriting");
|
||||
|
||||
obj.Url = reader.ReadElementContentAsString();
|
||||
break;
|
||||
case "hash":
|
||||
if (obj.Hash is not null && Debug)
|
||||
Console.WriteLine($"'{reader.Name}' element already found, overwriting");
|
||||
|
||||
obj.Hash = reader.ReadElementContentAsString();
|
||||
break;
|
||||
|
||||
default:
|
||||
if (Debug) Console.Error.WriteLine($"Element '{reader.Name}' is not recognized");
|
||||
reader.Skip();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (comments.Count > 0)
|
||||
obj.Comment = [.. comments];
|
||||
if (categories.Count > 0)
|
||||
obj.Category = [.. categories];
|
||||
if (releases.Count > 0)
|
||||
obj.Release = [.. releases];
|
||||
if (biosSets.Count > 0)
|
||||
obj.BiosSet = [.. biosSets];
|
||||
if (roms.Count > 0)
|
||||
obj.Rom = [.. roms];
|
||||
if (disks.Count > 0)
|
||||
obj.Disk = [.. disks];
|
||||
if (medias.Count > 0)
|
||||
obj.Media = [.. medias];
|
||||
if (deviceRefs.Count > 0)
|
||||
obj.DeviceRef = [.. deviceRefs];
|
||||
if (samples.Count > 0)
|
||||
obj.Sample = [.. samples];
|
||||
if (archives.Count > 0)
|
||||
obj.Archive = [.. archives];
|
||||
if (softwareLists.Count > 0)
|
||||
obj.SoftwareList = [.. softwareLists];
|
||||
|
||||
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();
|
||||
|
||||
obj.Name = reader.GetAttribute("name");
|
||||
obj.MD5 = reader.GetAttribute("md5");
|
||||
obj.SHA1 = reader.GetAttribute("sha1");
|
||||
obj.SHA256 = reader.GetAttribute("sha256");
|
||||
obj.SpamSum = reader.GetAttribute("spamsum");
|
||||
|
||||
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();
|
||||
|
||||
obj.Name = reader.GetAttribute("name");
|
||||
obj.Region = reader.GetAttribute("region");
|
||||
obj.Language = reader.GetAttribute("language");
|
||||
obj.Date = reader.GetAttribute("date");
|
||||
obj.Default = reader.GetAttribute("default");
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Parse from an XmlTextReader into a Rom
|
||||
/// </summary>
|
||||
/// <param name="reader">XmlTextReader to read from</param>
|
||||
/// <returns>Filled Rom on success, null on error</returns>
|
||||
public Rom ParseRom(XmlTextReader reader)
|
||||
{
|
||||
var obj = new Rom();
|
||||
|
||||
obj.Name = reader.GetAttribute("name");
|
||||
obj.Size = reader.GetAttribute("size");
|
||||
obj.CRC16 = reader.GetAttribute("crc16");
|
||||
obj.CRC = reader.GetAttribute("crc");
|
||||
obj.CRC64 = reader.GetAttribute("crc64");
|
||||
obj.MD2 = reader.GetAttribute("md2");
|
||||
obj.MD4 = reader.GetAttribute("md4");
|
||||
obj.MD5 = reader.GetAttribute("md5");
|
||||
obj.RIPEMD128 = reader.GetAttribute("ripemd128");
|
||||
obj.RIPEMD160 = reader.GetAttribute("ripemd160");
|
||||
obj.SHA1 = reader.GetAttribute("sha1");
|
||||
obj.SHA256 = reader.GetAttribute("sha256");
|
||||
obj.SHA384 = reader.GetAttribute("sha384");
|
||||
obj.SHA512 = reader.GetAttribute("sha512");
|
||||
obj.SpamSum = reader.GetAttribute("spamsum");
|
||||
obj.xxHash364 = reader.GetAttribute("xxh3_64");
|
||||
obj.xxHash3128 = reader.GetAttribute("xxh3_128");
|
||||
obj.Merge = reader.GetAttribute("merge");
|
||||
obj.Status = reader.GetAttribute("status");
|
||||
obj.Serial = reader.GetAttribute("serial");
|
||||
obj.Header = reader.GetAttribute("header");
|
||||
obj.Date = reader.GetAttribute("date");
|
||||
obj.Inverted = reader.GetAttribute("inverted");
|
||||
obj.MIA = reader.GetAttribute("mia");
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Parse from an XmlTextReader into a Sample
|
||||
/// </summary>
|
||||
/// <param name="reader">XmlTextReader to read from</param>
|
||||
/// <returns>Filled Sample on success, null on error</returns>
|
||||
public Sample ParseSample(XmlTextReader reader)
|
||||
{
|
||||
var obj = new Sample();
|
||||
|
||||
obj.Name = reader.GetAttribute("name");
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Parse from an XmlTextReader into a SoftwareList
|
||||
/// </summary>
|
||||
/// <param name="reader">XmlTextReader to read from</param>
|
||||
/// <returns>Filled SoftwareList on success, null on error</returns>
|
||||
public Data.Models.Logiqx.SoftwareList ParseSoftwareList(XmlTextReader reader)
|
||||
{
|
||||
var obj = new Data.Models.Logiqx.SoftwareList();
|
||||
|
||||
obj.Tag = reader.GetAttribute("tag");
|
||||
obj.Name = reader.GetAttribute("name");
|
||||
obj.Status = reader.GetAttribute("status");
|
||||
obj.Filter = reader.GetAttribute("filter");
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Parse from an XmlTextReader into a Trurip
|
||||
/// </summary>
|
||||
/// <param name="reader">XmlTextReader to read from</param>
|
||||
/// <returns>Filled Trurip on success, null on error</returns>
|
||||
public Trurip ParseTrurip(XmlTextReader reader)
|
||||
{
|
||||
var obj = new Trurip();
|
||||
|
||||
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 "titleid":
|
||||
if (obj.TitleID is not null && Debug)
|
||||
Console.WriteLine($"'{reader.Name}' element already found, overwriting");
|
||||
|
||||
obj.TitleID = reader.ReadElementContentAsString();
|
||||
break;
|
||||
case "publisher":
|
||||
if (obj.Publisher is not null && Debug)
|
||||
Console.WriteLine($"'{reader.Name}' element already found, overwriting");
|
||||
|
||||
obj.Publisher = reader.ReadElementContentAsString();
|
||||
break;
|
||||
case "developer":
|
||||
if (obj.Developer is not null && Debug)
|
||||
Console.WriteLine($"'{reader.Name}' element already found, overwriting");
|
||||
|
||||
obj.Developer = reader.ReadElementContentAsString();
|
||||
break;
|
||||
case "year":
|
||||
if (obj.Year is not null && Debug)
|
||||
Console.WriteLine($"'{reader.Name}' element already found, overwriting");
|
||||
|
||||
obj.Year = reader.ReadElementContentAsString();
|
||||
break;
|
||||
case "genre":
|
||||
if (obj.Genre is not null && Debug)
|
||||
Console.WriteLine($"'{reader.Name}' element already found, overwriting");
|
||||
|
||||
obj.Genre = reader.ReadElementContentAsString();
|
||||
break;
|
||||
case "subgenre":
|
||||
if (obj.Subgenre is not null && Debug)
|
||||
Console.WriteLine($"'{reader.Name}' element already found, overwriting");
|
||||
|
||||
obj.Subgenre = reader.ReadElementContentAsString();
|
||||
break;
|
||||
case "ratings":
|
||||
if (obj.Ratings is not null && Debug)
|
||||
Console.WriteLine($"'{reader.Name}' element already found, overwriting");
|
||||
|
||||
obj.Ratings = reader.ReadElementContentAsString();
|
||||
break;
|
||||
case "score":
|
||||
if (obj.Score is not null && Debug)
|
||||
Console.WriteLine($"'{reader.Name}' element already found, overwriting");
|
||||
|
||||
obj.Score = reader.ReadElementContentAsString();
|
||||
break;
|
||||
case "players":
|
||||
if (obj.Players is not null && Debug)
|
||||
Console.WriteLine($"'{reader.Name}' element already found, overwriting");
|
||||
|
||||
obj.Players = reader.ReadElementContentAsString();
|
||||
break;
|
||||
case "enabled":
|
||||
if (obj.Enabled is not null && Debug)
|
||||
Console.WriteLine($"'{reader.Name}' element already found, overwriting");
|
||||
|
||||
obj.Enabled = reader.ReadElementContentAsString();
|
||||
break;
|
||||
case "crc":
|
||||
if (obj.CRC is not null && Debug)
|
||||
Console.WriteLine($"'{reader.Name}' element already found, overwriting");
|
||||
|
||||
obj.CRC = reader.ReadElementContentAsString();
|
||||
break;
|
||||
case "source":
|
||||
if (obj.Source is not null && Debug)
|
||||
Console.WriteLine($"'{reader.Name}' element already found, overwriting");
|
||||
|
||||
obj.Source = reader.ReadElementContentAsString();
|
||||
break;
|
||||
case "cloneof":
|
||||
if (obj.CloneOf is not null && Debug)
|
||||
Console.WriteLine($"'{reader.Name}' element already found, overwriting");
|
||||
|
||||
obj.CloneOf = reader.ReadElementContentAsString();
|
||||
break;
|
||||
case "relatedto":
|
||||
if (obj.RelatedTo is not null && Debug)
|
||||
Console.WriteLine($"'{reader.Name}' element already found, overwriting");
|
||||
|
||||
obj.RelatedTo = reader.ReadElementContentAsString();
|
||||
break;
|
||||
|
||||
default:
|
||||
if (Debug) Console.Error.WriteLine($"Element '{reader.Name}' is not recognized");
|
||||
reader.Skip();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,9 +1,318 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Xml;
|
||||
using SabreTools.Data.Models.OpenMSX;
|
||||
|
||||
namespace SabreTools.Serialization.Readers
|
||||
{
|
||||
public class OpenMSX : XmlFile<SoftwareDb>
|
||||
public class OpenMSX : BaseBinaryReader<SoftwareDb>
|
||||
{
|
||||
// All logic taken care of in the base class
|
||||
/// <inheritdoc/>
|
||||
public override SoftwareDb? 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
|
||||
SoftwareDb? softwareDb = 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 "softwaredb":
|
||||
if (softwareDb is not null && Debug)
|
||||
Console.WriteLine($"'{reader.Name}' element already found, overwriting");
|
||||
|
||||
softwareDb = ParseSoftwareDb(reader);
|
||||
break;
|
||||
|
||||
default:
|
||||
if (Debug) Console.Error.WriteLine($"Element '{reader.Name}' is not recognized");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return softwareDb;
|
||||
}
|
||||
catch
|
||||
{
|
||||
// Ignore the actual error
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Parse from an XmlTextReader into a SoftwareDb
|
||||
/// </summary>
|
||||
/// <param name="reader">XmlTextReader to read from</param>
|
||||
/// <returns>Filled SoftwareDb on success, null on error</returns>
|
||||
public SoftwareDb ParseSoftwareDb(XmlTextReader reader)
|
||||
{
|
||||
var obj = new SoftwareDb();
|
||||
|
||||
obj.Timestamp = reader.GetAttribute("timestamp");
|
||||
|
||||
List<Software> softwares = [];
|
||||
|
||||
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 "software":
|
||||
var software = ParseSoftware(reader);
|
||||
if (software is not null)
|
||||
softwares.Add(software);
|
||||
|
||||
reader.Skip();
|
||||
break;
|
||||
|
||||
default:
|
||||
if (Debug) Console.Error.WriteLine($"Element '{reader.Name}' is not recognized");
|
||||
reader.Skip();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (softwares.Count > 0)
|
||||
obj.Software = [.. softwares];
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Parse from an XmlTextReader into a Dump
|
||||
/// </summary>
|
||||
/// <param name="reader">XmlTextReader to read from</param>
|
||||
/// <returns>Filled Dump on success, null on error</returns>
|
||||
public Dump ParseDump(XmlTextReader reader)
|
||||
{
|
||||
var obj = new Dump();
|
||||
|
||||
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 "original":
|
||||
if (obj.Original is not null && Debug)
|
||||
Console.WriteLine($"'{reader.Name}' element already found, overwriting");
|
||||
|
||||
obj.Original = ParseOriginal(reader);
|
||||
break;
|
||||
case "rom":
|
||||
case "megarom":
|
||||
case "sccpluscart":
|
||||
if (obj.Rom is not null && Debug)
|
||||
Console.WriteLine($"'{reader.Name}' element already found, overwriting");
|
||||
|
||||
obj.Rom = ParseRomBase(reader);
|
||||
reader.Skip();
|
||||
break;
|
||||
|
||||
default:
|
||||
if (Debug) Console.Error.WriteLine($"Element '{reader.Name}' is not recognized");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Parse from an XmlTextReader into a Original
|
||||
/// </summary>
|
||||
/// <param name="reader">XmlTextReader to read from</param>
|
||||
/// <returns>Filled Original on success, null on error</returns>
|
||||
public Original ParseOriginal(XmlTextReader reader)
|
||||
{
|
||||
var obj = new Original();
|
||||
|
||||
obj.Value = reader.GetAttribute("value");
|
||||
obj.Content = reader.ReadElementContentAsString();
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Parse from an XmlTextReader into a RomBase
|
||||
/// </summary>
|
||||
/// <param name="reader">XmlTextReader to read from</param>
|
||||
/// <returns>Filled RomBase on success, null on error</returns>
|
||||
public RomBase? ParseRomBase(XmlTextReader reader)
|
||||
{
|
||||
RomBase obj;
|
||||
if (reader.Name == "rom")
|
||||
obj = new Rom();
|
||||
else if (reader.Name == "megarom")
|
||||
obj = new MegaRom();
|
||||
else if (reader.Name == "sccpluscart")
|
||||
obj = new SCCPlusCart();
|
||||
else
|
||||
return null;
|
||||
|
||||
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 "start":
|
||||
if (obj.Start is not null && Debug)
|
||||
Console.WriteLine($"'{reader.Name}' element already found, overwriting");
|
||||
|
||||
obj.Start = reader.ReadElementContentAsString();
|
||||
break;
|
||||
case "type":
|
||||
if (obj.Type is not null && Debug)
|
||||
Console.WriteLine($"'{reader.Name}' element already found, overwriting");
|
||||
|
||||
obj.Type = reader.ReadElementContentAsString();
|
||||
break;
|
||||
case "hash":
|
||||
if (obj.Hash is not null && Debug)
|
||||
Console.WriteLine($"'{reader.Name}' element already found, overwriting");
|
||||
|
||||
obj.Hash = reader.ReadElementContentAsString();
|
||||
break;
|
||||
case "remark":
|
||||
if (obj.Remark is not null && Debug)
|
||||
Console.WriteLine($"'{reader.Name}' element already found, overwriting");
|
||||
|
||||
obj.Remark = reader.ReadElementContentAsString();
|
||||
break;
|
||||
|
||||
default:
|
||||
if (Debug) Console.Error.WriteLine($"Element '{reader.Name}' is not recognized");
|
||||
reader.Skip();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Parse from an XmlTextReader into a Software
|
||||
/// </summary>
|
||||
/// <param name="reader">XmlTextReader to read from</param>
|
||||
/// <returns>Filled Software on success, null on error</returns>
|
||||
public Software ParseSoftware(XmlTextReader reader)
|
||||
{
|
||||
var obj = new Software();
|
||||
|
||||
List<Dump> dumps = [];
|
||||
|
||||
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 "title":
|
||||
if (obj.Title is not null && Debug)
|
||||
Console.WriteLine($"'{reader.Name}' element already found, overwriting");
|
||||
|
||||
obj.Title = reader.ReadElementContentAsString();
|
||||
break;
|
||||
case "genmsxid":
|
||||
if (obj.GenMSXID is not null && Debug)
|
||||
Console.WriteLine($"'{reader.Name}' element already found, overwriting");
|
||||
|
||||
obj.GenMSXID = reader.ReadElementContentAsString();
|
||||
break;
|
||||
case "system":
|
||||
if (obj.System is not null && Debug)
|
||||
Console.WriteLine($"'{reader.Name}' element already found, overwriting");
|
||||
|
||||
obj.System = reader.ReadElementContentAsString();
|
||||
break;
|
||||
case "company":
|
||||
if (obj.Company is not null && Debug)
|
||||
Console.WriteLine($"'{reader.Name}' element already found, overwriting");
|
||||
|
||||
obj.Company = reader.ReadElementContentAsString();
|
||||
break;
|
||||
case "year":
|
||||
if (obj.Year is not null && Debug)
|
||||
Console.WriteLine($"'{reader.Name}' element already found, overwriting");
|
||||
|
||||
obj.Year = reader.ReadElementContentAsString();
|
||||
break;
|
||||
case "country":
|
||||
if (obj.Country is not null && Debug)
|
||||
Console.WriteLine($"'{reader.Name}' element already found, overwriting");
|
||||
|
||||
obj.Country = reader.ReadElementContentAsString();
|
||||
break;
|
||||
case "dump":
|
||||
var dump = ParseDump(reader);
|
||||
if (dump is not null)
|
||||
dumps.Add(dump);
|
||||
|
||||
reader.Skip();
|
||||
break;
|
||||
|
||||
default:
|
||||
if (Debug) Console.Error.WriteLine($"Element '{reader.Name}' is not recognized");
|
||||
reader.Skip();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (dumps.Count > 0)
|
||||
obj.Dump = [.. dumps];
|
||||
|
||||
return obj;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,535 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Xml;
|
||||
using SabreTools.Data.Models.SoftwareList;
|
||||
|
||||
namespace SabreTools.Serialization.Readers
|
||||
{
|
||||
public class SoftwareList : XmlFile<Data.Models.SoftwareList.SoftwareList>
|
||||
public class SoftwareList : BaseBinaryReader<Data.Models.SoftwareList.SoftwareList>
|
||||
{
|
||||
// All logic taken care of in the base class
|
||||
/// <inheritdoc/>
|
||||
public override Data.Models.SoftwareList.SoftwareList? 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
|
||||
Data.Models.SoftwareList.SoftwareList? softwareList = 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 "softwarelist":
|
||||
if (softwareList is not null && Debug)
|
||||
Console.WriteLine($"'{reader.Name}' element already found, overwriting");
|
||||
|
||||
softwareList = ParseSoftwareList(reader);
|
||||
break;
|
||||
|
||||
default:
|
||||
if (Debug) Console.Error.WriteLine($"Element '{reader.Name}' is not recognized");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return softwareList;
|
||||
}
|
||||
catch
|
||||
{
|
||||
// Ignore the actual error
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Parse from an XmlTextReader into a SoftwareList
|
||||
/// </summary>
|
||||
/// <param name="reader">XmlTextReader to read from</param>
|
||||
/// <returns>Filled SoftwareList on success, null on error</returns>
|
||||
public Data.Models.SoftwareList.SoftwareList ParseSoftwareList(XmlTextReader reader)
|
||||
{
|
||||
var obj = new Data.Models.SoftwareList.SoftwareList();
|
||||
|
||||
obj.Name = reader.GetAttribute("name");
|
||||
obj.Description = reader.GetAttribute("description");
|
||||
|
||||
List<Software> softwares = [];
|
||||
|
||||
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 "notes":
|
||||
if (obj.Notes is not null && Debug)
|
||||
Console.WriteLine($"'{reader.Name}' element already found, overwriting");
|
||||
|
||||
obj.Notes = reader.ReadElementContentAsString();
|
||||
break;
|
||||
case "software":
|
||||
var software = ParseSoftware(reader);
|
||||
if (software is not null)
|
||||
softwares.Add(software);
|
||||
|
||||
reader.Skip();
|
||||
break;
|
||||
|
||||
default:
|
||||
if (Debug) Console.Error.WriteLine($"Element '{reader.Name}' is not recognized");
|
||||
reader.Skip();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (softwares.Count > 0)
|
||||
obj.Software = [.. softwares];
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Parse from an XmlTextReader into a DataArea
|
||||
/// </summary>
|
||||
/// <param name="reader">XmlTextReader to read from</param>
|
||||
/// <returns>Filled DataArea on success, null on error</returns>
|
||||
public DataArea ParseDataArea(XmlTextReader reader)
|
||||
{
|
||||
var obj = new DataArea();
|
||||
|
||||
obj.Name = reader.GetAttribute("name");
|
||||
obj.Size = reader.GetAttribute("size");
|
||||
obj.Width = reader.GetAttribute("width");
|
||||
obj.Endianness = reader.GetAttribute("endianness");
|
||||
|
||||
List<Rom> roms = [];
|
||||
|
||||
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 "rom":
|
||||
var rom = ParseRom(reader);
|
||||
if (rom is not null)
|
||||
roms.Add(rom);
|
||||
|
||||
reader.Skip();
|
||||
break;
|
||||
|
||||
default:
|
||||
if (Debug) Console.Error.WriteLine($"Element '{reader.Name}' is not recognized");
|
||||
reader.Skip();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (roms.Count > 0)
|
||||
obj.Rom = [.. roms];
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Parse from an XmlTextReader into a DipSwitch
|
||||
/// </summary>
|
||||
/// <param name="reader">XmlTextReader to read from</param>
|
||||
/// <returns>Filled DipSwitch on success, null on error</returns>
|
||||
public DipSwitch ParseDipSwitch(XmlTextReader reader)
|
||||
{
|
||||
var obj = new DipSwitch();
|
||||
|
||||
obj.Name = reader.GetAttribute("name");
|
||||
obj.Tag = reader.GetAttribute("tag");
|
||||
obj.Mask = reader.GetAttribute("mask");
|
||||
|
||||
List<DipValue> dipValues = [];
|
||||
|
||||
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 "dipvalue":
|
||||
var dipValue = ParseDipValue(reader);
|
||||
if (dipValue is not null)
|
||||
dipValues.Add(dipValue);
|
||||
|
||||
reader.Skip();
|
||||
break;
|
||||
|
||||
default:
|
||||
if (Debug) Console.Error.WriteLine($"Element '{reader.Name}' is not recognized");
|
||||
reader.Skip();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (dipValues.Count > 0)
|
||||
obj.DipValue = [.. dipValues];
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Parse from an XmlTextReader into a DipValue
|
||||
/// </summary>
|
||||
/// <param name="reader">XmlTextReader to read from</param>
|
||||
/// <returns>Filled DipValue on success, null on error</returns>
|
||||
public DipValue ParseDipValue(XmlTextReader reader)
|
||||
{
|
||||
var obj = new DipValue();
|
||||
|
||||
obj.Name = reader.GetAttribute("name");
|
||||
obj.Value = reader.GetAttribute("value");
|
||||
obj.Default = reader.GetAttribute("default");
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Parse from an XmlTextReader into a Disk
|
||||
/// </summary>
|
||||
/// <param name="reader">XmlTextReader to read from</param>
|
||||
/// <returns>Filled Disk on success, null on error</returns>
|
||||
public Disk ParseDisk(XmlTextReader reader)
|
||||
{
|
||||
var obj = new Disk();
|
||||
|
||||
obj.Name = reader.GetAttribute("name");
|
||||
obj.MD5 = reader.GetAttribute("md5");
|
||||
obj.SHA1 = reader.GetAttribute("sha1");
|
||||
obj.Status = reader.GetAttribute("status");
|
||||
obj.Writeable = reader.GetAttribute("writable");
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Parse from an XmlTextReader into a DiskArea
|
||||
/// </summary>
|
||||
/// <param name="reader">XmlTextReader to read from</param>
|
||||
/// <returns>Filled DiskArea on success, null on error</returns>
|
||||
public DiskArea ParseDiskArea(XmlTextReader reader)
|
||||
{
|
||||
var obj = new DiskArea();
|
||||
|
||||
obj.Name = reader.GetAttribute("name");
|
||||
|
||||
List<Disk> disks = [];
|
||||
|
||||
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 "disk":
|
||||
var disk = ParseDisk(reader);
|
||||
if (disk is not null)
|
||||
disks.Add(disk);
|
||||
|
||||
reader.Skip();
|
||||
break;
|
||||
|
||||
default:
|
||||
if (Debug) Console.Error.WriteLine($"Element '{reader.Name}' is not recognized");
|
||||
reader.Skip();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (disks.Count > 0)
|
||||
obj.Disk = [.. disks];
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Parse from an XmlTextReader into a Feature
|
||||
/// </summary>
|
||||
/// <param name="reader">XmlTextReader to read from</param>
|
||||
/// <returns>Filled Feature on success, null on error</returns>
|
||||
public Feature ParseFeature(XmlTextReader reader)
|
||||
{
|
||||
var obj = new Feature();
|
||||
|
||||
obj.Name = reader.GetAttribute("name");
|
||||
obj.Value = reader.GetAttribute("value");
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Parse from an XmlTextReader into a Info
|
||||
/// </summary>
|
||||
/// <param name="reader">XmlTextReader to read from</param>
|
||||
/// <returns>Filled Info on success, null on error</returns>
|
||||
public Info ParseInfo(XmlTextReader reader)
|
||||
{
|
||||
var obj = new Info();
|
||||
|
||||
obj.Name = reader.GetAttribute("name");
|
||||
obj.Value = reader.GetAttribute("value");
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Parse from an XmlTextReader into a Part
|
||||
/// </summary>
|
||||
/// <param name="reader">XmlTextReader to read from</param>
|
||||
/// <returns>Filled Part on success, null on error</returns>
|
||||
public Part ParsePart(XmlTextReader reader)
|
||||
{
|
||||
var obj = new Part();
|
||||
|
||||
obj.Name = reader.GetAttribute("name");
|
||||
obj.Interface = reader.GetAttribute("interface");
|
||||
|
||||
List<Feature> features = [];
|
||||
List<DataArea> dataAreas = [];
|
||||
List<DiskArea> diskAreas = [];
|
||||
List<DipSwitch> dipSwitches = [];
|
||||
|
||||
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 "feature":
|
||||
var feature = ParseFeature(reader);
|
||||
if (feature is not null)
|
||||
features.Add(feature);
|
||||
|
||||
reader.Skip();
|
||||
break;
|
||||
case "dataarea":
|
||||
var dataArea = ParseDataArea(reader);
|
||||
if (dataArea is not null)
|
||||
dataAreas.Add(dataArea);
|
||||
|
||||
reader.Skip();
|
||||
break;
|
||||
case "diskarea":
|
||||
var diskArea = ParseDiskArea(reader);
|
||||
if (diskArea is not null)
|
||||
diskAreas.Add(diskArea);
|
||||
|
||||
reader.Skip();
|
||||
break;
|
||||
case "dipswitch":
|
||||
var dipSwitch = ParseDipSwitch(reader);
|
||||
if (dipSwitch is not null)
|
||||
dipSwitches.Add(dipSwitch);
|
||||
|
||||
reader.Skip();
|
||||
break;
|
||||
|
||||
default:
|
||||
if (Debug) Console.Error.WriteLine($"Element '{reader.Name}' is not recognized");
|
||||
reader.Skip();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (features.Count > 0)
|
||||
obj.Feature = [.. features];
|
||||
if (dataAreas.Count > 0)
|
||||
obj.DataArea = [.. dataAreas];
|
||||
if (diskAreas.Count > 0)
|
||||
obj.DiskArea = [.. diskAreas];
|
||||
if (dipSwitches.Count > 0)
|
||||
obj.DipSwitch = [.. dipSwitches];
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Parse from an XmlTextReader into a Rom
|
||||
/// </summary>
|
||||
/// <param name="reader">XmlTextReader to read from</param>
|
||||
/// <returns>Filled Rom on success, null on error</returns>
|
||||
public Rom ParseRom(XmlTextReader reader)
|
||||
{
|
||||
var obj = new Rom();
|
||||
|
||||
obj.Name = reader.GetAttribute("name");
|
||||
obj.Size = reader.GetAttribute("size");
|
||||
obj.Length = reader.GetAttribute("length");
|
||||
obj.CRC = reader.GetAttribute("crc");
|
||||
obj.SHA1 = reader.GetAttribute("sha1");
|
||||
obj.Offset = reader.GetAttribute("offset");
|
||||
obj.Value = reader.GetAttribute("value");
|
||||
obj.Status = reader.GetAttribute("status");
|
||||
obj.LoadFlag = reader.GetAttribute("loadflag");
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Parse from an XmlTextReader into a SharedFeat
|
||||
/// </summary>
|
||||
/// <param name="reader">XmlTextReader to read from</param>
|
||||
/// <returns>Filled SharedFeat on success, null on error</returns>
|
||||
public SharedFeat ParseSharedFeat(XmlTextReader reader)
|
||||
{
|
||||
var obj = new SharedFeat();
|
||||
|
||||
obj.Name = reader.GetAttribute("name");
|
||||
obj.Value = reader.GetAttribute("value");
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Parse from an XmlTextReader into a Software
|
||||
/// </summary>
|
||||
/// <param name="reader">XmlTextReader to read from</param>
|
||||
/// <returns>Filled Software on success, null on error</returns>
|
||||
public Software ParseSoftware(XmlTextReader reader)
|
||||
{
|
||||
var obj = new Software();
|
||||
|
||||
obj.Name = reader.GetAttribute("name");
|
||||
obj.CloneOf = reader.GetAttribute("cloneof");
|
||||
obj.Supported = reader.GetAttribute("supported");
|
||||
|
||||
List<Info> infos = [];
|
||||
List<SharedFeat> sharedFeats = [];
|
||||
List<Part> parts = [];
|
||||
|
||||
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 "description":
|
||||
if (obj.Description is not null && Debug)
|
||||
Console.WriteLine($"'{reader.Name}' element already found, overwriting");
|
||||
|
||||
obj.Description = reader.ReadElementContentAsString();
|
||||
break;
|
||||
case "year":
|
||||
if (obj.Year is not null && Debug)
|
||||
Console.WriteLine($"'{reader.Name}' element already found, overwriting");
|
||||
|
||||
obj.Year = reader.ReadElementContentAsString();
|
||||
break;
|
||||
case "publisher":
|
||||
if (obj.Publisher is not null && Debug)
|
||||
Console.WriteLine($"'{reader.Name}' element already found, overwriting");
|
||||
|
||||
obj.Publisher = reader.ReadElementContentAsString();
|
||||
break;
|
||||
case "notes":
|
||||
if (obj.Notes is not null && Debug)
|
||||
Console.WriteLine($"'{reader.Name}' element already found, overwriting");
|
||||
|
||||
obj.Notes = reader.ReadElementContentAsString();
|
||||
break;
|
||||
case "info":
|
||||
var info = ParseInfo(reader);
|
||||
if (info is not null)
|
||||
infos.Add(info);
|
||||
|
||||
reader.Skip();
|
||||
break;
|
||||
case "sharedfeat":
|
||||
var sharedFeat = ParseSharedFeat(reader);
|
||||
if (sharedFeat is not null)
|
||||
sharedFeats.Add(sharedFeat);
|
||||
|
||||
reader.Skip();
|
||||
break;
|
||||
case "part":
|
||||
var part = ParsePart(reader);
|
||||
if (part is not null)
|
||||
parts.Add(part);
|
||||
|
||||
reader.Skip();
|
||||
break;
|
||||
|
||||
default:
|
||||
if (Debug) Console.Error.WriteLine($"Element '{reader.Name}' is not recognized");
|
||||
reader.Skip();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (infos.Count > 0)
|
||||
obj.Info = [.. infos];
|
||||
if (sharedFeats.Count > 0)
|
||||
obj.SharedFeat = [.. sharedFeats];
|
||||
if (parts.Count > 0)
|
||||
obj.Part = [.. parts];
|
||||
|
||||
return obj;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,47 +0,0 @@
|
||||
using System.IO;
|
||||
using System.Xml;
|
||||
using System.Xml.Schema;
|
||||
using System.Xml.Serialization;
|
||||
|
||||
namespace SabreTools.Serialization.Readers
|
||||
{
|
||||
/// <summary>
|
||||
/// Base class for other XML deserializers
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
public abstract class XmlFile<T> : BaseBinaryReader<T>
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
public override T? Deserialize(Stream? data)
|
||||
{
|
||||
// If the stream is invalid
|
||||
if (data is null || !data.CanRead)
|
||||
return default;
|
||||
|
||||
try
|
||||
{
|
||||
// Setup the serializer and the reader
|
||||
var serializer = new XmlSerializer(typeof(T));
|
||||
var settings = new XmlReaderSettings
|
||||
{
|
||||
CheckCharacters = false,
|
||||
#if NET40_OR_GREATER || NETCOREAPP || NETSTANDARD2_0_OR_GREATER
|
||||
DtdProcessing = DtdProcessing.Ignore,
|
||||
#endif
|
||||
ValidationFlags = XmlSchemaValidationFlags.None,
|
||||
ValidationType = ValidationType.None,
|
||||
};
|
||||
var streamReader = new StreamReader(data);
|
||||
var xmlReader = XmlReader.Create(streamReader, settings);
|
||||
|
||||
// Perform the deserialization and return
|
||||
return (T?)serializer.Deserialize(xmlReader);
|
||||
}
|
||||
catch
|
||||
{
|
||||
// Ignore the actual error
|
||||
return default;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user