[UDIF] Use new source generator based big endian marshaller

This commit is contained in:
2025-10-21 10:59:48 +01:00
parent f676b26bec
commit c0c76f183e
3 changed files with 83 additions and 79 deletions

View File

@@ -51,7 +51,7 @@ public sealed partial class Udif
var footerB = new byte[Marshal.SizeOf<Footer>()]; var footerB = new byte[Marshal.SizeOf<Footer>()];
stream.EnsureRead(footerB, 0, Marshal.SizeOf<Footer>()); stream.EnsureRead(footerB, 0, Marshal.SizeOf<Footer>());
_footer = Marshal.ByteArrayToStructureBigEndian<Footer>(footerB); _footer = Marshal.ByteArrayToStructureBigEndianGenerated<Footer>(footerB);
if(_footer.signature == UDIF_SIGNATURE) return true; if(_footer.signature == UDIF_SIGNATURE) return true;
@@ -60,7 +60,7 @@ public sealed partial class Udif
var headerB = new byte[Marshal.SizeOf<Footer>()]; var headerB = new byte[Marshal.SizeOf<Footer>()];
stream.EnsureRead(headerB, 0, Marshal.SizeOf<Footer>()); stream.EnsureRead(headerB, 0, Marshal.SizeOf<Footer>());
_footer = Marshal.ByteArrayToStructureBigEndian<Footer>(headerB); _footer = Marshal.ByteArrayToStructureBigEndianGenerated<Footer>(headerB);
return _footer.signature == UDIF_SIGNATURE; return _footer.signature == UDIF_SIGNATURE;
} }

View File

