diff --git a/SabreTools.Serialization/Extensions/PortableExecutable.cs b/SabreTools.Serialization/Extensions/PortableExecutable.cs
index 456885cb..ed865f3a 100644
--- a/SabreTools.Serialization/Extensions/PortableExecutable.cs
+++ b/SabreTools.Serialization/Extensions/PortableExecutable.cs
@@ -173,75 +173,6 @@ namespace SabreTools.Data.Extensions
}
}
- ///
- /// Read resource data as a font group
- ///
- /// Resource data entry to parse into a font group
- /// A filled font group on success, null on error
- public static FontGroupHeader? AsFontGroup(this Models.PortableExecutable.Resource.DataEntry? entry)
- {
- // If we have an invalid entry, just skip
- if (entry?.Data is null)
- return null;
-
- // Initialize the iterator
- int offset = 0;
-
- // Create the output object
- var fontGroupHeader = new FontGroupHeader();
-
- fontGroupHeader.NumberOfFonts = entry.Data.ReadUInt16LittleEndian(ref offset);
- if (fontGroupHeader.NumberOfFonts > 0)
- {
- fontGroupHeader.DE = new DirEntry[fontGroupHeader.NumberOfFonts];
- for (int i = 0; i < fontGroupHeader.NumberOfFonts; i++)
- {
- var dirEntry = new DirEntry();
-
- dirEntry.FontOrdinal = entry.Data.ReadUInt16LittleEndian(ref offset);
-
- dirEntry.Entry = new FontDirEntry();
- dirEntry.Entry.Version = entry.Data.ReadUInt16LittleEndian(ref offset);
- dirEntry.Entry.Size = entry.Data.ReadUInt32LittleEndian(ref offset);
- dirEntry.Entry.Copyright = entry.Data.ReadBytes(ref offset, 60);
- dirEntry.Entry.Type = entry.Data.ReadUInt16LittleEndian(ref offset);
- dirEntry.Entry.Points = entry.Data.ReadUInt16LittleEndian(ref offset);
- dirEntry.Entry.VertRes = entry.Data.ReadUInt16LittleEndian(ref offset);
- dirEntry.Entry.HorizRes = entry.Data.ReadUInt16LittleEndian(ref offset);
- dirEntry.Entry.Ascent = entry.Data.ReadUInt16LittleEndian(ref offset);
- dirEntry.Entry.InternalLeading = entry.Data.ReadUInt16LittleEndian(ref offset);
- dirEntry.Entry.ExternalLeading = entry.Data.ReadUInt16LittleEndian(ref offset);
- dirEntry.Entry.Italic = entry.Data.ReadByte(ref offset);
- dirEntry.Entry.Underline = entry.Data.ReadByte(ref offset);
- dirEntry.Entry.StrikeOut = entry.Data.ReadByte(ref offset);
- dirEntry.Entry.Weight = entry.Data.ReadUInt16LittleEndian(ref offset);
- dirEntry.Entry.CharSet = entry.Data.ReadByte(ref offset);
- dirEntry.Entry.PixWidth = entry.Data.ReadUInt16LittleEndian(ref offset);
- dirEntry.Entry.PixHeight = entry.Data.ReadUInt16LittleEndian(ref offset);
- dirEntry.Entry.PitchAndFamily = entry.Data.ReadByte(ref offset);
- dirEntry.Entry.AvgWidth = entry.Data.ReadUInt16LittleEndian(ref offset);
- dirEntry.Entry.MaxWidth = entry.Data.ReadUInt16LittleEndian(ref offset);
- dirEntry.Entry.FirstChar = entry.Data.ReadByte(ref offset);
- dirEntry.Entry.LastChar = entry.Data.ReadByte(ref offset);
- dirEntry.Entry.DefaultChar = entry.Data.ReadByte(ref offset);
- dirEntry.Entry.BreakChar = entry.Data.ReadByte(ref offset);
- dirEntry.Entry.WidthBytes = entry.Data.ReadUInt16LittleEndian(ref offset);
- dirEntry.Entry.Device = entry.Data.ReadUInt32LittleEndian(ref offset);
- dirEntry.Entry.Face = entry.Data.ReadUInt32LittleEndian(ref offset);
- dirEntry.Entry.Reserved = entry.Data.ReadUInt32LittleEndian(ref offset);
-
- // TODO: Determine how to read these two? Immediately after?
- dirEntry.Entry.DeviceName = entry.Data.ReadNullTerminatedAnsiString(ref offset) ?? string.Empty;
- dirEntry.Entry.FaceName = entry.Data.ReadNullTerminatedAnsiString(ref offset) ?? string.Empty;
-
- fontGroupHeader.DE[i] = dirEntry;
- }
- }
-
- // TODO: Implement entry parsing
- return fontGroupHeader;
- }
-
///
/// Read resource data as a string table resource
///
@@ -274,20 +205,6 @@ namespace SabreTools.Data.Extensions
return stringTable;
}
- ///
- /// Read resource data as a version info resource
- ///
- /// Resource data entry to parse into a version info resource
- /// A filled version info resource on success, null on error
- public static VersionInfo? AsVersionInfo(this Models.PortableExecutable.Resource.DataEntry? entry)
- {
- // If we have an invalid entry, just skip
- if (entry?.Data is null)
- return null;
-
- return Serialization.Readers.PortableExecutable.ParseVersionInfo(entry.Data);
- }
-
///
/// Parse a byte array into a ResourceHeader
///
diff --git a/SabreTools.Serialization/Readers/PortableExecutable.cs b/SabreTools.Serialization/Readers/PortableExecutable.cs
index 9db1f0f5..2fbf4d31 100644
--- a/SabreTools.Serialization/Readers/PortableExecutable.cs
+++ b/SabreTools.Serialization/Readers/PortableExecutable.cs
@@ -1287,6 +1287,22 @@ namespace SabreTools.Serialization.Readers
return obj;
}
+ ///
+ /// Parse a byte array into a DirEntry
+ ///
+ /// Data to parse
+ /// Offset into the byte array
+ /// A filled DirEntry on success, null on error
+ public static Data.Models.PortableExecutable.Resource.Entries.DirEntry ParseDirEntry(byte[] data, ref int offset)
+ {
+ var obj = new Data.Models.PortableExecutable.Resource.Entries.DirEntry();
+
+ obj.FontOrdinal = data.ReadUInt16LittleEndian(ref offset);
+ obj.Entry = ParseFontDirEntry(data, ref offset);
+
+ return obj;
+ }
+
///
/// Parse a Stream into a ExportAddressTable
///
@@ -1477,6 +1493,80 @@ namespace SabreTools.Serialization.Readers
return obj;
}
+ ///
+ /// Parse a byte array into a FontDirEntry
+ ///
+ /// Data to parse
+ /// Offset into the byte array
+ /// A filled FontDirEntry on success, null on error
+ public static Data.Models.PortableExecutable.Resource.Entries.FontDirEntry ParseFontDirEntry(byte[] data, ref int offset)
+ {
+ var obj = new Data.Models.PortableExecutable.Resource.Entries.FontDirEntry();
+
+ obj.Version = data.ReadUInt16LittleEndian(ref offset);
+ obj.Size = data.ReadUInt32LittleEndian(ref offset);
+ obj.Copyright = data.ReadBytes(ref offset, 60);
+ obj.Type = data.ReadUInt16LittleEndian(ref offset);
+ obj.Points = data.ReadUInt16LittleEndian(ref offset);
+ obj.VertRes = data.ReadUInt16LittleEndian(ref offset);
+ obj.HorizRes = data.ReadUInt16LittleEndian(ref offset);
+ obj.Ascent = data.ReadUInt16LittleEndian(ref offset);
+ obj.InternalLeading = data.ReadUInt16LittleEndian(ref offset);
+ obj.ExternalLeading = data.ReadUInt16LittleEndian(ref offset);
+ obj.Italic = data.ReadByte(ref offset);
+ obj.Underline = data.ReadByte(ref offset);
+ obj.StrikeOut = data.ReadByte(ref offset);
+ obj.Weight = data.ReadUInt16LittleEndian(ref offset);
+ obj.CharSet = data.ReadByte(ref offset);
+ obj.PixWidth = data.ReadUInt16LittleEndian(ref offset);
+ obj.PixHeight = data.ReadUInt16LittleEndian(ref offset);
+ obj.PitchAndFamily = data.ReadByte(ref offset);
+ obj.AvgWidth = data.ReadUInt16LittleEndian(ref offset);
+ obj.MaxWidth = data.ReadUInt16LittleEndian(ref offset);
+ obj.FirstChar = data.ReadByte(ref offset);
+ obj.LastChar = data.ReadByte(ref offset);
+ obj.DefaultChar = data.ReadByte(ref offset);
+ obj.BreakChar = data.ReadByte(ref offset);
+ obj.WidthBytes = data.ReadUInt16LittleEndian(ref offset);
+ obj.Device = data.ReadUInt32LittleEndian(ref offset);
+ obj.Face = data.ReadUInt32LittleEndian(ref offset);
+ obj.Reserved = data.ReadUInt32LittleEndian(ref offset);
+
+ // TODO: Determine how to read these two? Immediately after?
+ obj.DeviceName = data.ReadNullTerminatedAnsiString(ref offset) ?? string.Empty;
+ obj.FaceName = data.ReadNullTerminatedAnsiString(ref offset) ?? string.Empty;
+
+ return obj;
+ }
+
+ ///
+ /// Parse a byte array into a FontGroupHeader
+ ///
+ /// Data to parse
+ /// Offset into the byte array
+ /// A filled FontGroupHeader on success, null on error
+ public static Data.Models.PortableExecutable.Resource.Entries.FontGroupHeader ParseFontGroupHeader(byte[] data)
+ {
+ // Initialize the iterator
+ int offset = 0;
+
+ // Create the output object
+ var fontGroupHeader = new Data.Models.PortableExecutable.Resource.Entries.FontGroupHeader();
+
+ fontGroupHeader.NumberOfFonts = data.ReadUInt16LittleEndian(ref offset);
+ if (fontGroupHeader.NumberOfFonts > 0)
+ {
+ fontGroupHeader.DE = new Data.Models.PortableExecutable.Resource.Entries.DirEntry[fontGroupHeader.NumberOfFonts];
+ for (int i = 0; i < fontGroupHeader.NumberOfFonts; i++)
+ {
+ fontGroupHeader.DE[i] = ParseDirEntry(data, ref offset);
+ }
+ }
+
+ // TODO: Implement entry parsing
+ return fontGroupHeader;
+ }
+
///
/// Parse a Stream into a FunctionDefinition
///