mirror of
https://github.com/claunia/SabreTools.git
synced 2025-12-16 19:14:27 +00:00
Add separated-value deserialization test
This commit is contained in:
9
SabreTools.Models/SeparatedValue/MetadataFile.cs
Normal file
9
SabreTools.Models/SeparatedValue/MetadataFile.cs
Normal file
@@ -0,0 +1,9 @@
|
||||
namespace SabreTools.Models.SeparatedValue
|
||||
{
|
||||
public class MetadataFile
|
||||
{
|
||||
public string[] Header { get; set; }
|
||||
|
||||
public Row[]? Row { get; set; }
|
||||
}
|
||||
}
|
||||
66
SabreTools.Models/SeparatedValue/Row.cs
Normal file
66
SabreTools.Models/SeparatedValue/Row.cs
Normal file
@@ -0,0 +1,66 @@
|
||||
namespace SabreTools.Models.SeparatedValue
|
||||
{
|
||||
/// <summary>
|
||||
/// Standardized variant of a row
|
||||
/// </summary>
|
||||
public class Row
|
||||
{
|
||||
/// <remarks>File Name</remarks>
|
||||
public string FileName { get; set; }
|
||||
|
||||
/// <remarks>Internal Name</remarks>
|
||||
public string InternalName { get; set; }
|
||||
|
||||
/// <remarks>Description</remarks>
|
||||
public string Description { get; set; }
|
||||
|
||||
/// <remarks>Game Name</remarks>
|
||||
public string GameName { get; set; }
|
||||
|
||||
/// <remarks>Game Description</remarks>
|
||||
public string GameDescription { get; set; }
|
||||
|
||||
/// <remarks>Type</remarks>
|
||||
public string Type { get; set; }
|
||||
|
||||
/// <remarks>Rom Name</remarks>
|
||||
public string RomName { get; set; }
|
||||
|
||||
/// <remarks>Disk Name</remarks>
|
||||
public string DiskName { get; set; }
|
||||
|
||||
/// <remarks>Size, Numeric</remarks>
|
||||
public string Size { get; set; }
|
||||
|
||||
/// <remarks>CRC</remarks>
|
||||
public string CRC { get; set; }
|
||||
|
||||
/// <remarks>MD5</remarks>
|
||||
public string MD5 { get; set; }
|
||||
|
||||
/// <remarks>SHA1</remarks>
|
||||
public string SHA1 { get; set; }
|
||||
|
||||
/// <remarks>SHA256</remarks>
|
||||
public string SHA256 { get; set; }
|
||||
|
||||
/// <remarks>SHA384, Optional</remarks>
|
||||
public string SHA384 { get; set; }
|
||||
|
||||
/// <remarks>SHA512, Optional</remarks>
|
||||
public string SHA512 { get; set; }
|
||||
|
||||
/// <remarks>SpamSum, Optional</remarks>
|
||||
public string SpamSum { get; set; }
|
||||
|
||||
/// <remarks>Nodump</remarks>
|
||||
public string Nodump { get; set; }
|
||||
|
||||
#region DO NOT USE IN PRODUCTION
|
||||
|
||||
/// <remarks>Should be empty</remarks>
|
||||
public string[]? ADDITIONAL_ELEMENTS { get; set; }
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -73,7 +73,7 @@ namespace SabreTools.Serialization
|
||||
break;
|
||||
|
||||
// Parse the line into a row
|
||||
Row row = null;
|
||||
Row? row = null;
|
||||
if (reader.Line.Count < HeaderWithRomnameCount)
|
||||
{
|
||||
row = new Row
|
||||
|
||||
143
SabreTools.Serialization/SeparatedValue.cs
Normal file
143
SabreTools.Serialization/SeparatedValue.cs
Normal file
@@ -0,0 +1,143 @@
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using SabreTools.IO.Readers;
|
||||
using SabreTools.Models.SeparatedValue;
|
||||
|
||||
namespace SabreTools.Serialization
|
||||
{
|
||||
/// <summary>
|
||||
/// Serializer for separated-value variants
|
||||
/// </summary>
|
||||
public class SeparatedValue
|
||||
{
|
||||
private const int HeaderWithoutExtendedHashesCount = 14;
|
||||
|
||||
private const int HeaderWithExtendedHashesCount = 17;
|
||||
|
||||
/// <summary>
|
||||
/// Deserializes a separated-value variant to the defined type
|
||||
/// </summary>
|
||||
/// <param name="path">Path to the file to deserialize</param>
|
||||
/// <param name="delim">Character delimiter between values</param>
|
||||
/// <returns>Deserialized data on success, null on failure</returns>
|
||||
public static MetadataFile? Deserialize(string path, char delim)
|
||||
{
|
||||
try
|
||||
{
|
||||
using var stream = PathProcessor.OpenStream(path);
|
||||
return Deserialize(stream, delim);
|
||||
}
|
||||
catch
|
||||
{
|
||||
// TODO: Handle logging the exception
|
||||
return default;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Deserializes a separated-value variant in a stream to the defined type
|
||||
/// </summary>
|
||||
/// <param name="stream">Stream to deserialize</param>
|
||||
/// <param name="delim">Character delimiter between values</param>
|
||||
/// <returns>Deserialized data on success, null on failure</returns>
|
||||
public static MetadataFile? Deserialize(Stream? stream, char delim)
|
||||
{
|
||||
try
|
||||
{
|
||||
// If the stream is null
|
||||
if (stream == null)
|
||||
return default;
|
||||
|
||||
// Setup the reader and output
|
||||
var reader = new SeparatedValueReader(stream, Encoding.UTF8)
|
||||
{
|
||||
Header = true,
|
||||
Separator = delim,
|
||||
VerifyFieldCount = false,
|
||||
};
|
||||
var dat = new MetadataFile();
|
||||
|
||||
// Read the header values first
|
||||
if (!reader.ReadHeader())
|
||||
return null;
|
||||
|
||||
dat.Header = reader.HeaderValues.ToArray();
|
||||
|
||||
// Loop through the rows and parse out values
|
||||
var rows = new List<Row>();
|
||||
while (!reader.EndOfStream)
|
||||
{
|
||||
// If we have no next line
|
||||
if (!reader.ReadNextLine())
|
||||
break;
|
||||
|
||||
// Parse the line into a row
|
||||
Row? row = null;
|
||||
if (reader.Line.Count < HeaderWithExtendedHashesCount)
|
||||
{
|
||||
row = new Row
|
||||
{
|
||||
FileName = reader.Line[0],
|
||||
InternalName = reader.Line[1],
|
||||
Description = reader.Line[2],
|
||||
GameName = reader.Line[3],
|
||||
GameDescription = reader.Line[4],
|
||||
Type = reader.Line[5],
|
||||
RomName = reader.Line[6],
|
||||
DiskName = reader.Line[7],
|
||||
Size = reader.Line[8],
|
||||
CRC = reader.Line[9],
|
||||
MD5 = reader.Line[10],
|
||||
SHA1 = reader.Line[11],
|
||||
SHA256 = reader.Line[12],
|
||||
Nodump = reader.Line[13],
|
||||
};
|
||||
|
||||
// If we have additional fields
|
||||
if (reader.Line.Count > HeaderWithoutExtendedHashesCount)
|
||||
row.ADDITIONAL_ELEMENTS = reader.Line.Skip(HeaderWithoutExtendedHashesCount).ToArray();
|
||||
}
|
||||
else
|
||||
{
|
||||
row = new Row
|
||||
{
|
||||
FileName = reader.Line[0],
|
||||
InternalName = reader.Line[1],
|
||||
Description = reader.Line[2],
|
||||
GameName = reader.Line[3],
|
||||
GameDescription = reader.Line[4],
|
||||
Type = reader.Line[5],
|
||||
RomName = reader.Line[6],
|
||||
DiskName = reader.Line[7],
|
||||
Size = reader.Line[8],
|
||||
CRC = reader.Line[9],
|
||||
MD5 = reader.Line[10],
|
||||
SHA1 = reader.Line[11],
|
||||
SHA256 = reader.Line[12],
|
||||
SHA384 = reader.Line[13],
|
||||
SHA512 = reader.Line[14],
|
||||
SpamSum = reader.Line[15],
|
||||
Nodump = reader.Line[16],
|
||||
};
|
||||
|
||||
// If we have additional fields
|
||||
if (reader.Line.Count > HeaderWithExtendedHashesCount)
|
||||
row.ADDITIONAL_ELEMENTS = reader.Line.Skip(HeaderWithExtendedHashesCount).ToArray();
|
||||
}
|
||||
rows.Add(row);
|
||||
}
|
||||
|
||||
// Assign the rows to the Dat and return
|
||||
dat.Row = rows.ToArray();
|
||||
return dat;
|
||||
}
|
||||
catch
|
||||
{
|
||||
// TODO: Handle logging the exception
|
||||
return default;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -816,6 +816,32 @@ namespace SabreTools.Test.Parser
|
||||
}
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData("test-csv-files1.csv", ',', 2)]
|
||||
[InlineData("test-csv-files2.csv", ',', 2)]
|
||||
[InlineData("test-ssv-files1.ssv", ';', 2)]
|
||||
[InlineData("test-ssv-files2.ssv", ';', 2)]
|
||||
[InlineData("test-tsv-files2.tsv", '\t', 2)]
|
||||
[InlineData("test-tsv-files1.tsv", '\t', 2)]
|
||||
public void SeparatedValueDeserializeTest(string path, char delim, long count)
|
||||
{
|
||||
// Open the file for reading
|
||||
string filename = System.IO.Path.Combine(Environment.CurrentDirectory, "TestData", path);
|
||||
|
||||
// Deserialize the file
|
||||
var dat = Serialization.SeparatedValue.Deserialize(filename, delim);
|
||||
|
||||
// Validate the values
|
||||
Assert.NotNull(dat);
|
||||
Assert.Equal(count, dat.Row.Length);
|
||||
|
||||
// Validate we're not missing any attributes or elements
|
||||
foreach (var rom in dat.Row ?? Array.Empty<Models.SeparatedValue.Row>())
|
||||
{
|
||||
Assert.Null(rom.ADDITIONAL_ELEMENTS);
|
||||
}
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData("test-softwarelist-files1.xml", 4531)]
|
||||
[InlineData("test-softwarelist-files2.xml", 2797)]
|
||||
|
||||
3
SabreTools.Test/TestData/test-csv-files1.csv
Normal file
3
SabreTools.Test/TestData/test-csv-files1.csv
Normal file
@@ -0,0 +1,3 @@
|
||||
File Name,Internal Name,Description,Game Name,Game Description,Type,Rom Name,Disk Name,Size,CRC,MD5,SHA1,SHA256,Nodump
|
||||
Original DatFile Name.xml,Original DatFile Name,Original DatFile,Game,A cool game,Rom,file.bin,,12345,0,d41d8cd98f00b204e9800998ecf8427e,da39a3ee5e6b4b0d3255bfef95601890afd80709,ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad,No
|
||||
Original DatFile Name.xml,Original DatFile Name,Original DatFile,Game,A cool game,Disk,,file.chd,,,,da39a3ee5e6b4b0d3255bfef95601890afd80709,,No
|
||||
|
3
SabreTools.Test/TestData/test-csv-files2.csv
Normal file
3
SabreTools.Test/TestData/test-csv-files2.csv
Normal file
@@ -0,0 +1,3 @@
|
||||
File Name,Internal Name,Description,Game Name,Game Description,Type,Rom Name,Disk Name,Size,CRC,MD5,SHA1,SHA256,SHA384,SHA512,SpamSum,Nodump
|
||||
Original DatFile Name.xml,Original DatFile Name,Original DatFile,Game,A cool game,Rom,file.bin,,12345,0,d41d8cd98f00b204e9800998ecf8427e,da39a3ee5e6b4b0d3255bfef95601890afd80709,ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad,cb00753f45a35e8bb5a03d699ac65007272c32ab0eded1631a8b605a43ff5bed8086072ba1e7cc2358baeca134c825a7,ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a2192992a274fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f,QXX,No
|
||||
Original DatFile Name.xml,Original DatFile Name,Original DatFile,Game,A cool game,Disk,,file.chd,,,,da39a3ee5e6b4b0d3255bfef95601890afd80709,,,,,No
|
||||
|
3
SabreTools.Test/TestData/test-ssv-files1.ssv
Normal file
3
SabreTools.Test/TestData/test-ssv-files1.ssv
Normal file
@@ -0,0 +1,3 @@
|
||||
File Name;Internal Name;Description;Game Name;Game Description;Type;Rom Name;Disk Name;Size;CRC;MD5;SHA1;SHA256;Nodump
|
||||
Original DatFile Name.xml;Original DatFile Name;Original DatFile;Game;A cool game;Rom;file.bin;;12345;0;d41d8cd98f00b204e9800998ecf8427e;da39a3ee5e6b4b0d3255bfef95601890afd80709;ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad;No
|
||||
Original DatFile Name.xml;Original DatFile Name;Original DatFile;Game;A cool game;Disk;;file.chd;;;;da39a3ee5e6b4b0d3255bfef95601890afd80709;;No
|
||||
3
SabreTools.Test/TestData/test-ssv-files2.ssv
Normal file
3
SabreTools.Test/TestData/test-ssv-files2.ssv
Normal file
@@ -0,0 +1,3 @@
|
||||
File Name;Internal Name;Description;Game Name;Game Description;Type;Rom Name;Disk Name;Size;CRC;MD5;SHA1;SHA256;SHA384;SHA512;SpamSum;Nodump
|
||||
Original DatFile Name.xml;Original DatFile Name;Original DatFile;Game;A cool game;Rom;file.bin;;12345;0;d41d8cd98f00b204e9800998ecf8427e;da39a3ee5e6b4b0d3255bfef95601890afd80709;ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad;cb00753f45a35e8bb5a03d699ac65007272c32ab0eded1631a8b605a43ff5bed8086072ba1e7cc2358baeca134c825a7;ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a2192992a274fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f;QXX;No
|
||||
Original DatFile Name.xml;Original DatFile Name;Original DatFile;Game;A cool game;Disk;;file.chd;;;;da39a3ee5e6b4b0d3255bfef95601890afd80709;;;;;No
|
||||
3
SabreTools.Test/TestData/test-tsv-files1.tsv
Normal file
3
SabreTools.Test/TestData/test-tsv-files1.tsv
Normal file
@@ -0,0 +1,3 @@
|
||||
File Name Internal Name Description Game Name Game Description Type Rom Name Disk Name Size CRC MD5 SHA1 SHA256 Nodump
|
||||
Original DatFile Name.xml Original DatFile Name Original DatFile Game A cool game Rom file.bin 12345 0 d41d8cd98f00b204e9800998ecf8427e da39a3ee5e6b4b0d3255bfef95601890afd80709 ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad No
|
||||
Original DatFile Name.xml Original DatFile Name Original DatFile Game A cool game Disk file.chd da39a3ee5e6b4b0d3255bfef95601890afd80709 No
|
||||
|
3
SabreTools.Test/TestData/test-tsv-files2.tsv
Normal file
3
SabreTools.Test/TestData/test-tsv-files2.tsv
Normal file
@@ -0,0 +1,3 @@
|
||||
File Name Internal Name Description Game Name Game Description Type Rom Name Disk Name Size CRC MD5 SHA1 SHA256 SHA384 SHA512 SpamSum Nodump
|
||||
Original DatFile Name.xml Original DatFile Name Original DatFile Game A cool game Rom file.bin 12345 0 d41d8cd98f00b204e9800998ecf8427e da39a3ee5e6b4b0d3255bfef95601890afd80709 ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad cb00753f45a35e8bb5a03d699ac65007272c32ab0eded1631a8b605a43ff5bed8086072ba1e7cc2358baeca134c825a7 ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a2192992a274fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f QXX No
|
||||
Original DatFile Name.xml Original DatFile Name Original DatFile Game A cool game Disk file.chd da39a3ee5e6b4b0d3255bfef95601890afd80709 No
|
||||
|
Reference in New Issue
Block a user