Compare commits

...

21 Commits
1.3.1 ... 1.4.1

Author SHA1 Message Date
Matt Nadareski
d265c14841 Bump version 2024-03-25 14:25:28 -04:00
Matt Nadareski
1148245226 Surface NE/LE/PE methods for other library use 2024-03-24 21:09:12 -04:00
Matt Nadareski
f53d9f94e6 Break if StringFileInfo child is total size 0 2024-03-22 23:46:05 -04:00
Matt Nadareski
4e3d832834 Ensure Listrom serializes to the correct model type 2024-03-19 15:47:13 -04:00
Matt Nadareski
0713dfafb2 Bump version 2024-03-12 16:35:45 -04:00
Matt Nadareski
c0d4f403c3 Update IO package 2024-03-12 16:34:32 -04:00
Matt Nadareski
5ed79166cf Update Models library 2024-03-12 16:29:05 -04:00
Matt Nadareski
17030cfb9f Fix Listxml type key issues 2024-03-12 12:58:27 -04:00
Matt Nadareski
530fa69d3c Fix OpenMSX cross-model serialization keys 2024-03-12 00:46:46 -04:00
Matt Nadareski
7a5956f599 Fix capitalization in RomCenter INI stream serializer 2024-03-11 23:08:10 -04:00
Matt Nadareski
5562768509 Fix separated value cross-model serialization 2024-03-11 22:47:38 -04:00
Matt Nadareski
aa538df229 All doctype overloads to take nullable objects 2024-03-11 22:31:40 -04:00
Matt Nadareski
b7b22cba32 Fix AttractMode writing 2024-03-11 14:52:32 -04:00
Matt Nadareski
fc489125d9 Fix serialization problem for listrom 2024-03-10 00:39:23 -05:00
Matt Nadareski
036589473d Fix serialziation problem for archive.org 2024-03-10 00:36:31 -05:00
Matt Nadareski
432ce85f89 Bump version 2024-03-05 11:16:22 -05:00
Matt Nadareski
438e8067eb Update SabreTools.IO 2024-03-05 11:12:59 -05:00
Matt Nadareski
9715507aaf Add nuget package and PR workflows 2024-02-27 19:17:20 -05:00
Matt Nadareski
b745d4b9f6 Update copyright year 2024-01-30 13:39:23 -05:00
Matt Nadareski
4271bd86b3 Bump version 2024-01-26 09:57:09 -05:00
Matt Nadareski
88de4be27b Fix too-long string values 2024-01-26 01:23:33 -05:00
19 changed files with 197 additions and 93 deletions

43
.github/workflows/build_nupkg.yml vendored Normal file
View File

@@ -0,0 +1,43 @@
name: Nuget Pack
on:
push:
branches: [ "main" ]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
submodules: recursive
- name: Setup .NET
uses: actions/setup-dotnet@v4
with:
dotnet-version: 8.0.x
- name: Restore dependencies
run: dotnet restore
- name: Pack
run: dotnet pack
- name: Upload build
uses: actions/upload-artifact@v4
with:
name: 'Nuget Package'
path: 'bin/Release/*.nupkg'
- name: Upload to rolling
uses: ncipollo/release-action@v1.14.0
with:
allowUpdates: True
artifacts: 'bin/Release/*.nupkg'
body: 'Last built commit: ${{ github.sha }}'
name: 'Rolling Release'
prerelease: True
replacesArtifacts: True
tag: "rolling"
updateOnlyUnreleased: True

17
.github/workflows/check_pr.yml vendored Normal file
View File

@@ -0,0 +1,17 @@
name: Build PR
on: [pull_request]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup .NET
uses: actions/setup-dotnet@v4
with:
dotnet-version: 8.0.x
- name: Build
run: dotnet build

View File

