[QCOW2] Use new source generator based big endian marshaller

This commit is contained in:
2025-10-21 11:41:08 +01:00
parent a1ad9aa6a0
commit 061669a255
3 changed files with 30 additions and 29 deletions

View File

@@ -49,9 +49,9 @@ public sealed partial class Qcow2
if(stream.Length < 512) return false;
byte[] qHdrB = new byte[Marshal.SizeOf<Header>()];
var qHdrB = new byte[Marshal.SizeOf<Header>()];
stream.EnsureRead(qHdrB, 0, Marshal.SizeOf<Header>());
_qHdr = Marshal.SpanToStructureBigEndian<Header>(qHdrB);
_qHdr = Marshal.SpanToStructureBigEndianGenerated<Header>(qHdrB);
AaruLogging.Debug(MODULE_NAME, "qHdr.magic = 0x{0:X8}", _qHdr.magic);
AaruLogging.Debug(MODULE_NAME, "qHdr.version = {0}", _qHdr.version);

View File

@@ -57,9 +57,9 @@ public sealed partial class Qcow2
if(stream.Length < 512) return ErrorNumber.InvalidArgument;
byte[] qHdrB = new byte[Marshal.SizeOf<Header>()];
var qHdrB = new byte[Marshal.SizeOf<Header>()];
stream.EnsureRead(qHdrB, 0, Marshal.SizeOf<Header>());
_qHdr = Marshal.SpanToStructureBigEndian<Header>(qHdrB);
_qHdr = Marshal.SpanToStructureBigEndianGenerated<Header>(qHdrB);
AaruLogging.Debug(MODULE_NAME, "qHdr.magic = 0x{0:X8}", _qHdr.magic);
AaruLogging.Debug(MODULE_NAME, "qHdr.version = {0}", _qHdr.version);
@@ -87,9 +87,8 @@ public sealed partial class Qcow2
if((_qHdr.features & QCOW_FEATURE_MASK) != 0)
{
AaruLogging.Error(string.Format(Localization
.Unknown_incompatible_features_0_enabled_not_proceeding,
_qHdr.features & QCOW_FEATURE_MASK));
AaruLogging.Error(string.Format(Localization.Unknown_incompatible_features_0_enabled_not_proceeding,
_qHdr.features & QCOW_FEATURE_MASK));
return ErrorNumber.InvalidArgument;
}
@@ -139,7 +138,7 @@ public sealed partial class Qcow2
AaruLogging.Debug(MODULE_NAME, "qHdr.l2Size = {0}", _l2Size);
AaruLogging.Debug(MODULE_NAME, "qHdr.sectors = {0}", _imageInfo.Sectors);
byte[] l1TableB = new byte[_qHdr.l1_size * 8];
var l1TableB = new byte[_qHdr.l1_size * 8];
stream.Seek((long)_qHdr.l1_table_offset, SeekOrigin.Begin);
stream.EnsureRead(l1TableB, 0, (int)_qHdr.l1_size * 8);
_l1Table = MemoryMarshal.Cast<byte, ulong>(l1TableB).ToArray();
@@ -148,10 +147,10 @@ public sealed partial class Qcow2
for(long i = 0; i < _l1Table.LongLength; i++) _l1Table[i] = Swapping.Swap(_l1Table[i]);
_l1Mask = 0;
int c = 0;
var c = 0;
_l1Shift = (int)(_l2Bits + _qHdr.cluster_bits);
for(int i = 0; i < 64; i++)
for(var i = 0; i < 64; i++)
{
_l1Mask <<= 1;
@@ -163,13 +162,13 @@ public sealed partial class Qcow2
_l2Mask = 0;
for(int i = 0; i < _l2Bits; i++) _l2Mask = (_l2Mask << 1) + 1;
for(var i = 0; i < _l2Bits; i++) _l2Mask = (_l2Mask << 1) + 1;
_l2Mask <<= (int)_qHdr.cluster_bits;
_sectorMask = 0;
for(int i = 0; i < _qHdr.cluster_bits; i++) _sectorMask = (_sectorMask << 1) + 1;
for(var i = 0; i < _qHdr.cluster_bits; i++) _sectorMask = (_sectorMask << 1) + 1;
AaruLogging.Debug(MODULE_NAME, "qHdr.l1Mask = {0:X}", _l1Mask);
AaruLogging.Debug(MODULE_NAME, "qHdr.l1Shift = {0}", _l1Shift);
@@ -219,9 +218,9 @@ public sealed partial class Qcow2
if((long)l1Off >= _l1Table.LongLength)
{
AaruLogging.Debug(MODULE_NAME,
string.Format(Localization.Trying_to_read_past_L1_table_position_0_of_a_max_1,
l1Off,
_l1Table.LongLength));
string.Format(Localization.Trying_to_read_past_L1_table_position_0_of_a_max_1,
l1Off,
_l1Table.LongLength));
return ErrorNumber.InvalidArgument;
}
@@ -237,7 +236,7 @@ public sealed partial class Qcow2
if(!_l2TableCache.TryGetValue(l1Off, out ulong[] l2Table))
{
_imageStream.Seek((long)(_l1Table[l1Off] & QCOW_FLAGS_MASK), SeekOrigin.Begin);
byte[] l2TableB = new byte[_l2Size * 8];
var l2TableB = new byte[_l2Size * 8];
_imageStream.EnsureRead(l2TableB, 0, _l2Size * 8);
AaruLogging.Debug(MODULE_NAME, Localization.Reading_L2_table_0, l1Off);
l2Table = MemoryMarshal.Cast<byte, ulong>(l2TableB).ToArray();
@@ -262,14 +261,14 @@ public sealed partial class Qcow2
if((offset & QCOW_COMPRESSED) == QCOW_COMPRESSED)
{
ulong compSizeMask = (ulong)(1 << (int)(_qHdr.cluster_bits - 8)) - 1;
byte countbits = (byte)(_qHdr.cluster_bits - 8);
var countbits = (byte)(_qHdr.cluster_bits - 8);
compSizeMask <<= 62 - countbits;
ulong offMask = ~compSizeMask & QCOW_FLAGS_MASK;
ulong realOff = offset & offMask;
ulong compSize = (((offset & compSizeMask) >> 62 - countbits) + 1) * 512;
byte[] zCluster = new byte[compSize];
var zCluster = new byte[compSize];
_imageStream.Seek((long)realOff, SeekOrigin.Begin);
_imageStream.EnsureRead(zCluster, 0, (int)compSize);

View File

@@ -31,6 +31,7 @@
// ****************************************************************************/
using System.Runtime.InteropServices;
using Aaru.CommonTypes.Attributes;
namespace Aaru.Images;
@@ -40,7 +41,8 @@ public sealed partial class Qcow2
/// <summary>QCOW header, big-endian</summary>
[StructLayout(LayoutKind.Sequential, Pack = 1)]
struct Header
[SwapEndian]
partial struct Header
{
/// <summary>
/// <see cref="Qcow2.QCOW_MAGIC" />
@@ -49,15 +51,15 @@ public sealed partial class Qcow2
/// <summary>Must be 1</summary>
public uint version;
/// <summary>Offset inside file to string containing backing file</summary>
public readonly ulong backing_file_offset;
public ulong backing_file_offset;
/// <summary>Size of <see cref="backing_file_offset" /></summary>
public readonly uint backing_file_size;
public uint backing_file_size;
/// <summary>Cluster bits</summary>
public uint cluster_bits;
/// <summary>Size in bytes</summary>
public ulong size;
/// <summary>Encryption method</summary>
public readonly uint crypt_method;
public uint crypt_method;
/// <summary>Size of L1 table</summary>
public uint l1_size;
/// <summary>Offset to L1 table</summary>
@@ -67,16 +69,16 @@ public sealed partial class Qcow2
/// <summary>How many clusters does the refcount table span</summary>
public uint refcount_table_clusters;
/// <summary>Number of snapshots</summary>
public readonly uint nb_snapshots;
public uint nb_snapshots;
/// <summary>Offset to QCowSnapshotHeader</summary>
public readonly ulong snapshots_offset;
public ulong snapshots_offset;
// Added in version 3
public readonly ulong features;
public readonly ulong compat_features;
public readonly ulong autoclear_features;
public readonly uint refcount_order;
public uint header_length;
public ulong features;
public ulong compat_features;
public ulong autoclear_features;
public uint refcount_order;
public uint header_length;
}
#endregion