@@ -62,10 +62,10 @@ public sealed partial class Udif
if(stream.Length < 512) return ErrorNumber.InvalidArgument; if(stream.Length < 512) return ErrorNumber.InvalidArgument;
stream.Seek(-Marshal.SizeOf<Footer>(), SeekOrigin.End); stream.Seek(-Marshal.SizeOf<Footer>(), SeekOrigin.End);
byte[] footerB = new byte[Marshal.SizeOf<Footer>()]; var footerB = new byte[Marshal.SizeOf<Footer>()];
stream.EnsureRead(footerB, 0, Marshal.SizeOf<Footer>()); stream.EnsureRead(footerB, 0, Marshal.SizeOf<Footer>());
_footer = Marshal.ByteArrayToStructureBigEndian<Footer>(footerB); _footer = Marshal.ByteArrayToStructureBigEndianGenerated<Footer>(footerB);
if(_footer.signature != UDIF_SIGNATURE) if(_footer.signature != UDIF_SIGNATURE)
{ {
@@ -73,7 +73,7 @@ public sealed partial class Udif
footerB = new byte[Marshal.SizeOf<Footer>()]; footerB = new byte[Marshal.SizeOf<Footer>()];
stream.EnsureRead(footerB, 0, Marshal.SizeOf<Footer>()); stream.EnsureRead(footerB, 0, Marshal.SizeOf<Footer>());
_footer = Marshal.ByteArrayToStructureBigEndian<Footer>(footerB); _footer = Marshal.ByteArrayToStructureBigEndianGenerated<Footer>(footerB);
if(_footer.signature != UDIF_SIGNATURE) if(_footer.signature != UDIF_SIGNATURE)
{ {
@@ -109,20 +109,20 @@ public sealed partial class Udif
AaruLogging.Debug(MODULE_NAME, "footer.sectorCount = {0}", _footer.sectorCount); AaruLogging.Debug(MODULE_NAME, "footer.sectorCount = {0}", _footer.sectorCount);
AaruLogging.Debug(MODULE_NAME, AaruLogging.Debug(MODULE_NAME,
"footer.reserved1 is empty? = {0}", "footer.reserved1 is empty? = {0}",
ArrayHelpers.ArrayIsNullOrEmpty(_footer.reserved1)); ArrayHelpers.ArrayIsNullOrEmpty(_footer.reserved1));
AaruLogging.Debug(MODULE_NAME, AaruLogging.Debug(MODULE_NAME,
"footer.reserved2 is empty? = {0}", "footer.reserved2 is empty? = {0}",
ArrayHelpers.ArrayIsNullOrEmpty(_footer.reserved2)); ArrayHelpers.ArrayIsNullOrEmpty(_footer.reserved2));
AaruLogging.Debug(MODULE_NAME, AaruLogging.Debug(MODULE_NAME,
"footer.reserved3 is empty? = {0}", "footer.reserved3 is empty? = {0}",
ArrayHelpers.ArrayIsNullOrEmpty(_footer.reserved3)); ArrayHelpers.ArrayIsNullOrEmpty(_footer.reserved3));
AaruLogging.Debug(MODULE_NAME, AaruLogging.Debug(MODULE_NAME,
"footer.reserved4 is empty? = {0}", "footer.reserved4 is empty? = {0}",
ArrayHelpers.ArrayIsNullOrEmpty(_footer.reserved4)); ArrayHelpers.ArrayIsNullOrEmpty(_footer.reserved4));
// Block chunks and headers // Block chunks and headers
List<byte[]> blkxList = []; List<byte[]> blkxList = [];
@@ -133,7 +133,7 @@ public sealed partial class Udif
if(_footer.plistLen == 0 && _footer.rsrcForkLen != 0) if(_footer.plistLen == 0 && _footer.rsrcForkLen != 0)
{ {
AaruLogging.Debug(MODULE_NAME, Localization.Reading_resource_fork); AaruLogging.Debug(MODULE_NAME, Localization.Reading_resource_fork);
byte[] rsrcB = new byte[_footer.rsrcForkLen]; var rsrcB = new byte[_footer.rsrcForkLen];
stream.Seek((long)_footer.rsrcForkOff, SeekOrigin.Begin); stream.Seek((long)_footer.rsrcForkOff, SeekOrigin.Begin);
stream.EnsureRead(rsrcB, 0, rsrcB.Length); stream.EnsureRead(rsrcB, 0, rsrcB.Length);
@@ -171,7 +171,7 @@ public sealed partial class Udif
else if(_footer.plistLen != 0) else if(_footer.plistLen != 0)
{ {
AaruLogging.Debug(MODULE_NAME, Localization.Reading_property_list); AaruLogging.Debug(MODULE_NAME, Localization.Reading_property_list);
byte[] plistB = new byte[_footer.plistLen]; var plistB = new byte[_footer.plistLen];
stream.Seek((long)_footer.plistOff, SeekOrigin.Begin); stream.Seek((long)_footer.plistOff, SeekOrigin.Begin);
stream.EnsureRead(plistB, 0, plistB.Length); stream.EnsureRead(plistB, 0, plistB.Length);
@@ -241,7 +241,7 @@ public sealed partial class Udif
AaruLogging.Debug(MODULE_NAME, Localization.Reading_resource_fork); AaruLogging.Debug(MODULE_NAME, Localization.Reading_resource_fork);
Stream rsrcStream = imageFilter.GetResourceForkStream(); Stream rsrcStream = imageFilter.GetResourceForkStream();
byte[] rsrcB = new byte[rsrcStream.Length]; var rsrcB = new byte[rsrcStream.Length];
rsrcStream.Position = 0; rsrcStream.Position = 0;
rsrcStream.EnsureRead(rsrcB, 0, rsrcB.Length); rsrcStream.EnsureRead(rsrcB, 0, rsrcB.Length);
@@ -284,8 +284,8 @@ public sealed partial class Udif
string release = null; string release = null;
string pre = null; string pre = null;
string major = $"{version.MajorVersion}"; var major = $"{version.MajorVersion}";
string minor = $".{version.MinorVersion / 10}"; var minor = $".{version.MinorVersion / 10}";
if(version.MinorVersion % 10 > 0) release = $".{version.MinorVersion % 10}"; if(version.MinorVersion % 10 > 0) release = $".{version.MinorVersion % 10}";
@@ -316,9 +316,9 @@ public sealed partial class Udif
_imageInfo.Application = "DiskCopy"; _imageInfo.Application = "DiskCopy";
AaruLogging.Debug(MODULE_NAME, AaruLogging.Debug(MODULE_NAME,
Localization.Image_application_0_version_1, Localization.Image_application_0_version_1,
_imageInfo.Application, _imageInfo.Application,
_imageInfo.ApplicationVersion); _imageInfo.ApplicationVersion);
_imageInfo.Sectors = 0; _imageInfo.Sectors = 0;
@@ -333,9 +333,9 @@ public sealed partial class Udif
foreach(byte[] blkxBytes in blkxList) foreach(byte[] blkxBytes in blkxList)
{ {
byte[] bHdrB = new byte[Marshal.SizeOf<BlockHeader>()]; var bHdrB = new byte[Marshal.SizeOf<BlockHeader>()];
Array.Copy(blkxBytes, 0, bHdrB, 0, Marshal.SizeOf<BlockHeader>()); Array.Copy(blkxBytes, 0, bHdrB, 0, Marshal.SizeOf<BlockHeader>());
BlockHeader bHdr = Marshal.ByteArrayToStructureBigEndian<BlockHeader>(bHdrB); BlockHeader bHdr = Marshal.ByteArrayToStructureBigEndianGenerated<BlockHeader>(bHdrB);
AaruLogging.Debug(MODULE_NAME, "bHdr.signature = 0x{0:X8}", bHdr.signature); AaruLogging.Debug(MODULE_NAME, "bHdr.signature = 0x{0:X8}", bHdr.signature);
AaruLogging.Debug(MODULE_NAME, "bHdr.version = {0}", bHdr.version); AaruLogging.Debug(MODULE_NAME, "bHdr.version = {0}", bHdr.version);
@@ -356,14 +356,14 @@ public sealed partial class Udif
AaruLogging.Debug(MODULE_NAME, "bHdr.chunks = {0}", bHdr.chunks); AaruLogging.Debug(MODULE_NAME, "bHdr.chunks = {0}", bHdr.chunks);
AaruLogging.Debug(MODULE_NAME, AaruLogging.Debug(MODULE_NAME,
"bHdr.reservedChk is empty? = {0}", "bHdr.reservedChk is empty? = {0}",
ArrayHelpers.ArrayIsNullOrEmpty(bHdr.reservedChk)); ArrayHelpers.ArrayIsNullOrEmpty(bHdr.reservedChk));
if(bHdr.buffers > _buffersize) _buffersize = bHdr.buffers * SECTOR_SIZE; if(bHdr.buffers > _buffersize) _buffersize = bHdr.buffers * SECTOR_SIZE;
for(int i = 0; i < bHdr.chunks; i++) for(var i = 0; i < bHdr.chunks; i++)
{ {
byte[] bChnkB = new byte[Marshal.SizeOf<BlockChunk>()]; var bChnkB = new byte[Marshal.SizeOf<BlockChunk>()];
Array.Copy(blkxBytes, Array.Copy(blkxBytes,
Marshal.SizeOf<BlockHeader>() + Marshal.SizeOf<BlockChunk>() * i, Marshal.SizeOf<BlockHeader>() + Marshal.SizeOf<BlockChunk>() * i,
@@ -371,7 +371,7 @@ public sealed partial class Udif
0, 0,
Marshal.SizeOf<BlockChunk>()); Marshal.SizeOf<BlockChunk>());
BlockChunk bChnk = Marshal.ByteArrayToStructureBigEndian<BlockChunk>(bChnkB); BlockChunk bChnk = Marshal.ByteArrayToStructureBigEndianGenerated<BlockChunk>(bChnkB);
AaruLogging.Debug(MODULE_NAME, "bHdr.chunk[{0}].type = 0x{1:X8}", i, bChnk.type); AaruLogging.Debug(MODULE_NAME, "bHdr.chunk[{0}].type = 0x{1:X8}", i, bChnk.type);
AaruLogging.Debug(MODULE_NAME, "bHdr.chunk[{0}].comment = {1}", i, bChnk.comment); AaruLogging.Debug(MODULE_NAME, "bHdr.chunk[{0}].comment = {1}", i, bChnk.comment);
@@ -451,7 +451,7 @@ public sealed partial class Udif
if(_sectorCache.TryGetValue(sectorAddress, out buffer)) return ErrorNumber.NoError; if(_sectorCache.TryGetValue(sectorAddress, out buffer)) return ErrorNumber.NoError;
var readChunk = new BlockChunk(); var readChunk = new BlockChunk();
bool chunkFound = false; var chunkFound = false;
ulong chunkStartSector = 0; ulong chunkStartSector = 0;
foreach(KeyValuePair<ulong, BlockChunk> kvp in _chunks.Where(kvp => sectorAddress >= kvp.Key)) foreach(KeyValuePair<ulong, BlockChunk> kvp in _chunks.Where(kvp => sectorAddress >= kvp.Key))
@@ -471,7 +471,7 @@ public sealed partial class Udif
{ {
if(!_chunkCache.TryGetValue(chunkStartSector, out byte[] data)) if(!_chunkCache.TryGetValue(chunkStartSector, out byte[] data))
{ {
byte[] cmpBuffer = new byte[readChunk.length]; var cmpBuffer = new byte[readChunk.length];
_imageStream.Seek((long)(readChunk.offset + _footer.dataForkOff), SeekOrigin.Begin); _imageStream.Seek((long)(readChunk.offset + _footer.dataForkOff), SeekOrigin.Begin);
_imageStream.EnsureRead(cmpBuffer, 0, cmpBuffer.Length); _imageStream.EnsureRead(cmpBuffer, 0, cmpBuffer.Length);
var cmpMs = new MemoryStream(cmpBuffer); var cmpMs = new MemoryStream(cmpBuffer);
@@ -502,7 +502,7 @@ public sealed partial class Udif
{ {
#endif #endif
byte[] tmpBuffer; byte[] tmpBuffer;
int realSize = 0; var realSize = 0;
switch(readChunk.type) switch(readChunk.type)
{ {

View File

@@ -32,6 +32,7 @@
using System; using System;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using Aaru.CommonTypes.Attributes;
namespace Aaru.Images; namespace Aaru.Images;
@@ -40,14 +41,15 @@ public sealed partial class Udif
#region Nested type: BlockChunk #region Nested type: BlockChunk
[StructLayout(LayoutKind.Sequential, Pack = 1)] [StructLayout(LayoutKind.Sequential, Pack = 1)]
struct BlockChunk [SwapEndian]
partial struct BlockChunk
{ {
public uint type; public uint type;
public readonly uint comment; public uint comment;
public ulong sector; public ulong sector;
public ulong sectors; public ulong sectors;
public ulong offset; public ulong offset;
public ulong length; public ulong length;
} }
#endregion #endregion
@@ -55,26 +57,27 @@ public sealed partial class Udif
#region Nested type: BlockHeader #region Nested type: BlockHeader
[StructLayout(LayoutKind.Sequential, Pack = 1)] [StructLayout(LayoutKind.Sequential, Pack = 1)]
struct BlockHeader [SwapEndian]
partial struct BlockHeader
{ {
public uint signature; public uint signature;
public uint version; public uint version;
public readonly ulong sectorStart; public ulong sectorStart;
public ulong sectorCount; public ulong sectorCount;
public readonly ulong dataOffset; public ulong dataOffset;
public readonly uint buffers; public uint buffers;
public readonly uint descriptor; public uint descriptor;
public readonly uint reserved1; public uint reserved1;
public readonly uint reserved2; public uint reserved2;
public readonly uint reserved3; public uint reserved3;
public readonly uint reserved4; public uint reserved4;
public readonly uint reserved5; public uint reserved5;
public readonly uint reserved6; public uint reserved6;
public uint checksumType; public uint checksumType;
public uint checksumLen; public uint checksumLen;
public uint checksum; public uint checksum;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 124)] [MarshalAs(UnmanagedType.ByValArray, SizeConst = 124)]
public readonly byte[] reservedChk; public byte[] reservedChk;
public uint chunks; public uint chunks;
} }
@@ -83,38 +86,39 @@ public sealed partial class Udif
#region Nested type: Footer #region Nested type: Footer
[StructLayout(LayoutKind.Sequential, Pack = 1)] [StructLayout(LayoutKind.Sequential, Pack = 1)]
struct Footer [SwapEndian]
partial struct Footer
{ {
public uint signature; public uint signature;
public uint version; public uint version;
public uint headerSize; public uint headerSize;
public uint flags; public uint flags;
public readonly ulong runningDataForkOff; public ulong runningDataForkOff;
public readonly ulong dataForkOff; public ulong dataForkOff;
public ulong dataForkLen; public ulong dataForkLen;
public readonly ulong rsrcForkOff; public ulong rsrcForkOff;
public readonly ulong rsrcForkLen; public ulong rsrcForkLen;
public uint segmentNumber; public uint segmentNumber;
public uint segmentCount; public uint segmentCount;
public Guid segmentId; public Guid segmentId;
public uint dataForkChkType; public uint dataForkChkType;
public uint dataForkChkLen; public uint dataForkChkLen;
public uint dataForkChk; public uint dataForkChk;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 124)] [MarshalAs(UnmanagedType.ByValArray, SizeConst = 124)]
public readonly byte[] reserved1; public byte[] reserved1;
public ulong plistOff; public ulong plistOff;
public ulong plistLen; public ulong plistLen;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 120)] [MarshalAs(UnmanagedType.ByValArray, SizeConst = 120)]
public readonly byte[] reserved2; public byte[] reserved2;
public readonly uint masterChkType; public uint masterChkType;
public readonly uint masterChkLen; public uint masterChkLen;
public readonly uint masterChk; public uint masterChk;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 124)] [MarshalAs(UnmanagedType.ByValArray, SizeConst = 124)]
public readonly byte[] reserved3; public byte[] reserved3;
public uint imageVariant; public uint imageVariant;
public ulong sectorCount; public ulong sectorCount;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 12)] [MarshalAs(UnmanagedType.ByValArray, SizeConst = 12)]
public readonly byte[] reserved4; public byte[] reserved4;
} }
#endregion #endregion