[NDIF] Use new source generator based big endian marshaller

This commit is contained in:
2025-10-21 10:56:59 +01:00
parent ebc971a02a
commit f676b26bec
2 changed files with 32 additions and 30 deletions

View File

@@ -85,14 +85,14 @@ public sealed partial class Ndif
{ {
if(bcem.Length < 128) return ErrorNumber.InvalidArgument; if(bcem.Length < 128) return ErrorNumber.InvalidArgument;
_header = Marshal.ByteArrayToStructureBigEndian<ChunkHeader>(bcem); _header = Marshal.ByteArrayToStructureBigEndianGenerated<ChunkHeader>(bcem);
AaruLogging.Debug(MODULE_NAME, "footer.type = {0}", _header.version); AaruLogging.Debug(MODULE_NAME, "footer.type = {0}", _header.version);
AaruLogging.Debug(MODULE_NAME, "footer.driver = {0}", _header.driver); AaruLogging.Debug(MODULE_NAME, "footer.driver = {0}", _header.driver);
AaruLogging.Debug(MODULE_NAME, AaruLogging.Debug(MODULE_NAME,
"footer.name = {0}", "footer.name = {0}",
StringHandlers.PascalToString(_header.name, Encoding.GetEncoding("macintosh"))); StringHandlers.PascalToString(_header.name, Encoding.GetEncoding("macintosh")));
AaruLogging.Debug(MODULE_NAME, "footer.sectors = {0}", _header.sectors); AaruLogging.Debug(MODULE_NAME, "footer.sectors = {0}", _header.sectors);
@@ -115,12 +115,12 @@ public sealed partial class Ndif
// Block chunks and headers // Block chunks and headers
_chunks = new Dictionary<ulong, BlockChunk>(); _chunks = new Dictionary<ulong, BlockChunk>();
for(int i = 0; i < _header.chunks; i++) for(var i = 0; i < _header.chunks; i++)
{ {
// Obsolete read-only NDIF only prepended the header and then put the image without any kind of block references. // Obsolete read-only NDIF only prepended the header and then put the image without any kind of block references.
// So let's falsify a block chunk // So let's falsify a block chunk
var bChnk = new BlockChunk(); var bChnk = new BlockChunk();
byte[] sector = new byte[4]; var sector = new byte[4];
Array.Copy(bcem, 128 + 0 + i * 12, sector, 1, 3); Array.Copy(bcem, 128 + 0 + i * 12, sector, 1, 3);
bChnk.sector = BigEndianBitConverter.ToUInt32(sector, 0); bChnk.sector = BigEndianBitConverter.ToUInt32(sector, 0);
bChnk.type = bcem[128 + 3 + i * 12]; bChnk.type = bcem[128 + 3 + i * 12];
@@ -207,8 +207,8 @@ public sealed partial class Ndif
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}";
@@ -238,9 +238,9 @@ public sealed partial class Ndif
} }
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);
_sectorCache = new Dictionary<ulong, byte[]>(); _sectorCache = new Dictionary<ulong, byte[]>();
_chunkCache = new Dictionary<ulong, byte[]>(); _chunkCache = new Dictionary<ulong, byte[]>();
@@ -307,7 +307,7 @@ public sealed partial class Ndif
if(_sectorCache.TryGetValue(sectorAddress, out buffer)) return ErrorNumber.NoError; if(_sectorCache.TryGetValue(sectorAddress, out buffer)) return ErrorNumber.NoError;
var currentChunk = new BlockChunk(); var currentChunk = 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))
@@ -327,7 +327,7 @@ public sealed partial class Ndif
{ {
if(!_chunkCache.TryGetValue(chunkStartSector, out byte[] data)) if(!_chunkCache.TryGetValue(chunkStartSector, out byte[] data))
{ {
byte[] cmpBuffer = new byte[currentChunk.length]; var cmpBuffer = new byte[currentChunk.length];
_imageStream.Seek(currentChunk.offset, SeekOrigin.Begin); _imageStream.Seek(currentChunk.offset, SeekOrigin.Begin);
_imageStream.EnsureRead(cmpBuffer, 0, cmpBuffer.Length); _imageStream.EnsureRead(cmpBuffer, 0, cmpBuffer.Length);
int realSize; int realSize;
@@ -336,7 +336,7 @@ public sealed partial class Ndif
{ {
case CHUNK_TYPE_ADC: case CHUNK_TYPE_ADC:
{ {
byte[] tmpBuffer = new byte[_bufferSize]; var tmpBuffer = new byte[_bufferSize];
realSize = ADC.DecodeBuffer(cmpBuffer, tmpBuffer); realSize = ADC.DecodeBuffer(cmpBuffer, tmpBuffer);
data = new byte[realSize]; data = new byte[realSize];
Array.Copy(tmpBuffer, 0, data, 0, realSize); Array.Copy(tmpBuffer, 0, data, 0, realSize);
@@ -346,7 +346,7 @@ public sealed partial class Ndif
case CHUNK_TYPE_RLE: case CHUNK_TYPE_RLE:
{ {
byte[] tmpBuffer = new byte[_bufferSize]; var tmpBuffer = new byte[_bufferSize];
realSize = AppleRle.DecodeBuffer(cmpBuffer, tmpBuffer); realSize = AppleRle.DecodeBuffer(cmpBuffer, tmpBuffer);
data = new byte[realSize]; data = new byte[realSize];
Array.Copy(tmpBuffer, 0, data, 0, realSize); Array.Copy(tmpBuffer, 0, data, 0, realSize);

View File

@@ -33,6 +33,7 @@
using System; using System;
using System.Diagnostics.CodeAnalysis; using System.Diagnostics.CodeAnalysis;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using Aaru.CommonTypes.Attributes;
namespace Aaru.Images; namespace Aaru.Images;
@@ -59,38 +60,39 @@ public sealed partial class Ndif
#region Nested type: ChunkHeader #region Nested type: ChunkHeader
[StructLayout(LayoutKind.Sequential, Pack = 1)] [StructLayout(LayoutKind.Sequential, Pack = 1)]
readonly struct ChunkHeader [SwapEndian]
partial struct ChunkHeader
{ {
/// <summary>Version</summary> /// <summary>Version</summary>
public readonly short version; public short version;
/// <summary>Filesystem ID</summary> /// <summary>Filesystem ID</summary>
public readonly short driver; public short driver;
/// <summary>Disk image name, Str63 (Pascal string)</summary> /// <summary>Disk image name, Str63 (Pascal string)</summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 64)] [MarshalAs(UnmanagedType.ByValArray, SizeConst = 64)]
public readonly byte[] name; public byte[] name;
/// <summary>Sectors in image</summary> /// <summary>Sectors in image</summary>
public readonly uint sectors; public uint sectors;
/// <summary>Maximum number of sectors per chunk</summary> /// <summary>Maximum number of sectors per chunk</summary>
public readonly uint maxSectorsPerChunk; public uint maxSectorsPerChunk;
/// <summary>Offset to add to every chunk offset</summary> /// <summary>Offset to add to every chunk offset</summary>
public readonly uint dataOffset; public uint dataOffset;
/// <summary>CRC28 of whole image</summary> /// <summary>CRC28 of whole image</summary>
public readonly uint crc; public uint crc;
/// <summary>Set to 1 if segmented</summary> /// <summary>Set to 1 if segmented</summary>
public readonly uint segmented; public uint segmented;
/// <summary>Unknown</summary> /// <summary>Unknown</summary>
public readonly uint p1; public uint p1;
/// <summary>Unknown</summary> /// <summary>Unknown</summary>
public readonly uint p2; public uint p2;
/// <summary>Unknown, spare?</summary> /// <summary>Unknown, spare?</summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 5)] [MarshalAs(UnmanagedType.ByValArray, SizeConst = 5)]
public readonly uint[] unknown; public uint[] unknown;
/// <summary>Set to 1 by ShrinkWrap if image is encrypted</summary> /// <summary>Set to 1 by ShrinkWrap if image is encrypted</summary>
public readonly uint encrypted; public uint encrypted;
/// <summary>Set by ShrinkWrap if image is encrypted, value is the same for same password</summary> /// <summary>Set by ShrinkWrap if image is encrypted, value is the same for same password</summary>
public readonly uint hash; public uint hash;
/// <summary>How many chunks follow the header</summary> /// <summary>How many chunks follow the header</summary>
public readonly uint chunks; public uint chunks;
} }
#endregion #endregion