mirror of
https://github.com/aaru-dps/Aaru.git
synced 2025-12-16 19:24:25 +00:00
[QCOW2] Use new source generator based big endian marshaller
This commit is contained in:
@@ -49,9 +49,9 @@ public sealed partial class Qcow2
|
|||||||
|
|
||||||
if(stream.Length < 512) return false;
|
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>());
|
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.magic = 0x{0:X8}", _qHdr.magic);
|
||||||
AaruLogging.Debug(MODULE_NAME, "qHdr.version = {0}", _qHdr.version);
|
AaruLogging.Debug(MODULE_NAME, "qHdr.version = {0}", _qHdr.version);
|
||||||
|
|||||||
@@ -57,9 +57,9 @@ public sealed partial class Qcow2
|
|||||||
|
|
||||||
if(stream.Length < 512) return ErrorNumber.InvalidArgument;
|
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>());
|
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.magic = 0x{0:X8}", _qHdr.magic);
|
||||||
AaruLogging.Debug(MODULE_NAME, "qHdr.version = {0}", _qHdr.version);
|
AaruLogging.Debug(MODULE_NAME, "qHdr.version = {0}", _qHdr.version);
|
||||||
@@ -87,8 +87,7 @@ public sealed partial class Qcow2
|
|||||||
|
|
||||||
if((_qHdr.features & QCOW_FEATURE_MASK) != 0)
|
if((_qHdr.features & QCOW_FEATURE_MASK) != 0)
|
||||||
{
|
{
|
||||||
AaruLogging.Error(string.Format(Localization
|
AaruLogging.Error(string.Format(Localization.Unknown_incompatible_features_0_enabled_not_proceeding,
|
||||||
.Unknown_incompatible_features_0_enabled_not_proceeding,
|
|
||||||
_qHdr.features & QCOW_FEATURE_MASK));
|
_qHdr.features & QCOW_FEATURE_MASK));
|
||||||
|
|
||||||
return ErrorNumber.InvalidArgument;
|
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.l2Size = {0}", _l2Size);
|
||||||
AaruLogging.Debug(MODULE_NAME, "qHdr.sectors = {0}", _imageInfo.Sectors);
|
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.Seek((long)_qHdr.l1_table_offset, SeekOrigin.Begin);
|
||||||
stream.EnsureRead(l1TableB, 0, (int)_qHdr.l1_size * 8);
|
stream.EnsureRead(l1TableB, 0, (int)_qHdr.l1_size * 8);
|
||||||
_l1Table = MemoryMarshal.Cast<byte, ulong>(l1TableB).ToArray();
|
_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]);
|
for(long i = 0; i < _l1Table.LongLength; i++) _l1Table[i] = Swapping.Swap(_l1Table[i]);
|
||||||
|
|
||||||
_l1Mask = 0;
|
_l1Mask = 0;
|
||||||
int c = 0;
|
var c = 0;
|
||||||
_l1Shift = (int)(_l2Bits + _qHdr.cluster_bits);
|
_l1Shift = (int)(_l2Bits + _qHdr.cluster_bits);
|
||||||
|
|
||||||
for(int i = 0; i < 64; i++)
|
for(var i = 0; i < 64; i++)
|
||||||
{
|
{
|
||||||
_l1Mask <<= 1;
|
_l1Mask <<= 1;
|
||||||
|
|
||||||
@@ -163,13 +162,13 @@ public sealed partial class Qcow2
|
|||||||
|
|
||||||
_l2Mask = 0;
|
_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;
|
_l2Mask <<= (int)_qHdr.cluster_bits;
|
||||||
|
|
||||||
_sectorMask = 0;
|
_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.l1Mask = {0:X}", _l1Mask);
|
||||||
AaruLogging.Debug(MODULE_NAME, "qHdr.l1Shift = {0}", _l1Shift);
|
AaruLogging.Debug(MODULE_NAME, "qHdr.l1Shift = {0}", _l1Shift);
|
||||||
@@ -237,7 +236,7 @@ public sealed partial class Qcow2
|
|||||||
if(!_l2TableCache.TryGetValue(l1Off, out ulong[] l2Table))
|
if(!_l2TableCache.TryGetValue(l1Off, out ulong[] l2Table))
|
||||||
{
|
{
|
||||||
_imageStream.Seek((long)(_l1Table[l1Off] & QCOW_FLAGS_MASK), SeekOrigin.Begin);
|
_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);
|
_imageStream.EnsureRead(l2TableB, 0, _l2Size * 8);
|
||||||
AaruLogging.Debug(MODULE_NAME, Localization.Reading_L2_table_0, l1Off);
|
AaruLogging.Debug(MODULE_NAME, Localization.Reading_L2_table_0, l1Off);
|
||||||
l2Table = MemoryMarshal.Cast<byte, ulong>(l2TableB).ToArray();
|
l2Table = MemoryMarshal.Cast<byte, ulong>(l2TableB).ToArray();
|
||||||
@@ -262,14 +261,14 @@ public sealed partial class Qcow2
|
|||||||
if((offset & QCOW_COMPRESSED) == QCOW_COMPRESSED)
|
if((offset & QCOW_COMPRESSED) == QCOW_COMPRESSED)
|
||||||
{
|
{
|
||||||
ulong compSizeMask = (ulong)(1 << (int)(_qHdr.cluster_bits - 8)) - 1;
|
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;
|
compSizeMask <<= 62 - countbits;
|
||||||
ulong offMask = ~compSizeMask & QCOW_FLAGS_MASK;
|
ulong offMask = ~compSizeMask & QCOW_FLAGS_MASK;
|
||||||
|
|
||||||
ulong realOff = offset & offMask;
|
ulong realOff = offset & offMask;
|
||||||
ulong compSize = (((offset & compSizeMask) >> 62 - countbits) + 1) * 512;
|
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.Seek((long)realOff, SeekOrigin.Begin);
|
||||||
_imageStream.EnsureRead(zCluster, 0, (int)compSize);
|
_imageStream.EnsureRead(zCluster, 0, (int)compSize);
|
||||||
|
|
||||||
|
|||||||
@@ -31,6 +31,7 @@
|
|||||||
// ****************************************************************************/
|
// ****************************************************************************/
|
||||||
|
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
|
using Aaru.CommonTypes.Attributes;
|
||||||
|
|
||||||
namespace Aaru.Images;
|
namespace Aaru.Images;
|
||||||
|
|
||||||
@@ -40,7 +41,8 @@ public sealed partial class Qcow2
|
|||||||
|
|
||||||
/// <summary>QCOW header, big-endian</summary>
|
/// <summary>QCOW header, big-endian</summary>
|
||||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||||
struct Header
|
[SwapEndian]
|
||||||
|
partial struct Header
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// <see cref="Qcow2.QCOW_MAGIC" />
|
/// <see cref="Qcow2.QCOW_MAGIC" />
|
||||||
@@ -49,15 +51,15 @@ public sealed partial class Qcow2
|
|||||||
/// <summary>Must be 1</summary>
|
/// <summary>Must be 1</summary>
|
||||||
public uint version;
|
public uint version;
|
||||||
/// <summary>Offset inside file to string containing backing file</summary>
|
/// <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>
|
/// <summary>Size of <see cref="backing_file_offset" /></summary>
|
||||||
public readonly uint backing_file_size;
|
public uint backing_file_size;
|
||||||
/// <summary>Cluster bits</summary>
|
/// <summary>Cluster bits</summary>
|
||||||
public uint cluster_bits;
|
public uint cluster_bits;
|
||||||
/// <summary>Size in bytes</summary>
|
/// <summary>Size in bytes</summary>
|
||||||
public ulong size;
|
public ulong size;
|
||||||
/// <summary>Encryption method</summary>
|
/// <summary>Encryption method</summary>
|
||||||
public readonly uint crypt_method;
|
public uint crypt_method;
|
||||||
/// <summary>Size of L1 table</summary>
|
/// <summary>Size of L1 table</summary>
|
||||||
public uint l1_size;
|
public uint l1_size;
|
||||||
/// <summary>Offset to L1 table</summary>
|
/// <summary>Offset to L1 table</summary>
|
||||||
@@ -67,15 +69,15 @@ public sealed partial class Qcow2
|
|||||||
/// <summary>How many clusters does the refcount table span</summary>
|
/// <summary>How many clusters does the refcount table span</summary>
|
||||||
public uint refcount_table_clusters;
|
public uint refcount_table_clusters;
|
||||||
/// <summary>Number of snapshots</summary>
|
/// <summary>Number of snapshots</summary>
|
||||||
public readonly uint nb_snapshots;
|
public uint nb_snapshots;
|
||||||
/// <summary>Offset to QCowSnapshotHeader</summary>
|
/// <summary>Offset to QCowSnapshotHeader</summary>
|
||||||
public readonly ulong snapshots_offset;
|
public ulong snapshots_offset;
|
||||||
|
|
||||||
// Added in version 3
|
// Added in version 3
|
||||||
public readonly ulong features;
|
public ulong features;
|
||||||
public readonly ulong compat_features;
|
public ulong compat_features;
|
||||||
public readonly ulong autoclear_features;
|
public ulong autoclear_features;
|
||||||
public readonly uint refcount_order;
|
public uint refcount_order;
|
||||||
public uint header_length;
|
public uint header_length;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user