@@ -10,7 +10,7 @@ namespace SabreTools.Serialization.CrossModel
{
if (item == null)
return null;
var metadataFile = new Models.Metadata.MetadataFile
{
[Models.Metadata.MetadataFile.HeaderKey] = ConvertHeaderToInternalModel(item),
@@ -45,10 +45,12 @@ namespace SabreTools.Serialization.CrossModel
/// </summary>
private static Models.Metadata.Machine ConvertMachineToInternalModel(Models.ArchiveDotOrg.File? item)
{
var machine = new Models.Metadata.Machine
{
[Models.Metadata.Machine.RomKey] = ConvertToInternalModel(item),
};
var machine = new Models.Metadata.Machine();
var rom = ConvertToInternalModel(item);
if (rom != null)
machine[Models.Metadata.Machine.RomKey] = new Models.Metadata.Rom[] { rom };
return machine;
}

View File

@@ -65,8 +65,8 @@ namespace SabreTools.Serialization.CrossModel
datItems.Add(ConvertToInternalModel(file));
}
machine[Models.Metadata.Machine.DiskKey] = datItems.Where(i => i.ReadString(Models.Metadata.DatItem.TypeKey) == "disk")?.ToArray();
machine[Models.Metadata.Machine.RomKey] = datItems.Where(i => i.ReadString(Models.Metadata.DatItem.TypeKey) == "rom")?.ToArray();
machine[Models.Metadata.Machine.DiskKey] = datItems.Where(i => i.ReadString(Models.Metadata.DatItem.TypeKey) == "disk").Select(d => d as Models.Metadata.Disk).ToArray();
machine[Models.Metadata.Machine.RomKey] = datItems.Where(i => i.ReadString(Models.Metadata.DatItem.TypeKey) == "rom").Select(d => d as Models.Metadata.Rom).ToArray();
}
return machine;
@@ -81,6 +81,7 @@ namespace SabreTools.Serialization.CrossModel
{
var disk = new Models.Metadata.Disk
{
[Models.Metadata.DatItem.TypeKey] = "disk",
[Models.Metadata.Disk.NameKey] = item.Name,
[Models.Metadata.Disk.MD5Key] = item.MD5,
[Models.Metadata.Disk.SHA1Key] = item.SHA1,
@@ -97,6 +98,7 @@ namespace SabreTools.Serialization.CrossModel
{
var rom = new Models.Metadata.Rom
{
[Models.Metadata.DatItem.TypeKey] = "rom",
[Models.Metadata.Rom.NameKey] = item.Name,
[Models.Metadata.Rom.SizeKey] = item.Size,
[Models.Metadata.Rom.CRCKey] = item.CRC,

View File

@@ -308,7 +308,7 @@ namespace SabreTools.Serialization.CrossModel
{
Name = item.ReadString(Models.Metadata.Chip.NameKey),
Tag = item.ReadString(Models.Metadata.Chip.TagKey),
Type = item.ReadString(Models.Metadata.Chip.TypeKey),
Type = item.ReadString(Models.Metadata.Chip.ChipTypeKey),
SoundOnly = item.ReadString(Models.Metadata.Chip.SoundOnlyKey),
Clock = item.ReadString(Models.Metadata.Chip.ClockKey),
};
@@ -407,7 +407,7 @@ namespace SabreTools.Serialization.CrossModel
{
var control = new Control
{
Type = item.ReadString(Models.Metadata.Control.TypeKey),
Type = item.ReadString(Models.Metadata.Control.ControlTypeKey),
Player = item.ReadString(Models.Metadata.Control.PlayerKey),
Buttons = item.ReadString(Models.Metadata.Control.ButtonsKey),
ReqButtons = item.ReadString(Models.Metadata.Control.ReqButtonsKey),
@@ -430,7 +430,7 @@ namespace SabreTools.Serialization.CrossModel
{
var device = new Device
{
Type = item.ReadString(Models.Metadata.Device.TypeKey),
Type = item.ReadString(Models.Metadata.Device.DeviceTypeKey),
Tag = item.ReadString(Models.Metadata.Device.TagKey),
FixedImage = item.ReadString(Models.Metadata.Device.FixedImageKey),
Mandatory = item.ReadString(Models.Metadata.Device.MandatoryKey),
@@ -563,7 +563,7 @@ namespace SabreTools.Serialization.CrossModel
var display = new Display
{
Tag = item.ReadString(Models.Metadata.Display.TagKey),
Type = item.ReadString(Models.Metadata.Display.TypeKey),
Type = item.ReadString(Models.Metadata.Display.DisplayTypeKey),
Rotate = item.ReadString(Models.Metadata.Display.RotateKey),
FlipX = item.ReadString(Models.Metadata.Display.FlipXKey),
Width = item.ReadString(Models.Metadata.Display.WidthKey),
@@ -621,7 +621,7 @@ namespace SabreTools.Serialization.CrossModel
{
var feature = new Feature
{
Type = item.ReadString(Models.Metadata.Feature.TypeKey),
Type = item.ReadString(Models.Metadata.Feature.FeatureTypeKey),
Status = item.ReadString(Models.Metadata.Feature.StatusKey),
Overall = item.ReadString(Models.Metadata.Feature.OverallKey),
};

View File

@@ -264,7 +264,7 @@ namespace SabreTools.Serialization.CrossModel
{
[Models.Metadata.Chip.NameKey] = item.Name,
[Models.Metadata.Chip.TagKey] = item.Tag,
[Models.Metadata.Chip.TypeKey] = item.Type,
[Models.Metadata.Chip.ChipTypeKey] = item.Type,
[Models.Metadata.Chip.SoundOnlyKey] = item.SoundOnly,
[Models.Metadata.Chip.ClockKey] = item.Clock,
};
@@ -359,7 +359,7 @@ namespace SabreTools.Serialization.CrossModel
{
var control = new Models.Metadata.Control
{
[Models.Metadata.Control.TypeKey] = item.Type,
[Models.Metadata.Control.ControlTypeKey] = item.Type,
[Models.Metadata.Control.PlayerKey] = item.Player,
[Models.Metadata.Control.ButtonsKey] = item.Buttons,
[Models.Metadata.Control.ReqButtonsKey] = item.ReqButtons,
@@ -382,7 +382,7 @@ namespace SabreTools.Serialization.CrossModel
{
var device = new Models.Metadata.Device
{
[Models.Metadata.Device.TypeKey] = item.Type,
[Models.Metadata.Device.DeviceTypeKey] = item.Type,
[Models.Metadata.Device.TagKey] = item.Tag,
[Models.Metadata.Device.FixedImageKey] = item.FixedImage,
[Models.Metadata.Device.MandatoryKey] = item.Mandatory,
@@ -509,7 +509,7 @@ namespace SabreTools.Serialization.CrossModel
var display = new Models.Metadata.Display
{
[Models.Metadata.Display.TagKey] = item.Tag,
[Models.Metadata.Display.TypeKey] = item.Type,
[Models.Metadata.Display.DisplayTypeKey] = item.Type,
[Models.Metadata.Display.RotateKey] = item.Rotate,
[Models.Metadata.Display.FlipXKey] = item.FlipX,
[Models.Metadata.Display.WidthKey] = item.Width,
@@ -567,7 +567,7 @@ namespace SabreTools.Serialization.CrossModel
{
var feature = new Models.Metadata.Feature
{
[Models.Metadata.Feature.TypeKey] = item.Type,
[Models.Metadata.Feature.FeatureTypeKey] = item.Type,
[Models.Metadata.Feature.StatusKey] = item.Status,
[Models.Metadata.Feature.OverallKey] = item.Overall,
};

View File

@@ -100,7 +100,7 @@ namespace SabreTools.Serialization.CrossModel
var megaRom = new MegaRom
{
Start = item.ReadString(Models.Metadata.Rom.StartKey),
Type = item.ReadString(Models.Metadata.Rom.TypeKey),
Type = item.ReadString(Models.Metadata.Rom.OpenMSXType),
Hash = item.ReadString(Models.Metadata.Rom.SHA1Key),
Remark = item.ReadString(Models.Metadata.Rom.RemarkKey),
};
@@ -128,7 +128,7 @@ namespace SabreTools.Serialization.CrossModel
var rom = new Rom
{
Start = item.ReadString(Models.Metadata.Rom.StartKey),
Type = item.ReadString(Models.Metadata.Rom.TypeKey),
Type = item.ReadString(Models.Metadata.Rom.OpenMSXType),
Hash = item.ReadString(Models.Metadata.Rom.SHA1Key),
Remark = item.ReadString(Models.Metadata.Rom.RemarkKey),
};
@@ -143,7 +143,7 @@ namespace SabreTools.Serialization.CrossModel
var sccPlusCart = new SCCPlusCart
{
Start = item.ReadString(Models.Metadata.Rom.StartKey),
Type = item.ReadString(Models.Metadata.Rom.TypeKey),
Type = item.ReadString(Models.Metadata.Rom.OpenMSXType),
Hash = item.ReadString(Models.Metadata.Rom.SHA1Key),
Remark = item.ReadString(Models.Metadata.Rom.RemarkKey),
};

View File

@@ -118,7 +118,7 @@ namespace SabreTools.Serialization.CrossModel
var rom = new Models.Metadata.Rom
{
[Models.Metadata.Rom.StartKey] = item.Start,
[Models.Metadata.Rom.TypeKey] = item.Type,
[Models.Metadata.Rom.OpenMSXType] = item.Type,
[Models.Metadata.Rom.SHA1Key] = item.Hash,
[Models.Metadata.Rom.RemarkKey] = item.Remark,
};

View File

@@ -21,7 +21,7 @@ namespace SabreTools.Serialization.CrossModel
{
metadataFile.Row = machines
.Where(m => m != null)
.SelectMany(ConvertMachineFromInternalModel)
.SelectMany(m => ConvertMachineFromInternalModel(m, header))
.ToArray();
}
@@ -43,7 +43,7 @@ namespace SabreTools.Serialization.CrossModel
/// <summary>
/// Convert from <cref="Models.Metadata.Machine"/> to an array of <cref="Models.SeparatedValue.Row"/>
/// </summary>
private static Row[] ConvertMachineFromInternalModel(Models.Metadata.Machine item)
private static Row[] ConvertMachineFromInternalModel(Models.Metadata.Machine item, Models.Metadata.Header? header)
{
var rowItems = new List<Row>();
@@ -52,7 +52,7 @@ namespace SabreTools.Serialization.CrossModel
{
rowItems.AddRange(roms
.Where(r => r != null)
.Select(rom => ConvertFromInternalModel(rom, item)));
.Select(rom => ConvertFromInternalModel(rom, item, header)));
}
var disks = item.Read<Models.Metadata.Disk[]>(Models.Metadata.Machine.DiskKey);
@@ -60,7 +60,7 @@ namespace SabreTools.Serialization.CrossModel
{
rowItems.AddRange(disks
.Where(d => d != null)
.Select(disk => ConvertFromInternalModel(disk, item)));
.Select(disk => ConvertFromInternalModel(disk, item, header)));
}
var media = item.Read<Models.Metadata.Media[]>(Models.Metadata.Machine.MediaKey);
@@ -68,7 +68,7 @@ namespace SabreTools.Serialization.CrossModel
{
rowItems.AddRange(media
.Where(m => m != null)
.Select(medium => ConvertFromInternalModel(medium, item)));
.Select(medium => ConvertFromInternalModel(medium, item, header)));
}
return rowItems.ToArray();
@@ -77,16 +77,26 @@ namespace SabreTools.Serialization.CrossModel
/// <summary>
/// Convert from <cref="Models.Metadata.Disk"/> to <cref="Models.SeparatedValue.Row"/>
/// </summary>
private static Row ConvertFromInternalModel(Models.Metadata.Disk item, Models.Metadata.Machine parent)
private static Row ConvertFromInternalModel(Models.Metadata.Disk item, Models.Metadata.Machine parent, Models.Metadata.Header? header)
{
var row = new Row
{
FileName = header?.ReadString("FILENAME"), // TODO: Make this an actual key to retrieve
InternalName = header?.ReadString(Models.Metadata.Header.NameKey),
Description = header?.ReadString(Models.Metadata.Header.DescriptionKey),
GameName = parent.ReadString(Models.Metadata.Machine.NameKey),
Description = parent.ReadString(Models.Metadata.Machine.DescriptionKey),
GameDescription = parent.ReadString(Models.Metadata.Machine.DescriptionKey),
Type = "disk",
RomName = null,
DiskName = item.ReadString(Models.Metadata.Disk.NameKey),
Size = null,
CRC = null,
MD5 = item.ReadString(Models.Metadata.Disk.MD5Key),
SHA1 = item.ReadString(Models.Metadata.Disk.SHA1Key),
SHA256 = null,
SHA384 = null,
SHA512 = null,
SpamSum = null,
Status = item.ReadString(Models.Metadata.Disk.StatusKey),
};
return row;
@@ -95,17 +105,25 @@ namespace SabreTools.Serialization.CrossModel
/// <summary>
/// Convert from <cref="Models.Metadata.Media"/> to <cref="Models.SeparatedValue.Row"/>
/// </summary>
private static Row ConvertFromInternalModel(Models.Metadata.Media item, Models.Metadata.Machine parent)
private static Row ConvertFromInternalModel(Models.Metadata.Media item, Models.Metadata.Machine parent, Models.Metadata.Header? header)
{
var row = new Row
{
FileName = header?.ReadString("FILENAME"), // TODO: Make this an actual key to retrieve
InternalName = header?.ReadString(Models.Metadata.Header.NameKey),
Description = header?.ReadString(Models.Metadata.Header.DescriptionKey),
GameName = parent.ReadString(Models.Metadata.Machine.NameKey),
Description = parent.ReadString(Models.Metadata.Machine.DescriptionKey),
GameDescription = parent.ReadString(Models.Metadata.Machine.DescriptionKey),
Type = "media",
RomName = null,
DiskName = item.ReadString(Models.Metadata.Media.NameKey),
Size = null,
CRC = null,
MD5 = item.ReadString(Models.Metadata.Media.MD5Key),
SHA1 = item.ReadString(Models.Metadata.Media.SHA1Key),
SHA256 = item.ReadString(Models.Metadata.Media.SHA256Key),
SHA384 = null,
SHA512 = null,
SpamSum = item.ReadString(Models.Metadata.Media.SpamSumKey),
};
return row;
@@ -114,14 +132,18 @@ namespace SabreTools.Serialization.CrossModel
/// <summary>
/// Convert from <cref="Models.Metadata.Rom"/> to <cref="Models.SeparatedValue.Row"/>
/// </summary>
private static Row ConvertFromInternalModel(Models.Metadata.Rom item, Models.Metadata.Machine parent)
private static Row ConvertFromInternalModel(Models.Metadata.Rom item, Models.Metadata.Machine parent, Models.Metadata.Header? header)
{
var row = new Row
{
GameName = parent?.ReadString(Models.Metadata.Machine.NameKey),
Description = parent?.ReadString(Models.Metadata.Machine.DescriptionKey),
FileName = header?.ReadString("FILENAME"), // TODO: Make this an actual key to retrieve
InternalName = header?.ReadString(Models.Metadata.Header.NameKey),
Description = header?.ReadString(Models.Metadata.Header.DescriptionKey),
GameName = parent.ReadString(Models.Metadata.Machine.NameKey),
GameDescription = parent.ReadString(Models.Metadata.Machine.DescriptionKey),
Type = "rom",
RomName = item.ReadString(Models.Metadata.Rom.NameKey),
DiskName = null,
Size = item.ReadString(Models.Metadata.Rom.SizeKey),
CRC = item.ReadString(Models.Metadata.Rom.CRCKey),
MD5 = item.ReadString(Models.Metadata.Rom.MD5Key),

View File

@@ -1280,6 +1280,7 @@ namespace SabreTools.Serialization
{
var stringData = new StringData();
int dataStartOffset = offset;
stringData.Length = data.ReadUInt16(ref offset);
stringData.ValueLength = data.ReadUInt16(ref offset);
stringData.ResourceType = (VersionResourceType)data.ReadUInt16(ref offset);
@@ -1294,7 +1295,8 @@ namespace SabreTools.Serialization
if (stringData.ValueLength > 0)
{
byte[]? valueBytes = data.ReadBytes(ref offset, stringData.ValueLength * sizeof(ushort));
int bytesReadable = Math.Min(stringData.ValueLength * sizeof(ushort), stringData.Length - (offset - dataStartOffset));
byte[]? valueBytes = data.ReadBytes(ref offset, bytesReadable);
if (valueBytes != null)
stringData.Value = Encoding.Unicode.GetString(valueBytes);
}
@@ -1307,6 +1309,8 @@ namespace SabreTools.Serialization
}
stringTableChildren.Add(stringData);
if (stringData.Length == 0 && stringData.ValueLength == 0)
break;
}
stringTable.Children = [.. stringTableChildren];

View File

@@ -5,7 +5,7 @@ namespace SabreTools.Serialization.Files
public partial class Logiqx : XmlFile<Datafile>
{
/// <inheritdoc cref="Serialize(Datafile, string, string?, string?, string?, string?)" />
public bool SerializeToFileWithDocType(Datafile obj, string path)
public bool SerializeToFileWithDocType(Datafile? obj, string path)
=> Serialize(obj, path, Serialization.Logiqx.DocTypeName, Serialization.Logiqx.DocTypePubId, Serialization.Logiqx.DocTypeSysId, Serialization.Logiqx.DocTypeSysId);
}
}

View File

@@ -5,7 +5,7 @@ namespace SabreTools.Serialization.Files
public partial class OpenMSX : XmlFile<SoftwareDb>
{
/// <inheritdoc cref="Serialize(SoftwareDb, string, string?, string?, string?, string?)" />
public bool SerializeToFileWithDocType(SoftwareDb obj, string path)
public bool SerializeToFileWithDocType(SoftwareDb? obj, string path)
=> Serialize(obj, path, Serialization.OpenMSX.DocTypeName, Serialization.OpenMSX.DocTypePubId, Serialization.OpenMSX.DocTypeSysId, Serialization.OpenMSX.DocTypeSysId);
}
}

View File

@@ -3,7 +3,7 @@ namespace SabreTools.Serialization.Files
public partial class SoftwareList : XmlFile<Models.SoftwareList.SoftwareList>
{
/// <inheritdoc cref="SerializeToFile(Models.SoftwareList.SoftwareList, string, string?, string?, string?, string?)" />
public bool SerializeToFileWithDocType(Models.SoftwareList.SoftwareList obj, string path)
public bool SerializeToFileWithDocType(Models.SoftwareList.SoftwareList? obj, string path)
=> Serialize(obj, path, Serialization.SoftawreList.DocTypeName, Serialization.SoftawreList.DocTypePubId, Serialization.SoftawreList.DocTypeSysId, Serialization.SoftawreList.DocTypeSysId);
}
}

View File

@@ -8,12 +8,12 @@
<LangVersion>latest</LangVersion>
<Nullable>enable</Nullable>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
<Version>1.3.1</Version>
<Version>1.4.1</Version>
<!-- Package Properties -->
<Authors>Matt Nadareski</Authors>
<Description>Serialization and deserialization helpers for various types</Description>
<Copyright>Copyright (c) Matt Nadareski 2019-2023</Copyright>
<Copyright>Copyright (c) Matt Nadareski 2019-2024</Copyright>
<PackageProjectUrl>https://github.com/SabreTools/</PackageProjectUrl>
<PackageReadmeFile>README.md</PackageReadmeFile>
<RepositoryUrl>https://github.com/SabreTools/SabreTools.Serialization</RepositoryUrl>
@@ -27,8 +27,8 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="SabreTools.IO" Version="1.3.0" />
<PackageReference Include="SabreTools.Models" Version="1.3.0" />
<PackageReference Include="SabreTools.IO" Version="1.3.2" />
<PackageReference Include="SabreTools.Models" Version="1.4.0" />
</ItemGroup>
</Project>

View File

@@ -28,6 +28,7 @@ namespace SabreTools.Serialization.Streams
// TODO: Include flag to write out long or short header
// Write the short header
writer.WriteString(Serialization.AttractMode.HeaderWithoutRomname); // TODO: Convert to array of values
writer.WriteLine();
// Write out the rows, if they exist
WriteRows(obj.Row, writer);

View File

@@ -424,7 +424,7 @@ namespace SabreTools.Serialization.Streams
/// </summary>
/// <param name="data">Stream to parse</param>
/// <returns>Filled information block on success, null on error</returns>
private static InformationBlock? ParseInformationBlock(Stream data)
public static InformationBlock? ParseInformationBlock(Stream data)
{
// TODO: Use marshalling here instead of building
var informationBlock = new InformationBlock();
@@ -491,7 +491,7 @@ namespace SabreTools.Serialization.Streams
/// </summary>
/// <param name="data">Stream to parse</param>
/// <returns>Filled object table entry on success, null on error</returns>
private static ObjectTableEntry ParseObjectTableEntry(Stream data)
public static ObjectTableEntry ParseObjectTableEntry(Stream data)
{
// TODO: Use marshalling here instead of building
var entry = new ObjectTableEntry();
@@ -511,7 +511,7 @@ namespace SabreTools.Serialization.Streams
/// </summary>
/// <param name="data">Stream to parse</param>
/// <returns>Filled object page map entry on success, null on error</returns>
private static ObjectPageMapEntry ParseObjectPageMapEntry(Stream data)
public static ObjectPageMapEntry ParseObjectPageMapEntry(Stream data)
{
// TODO: Use marshalling here instead of building
var entry = new ObjectPageMapEntry();
@@ -528,7 +528,7 @@ namespace SabreTools.Serialization.Streams
/// </summary>
/// <param name="data">Stream to parse</param>
/// <returns>Filled resource table entry on success, null on error</returns>
private static ResourceTableEntry ParseResourceTableEntry(Stream data)
public static ResourceTableEntry ParseResourceTableEntry(Stream data)
{
// TODO: Use marshalling here instead of building
var entry = new ResourceTableEntry();
@@ -547,7 +547,7 @@ namespace SabreTools.Serialization.Streams
/// </summary>
/// <param name="data">Stream to parse</param>
/// <returns>Filled resident names table entry on success, null on error</returns>
private static ResidentNamesTableEntry ParseResidentNamesTableEntry(Stream data)
public static ResidentNamesTableEntry ParseResidentNamesTableEntry(Stream data)
{
// TODO: Use marshalling here instead of building
var entry = new ResidentNamesTableEntry();
@@ -569,7 +569,7 @@ namespace SabreTools.Serialization.Streams
/// </summary>
/// <param name="data">Stream to parse</param>
/// <returns>Filled entry table bundle on success, null on error</returns>
private static EntryTableBundle? ParseEntryTableBundle(Stream data)
public static EntryTableBundle? ParseEntryTableBundle(Stream data)
{
// TODO: Use marshalling here instead of building
var bundle = new EntryTableBundle();
@@ -632,7 +632,7 @@ namespace SabreTools.Serialization.Streams
/// </summary>
/// <param name="data">Stream to parse</param>
/// <returns>Filled module format directives table entry on success, null on error</returns>
private static ModuleFormatDirectivesTableEntry ParseModuleFormatDirectivesTableEntry(Stream data)
public static ModuleFormatDirectivesTableEntry ParseModuleFormatDirectivesTableEntry(Stream data)
{
// TODO: Use marshalling here instead of building
var entry = new ModuleFormatDirectivesTableEntry();
@@ -649,7 +649,7 @@ namespace SabreTools.Serialization.Streams
/// </summary>
/// <param name="data">Stream to parse</param>
/// <returns>Filled verify record directive table entry on success, null on error</returns>
private static VerifyRecordDirectiveTableEntry ParseVerifyRecordDirectiveTableEntry(Stream data)
public static VerifyRecordDirectiveTableEntry ParseVerifyRecordDirectiveTableEntry(Stream data)
{
// TODO: Use marshalling here instead of building
var entry = new VerifyRecordDirectiveTableEntry();
@@ -670,7 +670,7 @@ namespace SabreTools.Serialization.Streams
/// </summary>
/// <param name="data">Stream to parse</param>
/// <returns>Filled fix-up page table entry on success, null on error</returns>
private static FixupPageTableEntry ParseFixupPageTableEntry(Stream data)
public static FixupPageTableEntry ParseFixupPageTableEntry(Stream data)
{
// TODO: Use marshalling here instead of building
var entry = new FixupPageTableEntry();
@@ -685,7 +685,7 @@ namespace SabreTools.Serialization.Streams
/// </summary>
/// <param name="data">Stream to parse</param>
/// <returns>Filled fix-up record table entry on success, null on error</returns>
private static FixupRecordTableEntry? ParseFixupRecordTableEntry(Stream data)
public static FixupRecordTableEntry? ParseFixupRecordTableEntry(Stream data)
{
// TODO: Use marshalling here instead of building
var entry = new FixupRecordTableEntry();
@@ -904,7 +904,7 @@ namespace SabreTools.Serialization.Streams
/// </summary>
/// <param name="data">Stream to parse</param>
/// <returns>Filled import module name table entry on success, null on error</returns>
private static ImportModuleNameTableEntry ParseImportModuleNameTableEntry(Stream data)
public static ImportModuleNameTableEntry ParseImportModuleNameTableEntry(Stream data)
{
// TODO: Use marshalling here instead of building
var entry = new ImportModuleNameTableEntry();
@@ -925,7 +925,7 @@ namespace SabreTools.Serialization.Streams
/// </summary>
/// <param name="data">Stream to parse</param>
/// <returns>Filled import module name table entry on success, null on error</returns>
private static ImportModuleProcedureNameTableEntry ParseImportModuleProcedureNameTableEntry(Stream data)
public static ImportModuleProcedureNameTableEntry ParseImportModuleProcedureNameTableEntry(Stream data)
{
// TODO: Use marshalling here instead of building
var entry = new ImportModuleProcedureNameTableEntry();
@@ -946,7 +946,7 @@ namespace SabreTools.Serialization.Streams
/// </summary>
/// <param name="data">Stream to parse</param>
/// <returns>Filled per-page checksum table entry on success, null on error</returns>
private static PerPageChecksumTableEntry ParsePerPageChecksumTableEntry(Stream data)
public static PerPageChecksumTableEntry ParsePerPageChecksumTableEntry(Stream data)
{
// TODO: Use marshalling here instead of building
var entry = new PerPageChecksumTableEntry();
@@ -961,7 +961,7 @@ namespace SabreTools.Serialization.Streams
/// </summary>
/// <param name="data">Stream to parse</param>
/// <returns>Filled non-resident names table entry on success, null on error</returns>
private static NonResidentNamesTableEntry ParseNonResidentNameTableEntry(Stream data)
public static NonResidentNamesTableEntry ParseNonResidentNameTableEntry(Stream data)
{
// TODO: Use marshalling here instead of building
var entry = new NonResidentNamesTableEntry();
@@ -984,7 +984,7 @@ namespace SabreTools.Serialization.Streams
/// <param name="data">Stream to parse</param>
/// <param name="size">Total size of the debug information</param>
/// <returns>Filled debug information on success, null on error</returns>
private static DebugInformation? ParseDebugInformation(Stream data, long size)
public static DebugInformation? ParseDebugInformation(Stream data, long size)
{
// TODO: Use marshalling here instead of building
var debugInformation = new DebugInformation();

View File

@@ -213,7 +213,7 @@ namespace SabreTools.Serialization.Streams
/// </summary>
/// <param name="data">Stream to parse</param>
/// <returns>Filled executable header on success, null on error</returns>
private static ExecutableHeader? ParseExecutableHeader(Stream data)
public static ExecutableHeader? ParseExecutableHeader(Stream data)
{
// TODO: Use marshalling here instead of building
var header = new ExecutableHeader();
@@ -266,7 +266,7 @@ namespace SabreTools.Serialization.Streams
/// <param name="data">Stream to parse</param>
/// <param name="count">Number of segment table entries to read</param>
/// <returns>Filled segment table on success, null on error</returns>
private static SegmentTableEntry[] ParseSegmentTable(Stream data, int count)
public static SegmentTableEntry[] ParseSegmentTable(Stream data, int count)
{
// TODO: Use marshalling here instead of building
var segmentTable = new SegmentTableEntry[count];
@@ -290,7 +290,7 @@ namespace SabreTools.Serialization.Streams
/// <param name="data">Stream to parse</param>
/// <param name="count">Number of resource table entries to read</param>
/// <returns>Filled resource table on success, null on error</returns>
private static ResourceTable ParseResourceTable(Stream data, int count)
public static ResourceTable ParseResourceTable(Stream data, int count)
{
long initialOffset = data.Position;
@@ -355,7 +355,7 @@ namespace SabreTools.Serialization.Streams
/// <param name="data">Stream to parse</param>
/// <param name="endOffset">First address not part of the resident-name table</param>
/// <returns>Filled resident-name table on success, null on error</returns>
private static ResidentNameTableEntry[] ParseResidentNameTable(Stream data, int endOffset)
public static ResidentNameTableEntry[] ParseResidentNameTable(Stream data, int endOffset)
{
// TODO: Use marshalling here instead of building
var residentNameTable = new List<ResidentNameTableEntry>();
@@ -378,7 +378,7 @@ namespace SabreTools.Serialization.Streams
/// <param name="data">Stream to parse</param>
/// <param name="count">Number of module-reference table entries to read</param>
/// <returns>Filled module-reference table on success, null on error</returns>
private static ModuleReferenceTableEntry[] ParseModuleReferenceTable(Stream data, int count)
public static ModuleReferenceTableEntry[] ParseModuleReferenceTable(Stream data, int count)
{
// TODO: Use marshalling here instead of building
var moduleReferenceTable = new ModuleReferenceTableEntry[count];
@@ -399,7 +399,7 @@ namespace SabreTools.Serialization.Streams
/// <param name="data">Stream to parse</param>
/// <param name="endOffset">First address not part of the imported-name table</param>
/// <returns>Filled imported-name table on success, null on error</returns>
private static Dictionary<ushort, ImportedNameTableEntry?> ParseImportedNameTable(Stream data, int endOffset)
public static Dictionary<ushort, ImportedNameTableEntry?> ParseImportedNameTable(Stream data, int endOffset)
{
// TODO: Use marshalling here instead of building
var importedNameTable = new Dictionary<ushort, ImportedNameTableEntry?>();
@@ -422,7 +422,7 @@ namespace SabreTools.Serialization.Streams
/// <param name="data">Stream to parse</param>
/// <param name="endOffset">First address not part of the entry table</param>
/// <returns>Filled entry table on success, null on error</returns>
private static EntryTableBundle[] ParseEntryTable(Stream data, int endOffset)
public static EntryTableBundle[] ParseEntryTable(Stream data, int endOffset)
{
// TODO: Use marshalling here instead of building
var entryTable = new List<EntryTableBundle>();
@@ -461,7 +461,7 @@ namespace SabreTools.Serialization.Streams
/// <param name="data">Stream to parse</param>
/// <param name="endOffset">First address not part of the nonresident-name table</param>
/// <returns>Filled nonresident-name table on success, null on error</returns>
private static NonResidentNameTableEntry[] ParseNonResidentNameTable(Stream data, int endOffset)
public static NonResidentNameTableEntry[] ParseNonResidentNameTable(Stream data, int endOffset)
{
// TODO: Use marshalling here instead of building
var residentNameTable = new List<NonResidentNameTableEntry>();

View File

@@ -292,7 +292,7 @@ namespace SabreTools.Serialization.Streams
/// </summary>
/// <param name="data">Stream to parse</param>
/// <returns>Filled executable header on success, null on error</returns>
private static COFFFileHeader ParseCOFFFileHeader(Stream data)
public static COFFFileHeader ParseCOFFFileHeader(Stream data)
{
// TODO: Use marshalling here instead of building
var fileHeader = new COFFFileHeader();
@@ -314,7 +314,7 @@ namespace SabreTools.Serialization.Streams
/// <param name="data">Stream to parse</param>
/// <param name="optionalSize">Size of the optional header</param>
/// <returns>Filled optional header on success, null on error</returns>
private static OptionalHeader ParseOptionalHeader(Stream data, int optionalSize)
public static OptionalHeader ParseOptionalHeader(Stream data, int optionalSize)
{
long initialOffset = data.Position;
@@ -484,7 +484,7 @@ namespace SabreTools.Serialization.Streams
/// <param name="data">Stream to parse</param>
/// <param name="count">Number of section table entries to read</param>
/// <returns>Filled section table on success, null on error</returns>
private static SectionHeader[] ParseSectionTable(Stream data, int count)
public static SectionHeader[] ParseSectionTable(Stream data, int count)
{
// TODO: Use marshalling here instead of building
var sectionTable = new SectionHeader[count];
@@ -524,7 +524,7 @@ namespace SabreTools.Serialization.Streams
/// <param name="data">Stream to parse</param>
/// <param name="count">Number of COFF symbol table entries to read</param>
/// <returns>Filled COFF symbol table on success, null on error</returns>
private static COFFSymbolTableEntry[] ParseCOFFSymbolTable(Stream data, uint count)
public static COFFSymbolTableEntry[] ParseCOFFSymbolTable(Stream data, uint count)
{
// TODO: Use marshalling here instead of building
var coffSymbolTable = new COFFSymbolTableEntry[count];
@@ -681,7 +681,7 @@ namespace SabreTools.Serialization.Streams
/// </summary>
/// <param name="data">Stream to parse</param>
/// <returns>Filled COFF string table on success, null on error</returns>
private static COFFStringTable ParseCOFFStringTable(Stream data)
public static COFFStringTable ParseCOFFStringTable(Stream data)
{
// TODO: Use marshalling here instead of building
var coffStringTable = new COFFStringTable();
@@ -712,7 +712,7 @@ namespace SabreTools.Serialization.Streams
/// <param name="data">Stream to parse</param>
/// <param name="endOffset">First address not part of the attribute certificate table</param>
/// <returns>Filled attribute certificate on success, null on error</returns>
private static AttributeCertificateTableEntry[] ParseAttributeCertificateTable(Stream data, int endOffset)
public static AttributeCertificateTableEntry[] ParseAttributeCertificateTable(Stream data, int endOffset)
{
var attributeCertificateTable = new List<AttributeCertificateTableEntry>();
@@ -743,7 +743,7 @@ namespace SabreTools.Serialization.Streams
/// </summary>
/// <param name="data">Stream to parse</param>
/// <returns>Filled delay-load directory table on success, null on error</returns>
private static DelayLoadDirectoryTable ParseDelayLoadDirectoryTable(Stream data)
public static DelayLoadDirectoryTable ParseDelayLoadDirectoryTable(Stream data)
{
// TODO: Use marshalling here instead of building
var delayLoadDirectoryTable = new DelayLoadDirectoryTable();
@@ -767,7 +767,7 @@ namespace SabreTools.Serialization.Streams
/// <param name="endOffset">First address not part of the base relocation table</param>
/// <param name="sections">Section table to use for virtual address translation</param>
/// <returns>Filled base relocation table on success, null on error</returns>
private static BaseRelocationBlock[] ParseBaseRelocationTable(Stream data, int endOffset, SectionHeader?[] sections)
public static BaseRelocationBlock[] ParseBaseRelocationTable(Stream data, int endOffset, SectionHeader?[] sections)
{
// TODO: Use marshalling here instead of building
var baseRelocationTable = new List<BaseRelocationBlock>();
@@ -808,7 +808,7 @@ namespace SabreTools.Serialization.Streams
/// <param name="endOffset">First address not part of the debug table</param>
/// <param name="sections">Section table to use for virtual address translation</param>
/// <returns>Filled debug table on success, null on error</returns>
private static DebugTable ParseDebugTable(Stream data, int endOffset, SectionHeader?[] sections)
public static DebugTable ParseDebugTable(Stream data, int endOffset, SectionHeader?[] sections)
{
// TODO: Use marshalling here instead of building
var debugTable = new DebugTable();
@@ -845,7 +845,7 @@ namespace SabreTools.Serialization.Streams
/// <param name="data">Stream to parse</param>
/// <param name="sections">Section table to use for virtual address translation</param>
/// <returns>Filled export table on success, null on error</returns>
private static ExportTable ParseExportTable(Stream data, SectionHeader?[] sections)
public static ExportTable ParseExportTable(Stream data, SectionHeader?[] sections)
{
// TODO: Use marshalling here instead of building
var exportTable = new ExportTable();
@@ -962,7 +962,7 @@ namespace SabreTools.Serialization.Streams
/// <param name="magic">Optional header magic number indicating PE32 or PE32+</param>
/// <param name="sections">Section table to use for virtual address translation</param>
/// <returns>Filled import table on success, null on error</returns>
private static ImportTable ParseImportTable(Stream data, OptionalHeaderMagicNumber magic, SectionHeader?[] sections)
public static ImportTable ParseImportTable(Stream data, OptionalHeaderMagicNumber magic, SectionHeader?[] sections)
{
// TODO: Use marshalling here instead of building
var importTable = new ImportTable();
@@ -1187,7 +1187,7 @@ namespace SabreTools.Serialization.Streams
/// <param name="sections">Section table to use for virtual address translation</param>
/// <param name="topLevel">Indicates if this is the top level or not</param>
/// <returns>Filled resource directory table on success, null on error</returns>
private static ResourceDirectoryTable? ParseResourceDirectoryTable(Stream data, long initialOffset, SectionHeader?[] sections, bool topLevel = false)
public static ResourceDirectoryTable? ParseResourceDirectoryTable(Stream data, long initialOffset, SectionHeader?[] sections, bool topLevel = false)
{
// TODO: Use marshalling here instead of building
var resourceDirectoryTable = new ResourceDirectoryTable();

View File

@@ -48,15 +48,22 @@ namespace SabreTools.Serialization.Streams
if (credits == null)
return;
writer.WriteSection("credits");
writer.WriteSection("CREDITS");
writer.WriteKeyValuePair("author", credits.Author);
writer.WriteKeyValuePair("version", credits.Version);
writer.WriteKeyValuePair("email", credits.Email);
writer.WriteKeyValuePair("homepage", credits.Homepage);
writer.WriteKeyValuePair("url", credits.Url);
writer.WriteKeyValuePair("date", credits.Date);
writer.WriteKeyValuePair("comment", credits.Comment);
if (credits.Author != null)
writer.WriteKeyValuePair("Author", credits.Author);
if (credits.Version != null)
writer.WriteKeyValuePair("Version", credits.Version);
if (credits.Email != null)
writer.WriteKeyValuePair("Email", credits.Email);
if (credits.Homepage != null)
writer.WriteKeyValuePair("Homepage", credits.Homepage);
if (credits.Url != null)
writer.WriteKeyValuePair("Url", credits.Url);
if (credits.Date != null)
writer.WriteKeyValuePair("Date", credits.Date);
if (credits.Comment != null)
writer.WriteKeyValuePair("Comment", credits.Comment);
writer.WriteLine();
writer.Flush();
@@ -73,12 +80,16 @@ namespace SabreTools.Serialization.Streams
if (dat == null)
return;
writer.WriteSection("dat");
writer.WriteSection("DAT");
writer.WriteKeyValuePair("version", dat.Version);
writer.WriteKeyValuePair("plugin", dat.Plugin);
writer.WriteKeyValuePair("split", dat.Split);
writer.WriteKeyValuePair("merge", dat.Merge);
if (dat.Version != null)
writer.WriteKeyValuePair("Version", dat.Version);
if (dat.Plugin != null)
writer.WriteKeyValuePair("Plugin", dat.Plugin);
if (dat.Split != null)
writer.WriteKeyValuePair("Split", dat.Split);
if (dat.Merge != null)
writer.WriteKeyValuePair("Merge", dat.Merge);
writer.WriteLine();
writer.Flush();
@@ -95,10 +106,12 @@ namespace SabreTools.Serialization.Streams
if (emulator == null)
return;
writer.WriteSection("emulator");
writer.WriteSection("EMULATOR");
writer.WriteKeyValuePair("refname", emulator.RefName);
writer.WriteKeyValuePair("version", emulator.Version);
if (emulator.RefName != null)
writer.WriteKeyValuePair("refname", emulator.RefName);
if (emulator.Version != null)
writer.WriteKeyValuePair("version", emulator.Version);
writer.WriteLine();
writer.Flush();
@@ -115,7 +128,7 @@ namespace SabreTools.Serialization.Streams
if (games?.Rom == null || !games.Rom.Any())
return;
writer.WriteSection("games");
writer.WriteSection("GAMES");
foreach (var rom in games.Rom)
{