[CHD] Use new source generator based big endian marshaller

This commit is contained in:
2025-10-21 10:29:33 +01:00
parent 3d3425002e
commit e613563359
3 changed files with 217 additions and 228 deletions

View File

@@ -72,7 +72,7 @@ public sealed partial class Chd
ulong offset = _hunkTable[hunkNo] & 0x00000FFFFFFFFFFF;
ulong length = _hunkTable[hunkNo] >> 44;
byte[] compHunk = new byte[length];
var compHunk = new byte[length];
_imageStream.Seek((long)offset, SeekOrigin.Begin);
_imageStream.EnsureRead(compHunk, 0, compHunk.Length);
@@ -81,7 +81,7 @@ public sealed partial class Chd
else if((Compression)_hdrCompression > Compression.Zlib)
{
AaruLogging.Error(string.Format(Localization.Unsupported_compression_0,
(Compression)_hdrCompression));
(Compression)_hdrCompression));
return ErrorNumber.InvalidArgument;
}
@@ -94,9 +94,9 @@ public sealed partial class Chd
if(read != _sectorsPerHunk * _imageInfo.SectorSize)
{
AaruLogging.Error(string.Format(Localization
.Unable_to_decompress_hunk_correctly_got_0_bytes_expected_1,
read,
_sectorsPerHunk * _imageInfo.SectorSize));
.Unable_to_decompress_hunk_correctly_got_0_bytes_expected_1,
read,
_sectorsPerHunk * _imageInfo.SectorSize));
return ErrorNumber.InOutError;
}
@@ -106,9 +106,9 @@ public sealed partial class Chd
break;
case 3:
byte[] entryBytes = new byte[16];
var entryBytes = new byte[16];
Array.Copy(_hunkMap, (int)(hunkNo * 16), entryBytes, 0, 16);
MapEntryV3 entry = Marshal.ByteArrayToStructureBigEndian<MapEntryV3>(entryBytes);
MapEntryV3 entry = Marshal.ByteArrayToStructureBigEndianGenerated<MapEntryV3>(entryBytes);
switch((EntryFlagsV3)(entry.flags & 0x0F))
{
@@ -125,7 +125,7 @@ public sealed partial class Chd
case Compression.ZlibPlus:
if(_isHdd)
{
byte[] zHunk = new byte[(entry.lengthLsb << 16) + entry.lengthLsb];
var zHunk = new byte[(entry.lengthLsb << 16) + entry.lengthLsb];
_imageStream.Seek((long)entry.offset, SeekOrigin.Begin);
_imageStream.EnsureRead(zHunk, 0, zHunk.Length);
@@ -138,9 +138,9 @@ public sealed partial class Chd
if(read != _bytesPerHunk)
{
AaruLogging.Error(string.Format(Localization
.Unable_to_decompress_hunk_correctly_got_0_bytes_expected_1,
read,
_bytesPerHunk));
.Unable_to_decompress_hunk_correctly_got_0_bytes_expected_1,
read,
_bytesPerHunk));
return ErrorNumber.InOutError;
}
@@ -151,8 +151,7 @@ public sealed partial class Chd
// TODO: Guess wth is MAME doing with these hunks
else
{
AaruLogging.Error(Localization
.Compressed_CD_GD_ROM_hunks_are_not_yet_supported);
AaruLogging.Error(Localization.Compressed_CD_GD_ROM_hunks_are_not_yet_supported);
return ErrorNumber.NotImplemented;
}
@@ -160,7 +159,7 @@ public sealed partial class Chd
break;
case Compression.Av:
AaruLogging.Error(string.Format(Localization.Unsupported_compression_0,
(Compression)_hdrCompression));
(Compression)_hdrCompression));
return ErrorNumber.NotImplemented;
}
@@ -177,7 +176,7 @@ public sealed partial class Chd
buffer = new byte[_bytesPerHunk];
byte[] mini = BigEndianBitConverter.GetBytes(entry.offset);
for(int i = 0; i < _bytesPerHunk; i++) buffer[i] = mini[i % 8];
for(var i = 0; i < _bytesPerHunk; i++) buffer[i] = mini[i % 8];
break;
case EntryFlagsV3.SelfHunk:
@@ -191,8 +190,7 @@ public sealed partial class Chd
return ErrorNumber.NotImplemented;
default:
AaruLogging.Error(string.Format(Localization.Hunk_type_0_is_not_supported,
entry.flags & 0xF));
AaruLogging.Error(string.Format(Localization.Hunk_type_0_is_not_supported, entry.flags & 0xF));
return ErrorNumber.NotSupported;
}

View File

@@ -60,18 +60,18 @@ public sealed partial class Chd
{
Stream stream = imageFilter.GetDataForkStream();
stream.Seek(0, SeekOrigin.Begin);
byte[] magic = new byte[8];
var magic = new byte[8];
stream.EnsureRead(magic, 0, 8);
if(!_chdTag.SequenceEqual(magic)) return ErrorNumber.InvalidArgument;
// Read length
byte[] buffer = new byte[4];
var buffer = new byte[4];
stream.EnsureRead(buffer, 0, 4);
uint length = BitConverter.ToUInt32(buffer.Reverse().ToArray(), 0);
var length = BitConverter.ToUInt32(buffer.Reverse().ToArray(), 0);
buffer = new byte[4];
stream.EnsureRead(buffer, 0, 4);
uint version = BitConverter.ToUInt32(buffer.Reverse().ToArray(), 0);
var version = BitConverter.ToUInt32(buffer.Reverse().ToArray(), 0);
buffer = new byte[length];
stream.Seek(0, SeekOrigin.Begin);
@@ -84,7 +84,7 @@ public sealed partial class Chd
{
case 1:
{
HeaderV1 hdrV1 = Marshal.ByteArrayToStructureBigEndian<HeaderV1>(buffer);
HeaderV1 hdrV1 = Marshal.ByteArrayToStructureBigEndianGenerated<HeaderV1>(buffer);
AaruLogging.Debug(MODULE_NAME, "hdrV1.tag = \"{0}\"", Encoding.ASCII.GetString(hdrV1.tag));
@@ -94,29 +94,29 @@ public sealed partial class Chd
AaruLogging.Debug(MODULE_NAME, "hdrV1.compression = {0}", (Compression)hdrV1.compression);
AaruLogging.Debug(MODULE_NAME, "hdrV1.hunksize = {0}", hdrV1.hunksize);
AaruLogging.Debug(MODULE_NAME, "hdrV1.hunksize = {0}", hdrV1.hunksize);
AaruLogging.Debug(MODULE_NAME, "hdrV1.totalhunks = {0}", hdrV1.totalhunks);
AaruLogging.Debug(MODULE_NAME, "hdrV1.cylinders = {0}", hdrV1.cylinders);
AaruLogging.Debug(MODULE_NAME, "hdrV1.heads = {0}", hdrV1.heads);
AaruLogging.Debug(MODULE_NAME, "hdrV1.sectors = {0}", hdrV1.sectors);
AaruLogging.Debug(MODULE_NAME, "hdrV1.md5 = {0}", ArrayHelpers.ByteArrayToHex(hdrV1.md5));
AaruLogging.Debug(MODULE_NAME, "hdrV1.cylinders = {0}", hdrV1.cylinders);
AaruLogging.Debug(MODULE_NAME, "hdrV1.heads = {0}", hdrV1.heads);
AaruLogging.Debug(MODULE_NAME, "hdrV1.sectors = {0}", hdrV1.sectors);
AaruLogging.Debug(MODULE_NAME, "hdrV1.md5 = {0}", ArrayHelpers.ByteArrayToHex(hdrV1.md5));
AaruLogging.Debug(MODULE_NAME,
"hdrV1.parentmd5 = {0}",
ArrayHelpers.ArrayIsNullOrEmpty(hdrV1.parentmd5)
? "null"
: ArrayHelpers.ByteArrayToHex(hdrV1.parentmd5));
"hdrV1.parentmd5 = {0}",
ArrayHelpers.ArrayIsNullOrEmpty(hdrV1.parentmd5)
? "null"
: ArrayHelpers.ByteArrayToHex(hdrV1.parentmd5));
AaruLogging.Debug(MODULE_NAME, Localization.Reading_Hunk_map);
hunkMapStopwatch.Restart();
_hunkTable = new ulong[hdrV1.totalhunks];
uint hunkSectorCount = (uint)Math.Ceiling((double)hdrV1.totalhunks * 8 / 512);
var hunkSectorCount = (uint)Math.Ceiling((double)hdrV1.totalhunks * 8 / 512);
byte[] hunkSectorBytes = new byte[512];
var hunkSectorBytes = new byte[512];
for(int i = 0; i < hunkSectorCount; i++)
for(var i = 0; i < hunkSectorCount; i++)
{
stream.EnsureRead(hunkSectorBytes, 0, 512);
@@ -135,9 +135,7 @@ public sealed partial class Chd
hunkMapStopwatch.Stop();
AaruLogging.Debug(MODULE_NAME,
Localization.Took_0_seconds,
hunkMapStopwatch.Elapsed.TotalSeconds);
AaruLogging.Debug(MODULE_NAME, Localization.Took_0_seconds, hunkMapStopwatch.Elapsed.TotalSeconds);
_imageInfo.MediaType = MediaType.GENERIC_HDD;
_imageInfo.Sectors = hdrV1.hunksize * hdrV1.totalhunks;
@@ -161,7 +159,7 @@ public sealed partial class Chd
case 2:
{
HeaderV2 hdrV2 = Marshal.ByteArrayToStructureBigEndian<HeaderV2>(buffer);
HeaderV2 hdrV2 = Marshal.ByteArrayToStructureBigEndianGenerated<HeaderV2>(buffer);
AaruLogging.Debug(MODULE_NAME, "hdrV2.tag = \"{0}\"", Encoding.ASCII.GetString(hdrV2.tag));
@@ -171,18 +169,18 @@ public sealed partial class Chd
AaruLogging.Debug(MODULE_NAME, "hdrV2.compression = {0}", (Compression)hdrV2.compression);
AaruLogging.Debug(MODULE_NAME, "hdrV2.hunksize = {0}", hdrV2.hunksize);
AaruLogging.Debug(MODULE_NAME, "hdrV2.hunksize = {0}", hdrV2.hunksize);
AaruLogging.Debug(MODULE_NAME, "hdrV2.totalhunks = {0}", hdrV2.totalhunks);
AaruLogging.Debug(MODULE_NAME, "hdrV2.cylinders = {0}", hdrV2.cylinders);
AaruLogging.Debug(MODULE_NAME, "hdrV2.heads = {0}", hdrV2.heads);
AaruLogging.Debug(MODULE_NAME, "hdrV2.sectors = {0}", hdrV2.sectors);
AaruLogging.Debug(MODULE_NAME, "hdrV2.md5 = {0}", ArrayHelpers.ByteArrayToHex(hdrV2.md5));
AaruLogging.Debug(MODULE_NAME, "hdrV2.cylinders = {0}", hdrV2.cylinders);
AaruLogging.Debug(MODULE_NAME, "hdrV2.heads = {0}", hdrV2.heads);
AaruLogging.Debug(MODULE_NAME, "hdrV2.sectors = {0}", hdrV2.sectors);
AaruLogging.Debug(MODULE_NAME, "hdrV2.md5 = {0}", ArrayHelpers.ByteArrayToHex(hdrV2.md5));
AaruLogging.Debug(MODULE_NAME,
"hdrV2.parentmd5 = {0}",
ArrayHelpers.ArrayIsNullOrEmpty(hdrV2.parentmd5)
? "null"
: ArrayHelpers.ByteArrayToHex(hdrV2.parentmd5));
"hdrV2.parentmd5 = {0}",
ArrayHelpers.ArrayIsNullOrEmpty(hdrV2.parentmd5)
? "null"
: ArrayHelpers.ByteArrayToHex(hdrV2.parentmd5));
AaruLogging.Debug(MODULE_NAME, "hdrV2.seclen = {0}", hdrV2.seclen);
@@ -192,11 +190,11 @@ public sealed partial class Chd
_hunkTable = new ulong[hdrV2.totalhunks];
// How many sectors uses the BAT
uint hunkSectorCount = (uint)Math.Ceiling((double)hdrV2.totalhunks * 8 / 512);
var hunkSectorCount = (uint)Math.Ceiling((double)hdrV2.totalhunks * 8 / 512);
byte[] hunkSectorBytes = new byte[512];
var hunkSectorBytes = new byte[512];
for(int i = 0; i < hunkSectorCount; i++)
for(var i = 0; i < hunkSectorCount; i++)
{
stream.EnsureRead(hunkSectorBytes, 0, 512);
@@ -215,9 +213,7 @@ public sealed partial class Chd
hunkMapStopwatch.Stop();
AaruLogging.Debug(MODULE_NAME,
Localization.Took_0_seconds,
hunkMapStopwatch.Elapsed.TotalSeconds);
AaruLogging.Debug(MODULE_NAME, Localization.Took_0_seconds, hunkMapStopwatch.Elapsed.TotalSeconds);
_imageInfo.MediaType = MediaType.GENERIC_HDD;
_imageInfo.Sectors = hdrV2.hunksize * hdrV2.totalhunks;
@@ -241,7 +237,7 @@ public sealed partial class Chd
case 3:
{
HeaderV3 hdrV3 = Marshal.ByteArrayToStructureBigEndian<HeaderV3>(buffer);
HeaderV3 hdrV3 = Marshal.ByteArrayToStructureBigEndianGenerated<HeaderV3>(buffer);
AaruLogging.Debug(MODULE_NAME, "hdrV3.tag = \"{0}\"", Encoding.ASCII.GetString(hdrV3.tag));
@@ -251,26 +247,26 @@ public sealed partial class Chd
AaruLogging.Debug(MODULE_NAME, "hdrV3.compression = {0}", (Compression)hdrV3.compression);
AaruLogging.Debug(MODULE_NAME, "hdrV3.totalhunks = {0}", hdrV3.totalhunks);
AaruLogging.Debug(MODULE_NAME, "hdrV3.totalhunks = {0}", hdrV3.totalhunks);
AaruLogging.Debug(MODULE_NAME, "hdrV3.logicalbytes = {0}", hdrV3.logicalbytes);
AaruLogging.Debug(MODULE_NAME, "hdrV3.metaoffset = {0}", hdrV3.metaoffset);
AaruLogging.Debug(MODULE_NAME, "hdrV3.md5 = {0}", ArrayHelpers.ByteArrayToHex(hdrV3.md5));
AaruLogging.Debug(MODULE_NAME, "hdrV3.metaoffset = {0}", hdrV3.metaoffset);
AaruLogging.Debug(MODULE_NAME, "hdrV3.md5 = {0}", ArrayHelpers.ByteArrayToHex(hdrV3.md5));
AaruLogging.Debug(MODULE_NAME,
"hdrV3.parentmd5 = {0}",
ArrayHelpers.ArrayIsNullOrEmpty(hdrV3.parentmd5)
? "null"
: ArrayHelpers.ByteArrayToHex(hdrV3.parentmd5));
"hdrV3.parentmd5 = {0}",
ArrayHelpers.ArrayIsNullOrEmpty(hdrV3.parentmd5)
? "null"
: ArrayHelpers.ByteArrayToHex(hdrV3.parentmd5));
AaruLogging.Debug(MODULE_NAME, "hdrV3.hunkbytes = {0}", hdrV3.hunkbytes);
AaruLogging.Debug(MODULE_NAME, "hdrV3.sha1 = {0}", ArrayHelpers.ByteArrayToHex(hdrV3.sha1));
AaruLogging.Debug(MODULE_NAME,
"hdrV3.parentsha1 = {0}",
ArrayHelpers.ArrayIsNullOrEmpty(hdrV3.parentsha1)
? "null"
: ArrayHelpers.ByteArrayToHex(hdrV3.parentsha1));
"hdrV3.parentsha1 = {0}",
ArrayHelpers.ArrayIsNullOrEmpty(hdrV3.parentsha1)
? "null"
: ArrayHelpers.ByteArrayToHex(hdrV3.parentsha1));
AaruLogging.Debug(MODULE_NAME, Localization.Reading_Hunk_map);
hunkMapStopwatch.Restart();
@@ -280,9 +276,7 @@ public sealed partial class Chd
hunkMapStopwatch.Stop();
AaruLogging.Debug(MODULE_NAME,
Localization.Took_0_seconds,
hunkMapStopwatch.Elapsed.TotalSeconds);
AaruLogging.Debug(MODULE_NAME, Localization.Took_0_seconds, hunkMapStopwatch.Elapsed.TotalSeconds);
nextMetaOff = hdrV3.metaoffset;
@@ -299,7 +293,7 @@ public sealed partial class Chd
case 4:
{
HeaderV4 hdrV4 = Marshal.ByteArrayToStructureBigEndian<HeaderV4>(buffer);
HeaderV4 hdrV4 = Marshal.ByteArrayToStructureBigEndianGenerated<HeaderV4>(buffer);
AaruLogging.Debug(MODULE_NAME, "hdrV4.tag = \"{0}\"", Encoding.ASCII.GetString(hdrV4.tag));
@@ -317,14 +311,12 @@ public sealed partial class Chd
AaruLogging.Debug(MODULE_NAME, "hdrV4.sha1 = {0}", ArrayHelpers.ByteArrayToHex(hdrV4.sha1));
AaruLogging.Debug(MODULE_NAME,
"hdrV4.parentsha1 = {0}",
ArrayHelpers.ArrayIsNullOrEmpty(hdrV4.parentsha1)
? "null"
: ArrayHelpers.ByteArrayToHex(hdrV4.parentsha1));
"hdrV4.parentsha1 = {0}",
ArrayHelpers.ArrayIsNullOrEmpty(hdrV4.parentsha1)
? "null"
: ArrayHelpers.ByteArrayToHex(hdrV4.parentsha1));
AaruLogging.Debug(MODULE_NAME,
"hdrV4.rawsha1 = {0}",
ArrayHelpers.ByteArrayToHex(hdrV4.rawsha1));
AaruLogging.Debug(MODULE_NAME, "hdrV4.rawsha1 = {0}", ArrayHelpers.ByteArrayToHex(hdrV4.rawsha1));
AaruLogging.Debug(MODULE_NAME, Localization.Reading_Hunk_map);
hunkMapStopwatch.Restart();
@@ -334,9 +326,7 @@ public sealed partial class Chd
hunkMapStopwatch.Stop();
AaruLogging.Debug(MODULE_NAME,
Localization.Took_0_seconds,
hunkMapStopwatch.Elapsed.TotalSeconds);
AaruLogging.Debug(MODULE_NAME, Localization.Took_0_seconds, hunkMapStopwatch.Elapsed.TotalSeconds);
nextMetaOff = hdrV4.metaoffset;
@@ -358,7 +348,7 @@ public sealed partial class Chd
return ErrorNumber.NotImplemented;
HeaderV5 hdrV5 = Marshal.ByteArrayToStructureBigEndian<HeaderV5>(buffer);
HeaderV5 hdrV5 = Marshal.ByteArrayToStructureBigEndianGenerated<HeaderV5>(buffer);
AaruLogging.Debug(MODULE_NAME, "hdrV5.tag = \"{0}\"", Encoding.ASCII.GetString(hdrV5.tag));
@@ -366,20 +356,20 @@ public sealed partial class Chd
AaruLogging.Debug(MODULE_NAME, "hdrV5.version = {0}", hdrV5.version);
AaruLogging.Debug(MODULE_NAME,
"hdrV5.compressor0 = \"{0}\"",
Encoding.ASCII.GetString(BigEndianBitConverter.GetBytes(hdrV5.compressor0)));
"hdrV5.compressor0 = \"{0}\"",
Encoding.ASCII.GetString(BigEndianBitConverter.GetBytes(hdrV5.compressor0)));
AaruLogging.Debug(MODULE_NAME,
"hdrV5.compressor1 = \"{0}\"",
Encoding.ASCII.GetString(BigEndianBitConverter.GetBytes(hdrV5.compressor1)));
"hdrV5.compressor1 = \"{0}\"",
Encoding.ASCII.GetString(BigEndianBitConverter.GetBytes(hdrV5.compressor1)));
AaruLogging.Debug(MODULE_NAME,
"hdrV5.compressor2 = \"{0}\"",
Encoding.ASCII.GetString(BigEndianBitConverter.GetBytes(hdrV5.compressor2)));
"hdrV5.compressor2 = \"{0}\"",
Encoding.ASCII.GetString(BigEndianBitConverter.GetBytes(hdrV5.compressor2)));
AaruLogging.Debug(MODULE_NAME,
"hdrV5.compressor3 = \"{0}\"",
Encoding.ASCII.GetString(BigEndianBitConverter.GetBytes(hdrV5.compressor3)));
"hdrV5.compressor3 = \"{0}\"",
Encoding.ASCII.GetString(BigEndianBitConverter.GetBytes(hdrV5.compressor3)));
AaruLogging.Debug(MODULE_NAME, "hdrV5.logicalbytes = {0}", hdrV5.logicalbytes);
AaruLogging.Debug(MODULE_NAME, "hdrV5.mapoffset = {0}", hdrV5.mapoffset);
@@ -390,14 +380,12 @@ public sealed partial class Chd
AaruLogging.Debug(MODULE_NAME, "hdrV5.sha1 = {0}", ArrayHelpers.ByteArrayToHex(hdrV5.sha1));
AaruLogging.Debug(MODULE_NAME,
"hdrV5.parentsha1 = {0}",
ArrayHelpers.ArrayIsNullOrEmpty(hdrV5.parentsha1)
? "null"
: ArrayHelpers.ByteArrayToHex(hdrV5.parentsha1));
"hdrV5.parentsha1 = {0}",
ArrayHelpers.ArrayIsNullOrEmpty(hdrV5.parentsha1)
? "null"
: ArrayHelpers.ByteArrayToHex(hdrV5.parentsha1));
AaruLogging.Debug(MODULE_NAME,
"hdrV5.rawsha1 = {0}",
ArrayHelpers.ByteArrayToHex(hdrV5.rawsha1));
AaruLogging.Debug(MODULE_NAME, "hdrV5.rawsha1 = {0}", ArrayHelpers.ByteArrayToHex(hdrV5.rawsha1));
// TODO: Implement compressed CHD v5
if(hdrV5.compressor0 == 0)
@@ -407,13 +395,13 @@ public sealed partial class Chd
_hunkTableSmall = new uint[hdrV5.logicalbytes / hdrV5.hunkbytes];
uint hunkSectorCount = (uint)Math.Ceiling((double)_hunkTableSmall.Length * 4 / 512);
var hunkSectorCount = (uint)Math.Ceiling((double)_hunkTableSmall.Length * 4 / 512);
byte[] hunkSectorBytes = new byte[512];
var hunkSectorBytes = new byte[512];
stream.Seek((long)hdrV5.mapoffset, SeekOrigin.Begin);
for(int i = 0; i < hunkSectorCount; i++)
for(var i = 0; i < hunkSectorCount; i++)
{
stream.EnsureRead(hunkSectorBytes, 0, 512);
@@ -440,9 +428,7 @@ public sealed partial class Chd
hunkMapStopwatch.Stop();
AaruLogging.Debug(MODULE_NAME,
Localization.Took_0_seconds,
hunkMapStopwatch.Elapsed.TotalSeconds);
AaruLogging.Debug(MODULE_NAME, Localization.Took_0_seconds, hunkMapStopwatch.Elapsed.TotalSeconds);
}
else
{
@@ -488,16 +474,16 @@ public sealed partial class Chd
while(nextMetaOff > 0)
{
byte[] hdrBytes = new byte[16];
var hdrBytes = new byte[16];
stream.Seek((long)nextMetaOff, SeekOrigin.Begin);
stream.EnsureRead(hdrBytes, 0, hdrBytes.Length);
MetadataHeader header = Marshal.ByteArrayToStructureBigEndian<MetadataHeader>(hdrBytes);
byte[] meta = new byte[header.flagsAndLength & 0xFFFFFF];
MetadataHeader header = Marshal.ByteArrayToStructureBigEndianGenerated<MetadataHeader>(hdrBytes);
var meta = new byte[header.flagsAndLength & 0xFFFFFF];
stream.EnsureRead(meta, 0, meta.Length);
AaruLogging.Debug(MODULE_NAME,
Localization.Found_metadata_0_,
Encoding.ASCII.GetString(BigEndianBitConverter.GetBytes(header.tag)));
Localization.Found_metadata_0_,
Encoding.ASCII.GetString(BigEndianBitConverter.GetBytes(header.tag)));
switch(header.tag)
{
@@ -506,7 +492,7 @@ public sealed partial class Chd
if(_isCdrom || _isGdrom)
{
AaruLogging.Error(Localization
.Image_cannot_be_a_hard_disk_and_a_CGD_ROM_at_the_same_time_aborting);
.Image_cannot_be_a_hard_disk_and_a_CGD_ROM_at_the_same_time_aborting);
return ErrorNumber.NotSupported;
}
@@ -531,7 +517,7 @@ public sealed partial class Chd
if(_isHdd)
{
AaruLogging.Error(Localization
.Image_cannot_be_a_hard_disk_and_a_CD_ROM_at_the_same_time_aborting);
.Image_cannot_be_a_hard_disk_and_a_CD_ROM_at_the_same_time_aborting);
return ErrorNumber.NotSupported;
}
@@ -539,12 +525,12 @@ public sealed partial class Chd
if(_isGdrom)
{
AaruLogging.Error(Localization
.Image_cannot_be_a_GD_ROM_and_a_CD_ROM_at_the_same_time_aborting);
.Image_cannot_be_a_GD_ROM_and_a_CD_ROM_at_the_same_time_aborting);
return ErrorNumber.NotSupported;
}
uint chdTracksNumber = BigEndianBitConverter.ToUInt32(meta, 0);
var chdTracksNumber = BigEndianBitConverter.ToUInt32(meta, 0);
// Byteswapped
if(chdTracksNumber > 99) chdTracksNumber = BigEndianBitConverter.ToUInt32(meta, 0);
@@ -613,7 +599,7 @@ public sealed partial class Chd
default:
{
AaruLogging.Error(string.Format(Localization.Unsupported_track_type_0,
chdTrack.type));
chdTrack.type));
return ErrorNumber.NotSupported;
}
@@ -640,7 +626,7 @@ public sealed partial class Chd
default:
{
AaruLogging.Error(string.Format(Localization.Unsupported_subchannel_type_0,
chdTrack.type));
chdTrack.type));
return ErrorNumber.NotSupported;
}
@@ -671,7 +657,7 @@ public sealed partial class Chd
if(_isHdd)
{
AaruLogging.Error(Localization
.Image_cannot_be_a_hard_disk_and_a_CD_ROM_at_the_same_time_aborting);
.Image_cannot_be_a_hard_disk_and_a_CD_ROM_at_the_same_time_aborting);
return ErrorNumber.NotSupported;
}
@@ -679,7 +665,7 @@ public sealed partial class Chd
if(_isGdrom)
{
AaruLogging.Error(Localization
.Image_cannot_be_a_GD_ROM_and_a_CD_ROM_at_the_same_time_aborting);
.Image_cannot_be_a_GD_ROM_and_a_CD_ROM_at_the_same_time_aborting);
return ErrorNumber.NotSupported;
}
@@ -692,8 +678,8 @@ public sealed partial class Chd
{
_isCdrom = true;
uint trackNo = uint.Parse(chtrMatch.Groups["track"].Value);
uint frames = uint.Parse(chtrMatch.Groups["frames"].Value);
var trackNo = uint.Parse(chtrMatch.Groups["track"].Value);
var frames = uint.Parse(chtrMatch.Groups["frames"].Value);
string subtype = chtrMatch.Groups["sub_type"].Value;
string tracktype = chtrMatch.Groups["track_type"].Value;
@@ -759,8 +745,7 @@ public sealed partial class Chd
break;
default:
{
AaruLogging.Error(string.Format(Localization.Unsupported_track_type_0,
tracktype));
AaruLogging.Error(string.Format(Localization.Unsupported_track_type_0, tracktype));
return ErrorNumber.NotSupported;
}
@@ -787,7 +772,7 @@ public sealed partial class Chd
default:
{
AaruLogging.Error(string.Format(Localization.Unsupported_subchannel_type_0,
subtype));
subtype));
return ErrorNumber.NotSupported;
}
@@ -817,7 +802,7 @@ public sealed partial class Chd
if(_isHdd)
{
AaruLogging.Error(Localization
.Image_cannot_be_a_hard_disk_and_a_CD_ROM_at_the_same_time_aborting);
.Image_cannot_be_a_hard_disk_and_a_CD_ROM_at_the_same_time_aborting);
return ErrorNumber.NotSupported;
}
@@ -825,7 +810,7 @@ public sealed partial class Chd
if(_isGdrom)
{
AaruLogging.Error(Localization
.Image_cannot_be_a_GD_ROM_and_a_CD_ROM_at_the_same_time_aborting);
.Image_cannot_be_a_GD_ROM_and_a_CD_ROM_at_the_same_time_aborting);
return ErrorNumber.NotSupported;
}
@@ -838,12 +823,12 @@ public sealed partial class Chd
{
_isCdrom = true;
uint trackNo = uint.Parse(cht2Match.Groups["track"].Value);
uint frames = uint.Parse(cht2Match.Groups["frames"].Value);
var trackNo = uint.Parse(cht2Match.Groups["track"].Value);
var frames = uint.Parse(cht2Match.Groups["frames"].Value);
string subtype = cht2Match.Groups["sub_type"].Value;
string trackType = cht2Match.Groups["track_type"].Value;
uint pregap = uint.Parse(cht2Match.Groups["pregap"].Value);
var pregap = uint.Parse(cht2Match.Groups["pregap"].Value);
// What is this, really? Same as track type?
string pregapType = cht2Match.Groups["pgtype"].Value;
@@ -855,7 +840,7 @@ public sealed partial class Chd
// or of any data track followed by an audio track, according to Yellow Book.
// It is indistinguishable from normal data.
// TODO: Does CHD store it, or like CDRWin, ignores it?
uint postgap = uint.Parse(cht2Match.Groups["postgap"].Value);
var postgap = uint.Parse(cht2Match.Groups["postgap"].Value);
if(trackNo != currentTrack)
{
@@ -919,8 +904,7 @@ public sealed partial class Chd
break;
default:
{
AaruLogging.Error(string.Format(Localization.Unsupported_track_type_0,
trackType));
AaruLogging.Error(string.Format(Localization.Unsupported_track_type_0, trackType));
return ErrorNumber.NotSupported;
}
@@ -947,7 +931,7 @@ public sealed partial class Chd
default:
{
AaruLogging.Error(string.Format(Localization.Unsupported_subchannel_type_0,
subtype));
subtype));
return ErrorNumber.NotSupported;
}
@@ -1003,7 +987,7 @@ public sealed partial class Chd
if(_isHdd)
{
AaruLogging.Error(Localization
.Image_cannot_be_a_hard_disk_and_a_GD_ROM_at_the_same_time_aborting);
.Image_cannot_be_a_hard_disk_and_a_GD_ROM_at_the_same_time_aborting);
return ErrorNumber.NotSupported;
}
@@ -1011,7 +995,7 @@ public sealed partial class Chd
if(_isCdrom)
{
AaruLogging.Error(Localization
.Image_cannot_be_a_CD_ROM_and_a_GD_ROM_at_the_same_time_aborting);
.Image_cannot_be_a_CD_ROM_and_a_GD_ROM_at_the_same_time_aborting);
return ErrorNumber.NotSupported;
}
@@ -1024,17 +1008,17 @@ public sealed partial class Chd
{
_isGdrom = true;
uint trackNo = uint.Parse(chgdMatch.Groups["track"].Value);
uint frames = uint.Parse(chgdMatch.Groups["frames"].Value);
var trackNo = uint.Parse(chgdMatch.Groups["track"].Value);
var frames = uint.Parse(chgdMatch.Groups["frames"].Value);
string subtype = chgdMatch.Groups["sub_type"].Value;
string trackType = chgdMatch.Groups["track_type"].Value;
// TODO: Check pregap, postgap and pad behaviour
uint pregap = uint.Parse(chgdMatch.Groups["pregap"].Value);
var pregap = uint.Parse(chgdMatch.Groups["pregap"].Value);
string pregapType = chgdMatch.Groups["pgtype"].Value;
string pregapSubType = chgdMatch.Groups["pgsub"].Value;
uint postgap = uint.Parse(chgdMatch.Groups["postgap"].Value);
uint pad = uint.Parse(chgdMatch.Groups["pad"].Value);
var postgap = uint.Parse(chgdMatch.Groups["postgap"].Value);
var pad = uint.Parse(chgdMatch.Groups["pad"].Value);
if(trackNo != currentTrack)
{
@@ -1098,8 +1082,7 @@ public sealed partial class Chd
break;
default:
{
AaruLogging.Error(string.Format(Localization.Unsupported_track_type_0,
trackType));
AaruLogging.Error(string.Format(Localization.Unsupported_track_type_0, trackType));
return ErrorNumber.NotSupported;
}
@@ -1126,7 +1109,7 @@ public sealed partial class Chd
default:
{
AaruLogging.Error(string.Format(Localization.Unsupported_subchannel_type_0,
subtype));
subtype));
return ErrorNumber.NotSupported;
}
@@ -1408,7 +1391,7 @@ public sealed partial class Chd
}
uint sectorOffset;
bool mode2 = false;
var mode2 = false;
switch(track.Type)
{
@@ -1488,7 +1471,7 @@ public sealed partial class Chd
buffer = Sector.GetUserDataFromMode2(sector);
else if(track.Type == TrackType.Audio && _swapAudio)
{
for(int i = 0; i < 2352; i += 2)
for(var i = 0; i < 2352; i += 2)
{
buffer[i + 1] = sector[i];
buffer[i] = sector[i + 1];
@@ -1753,7 +1736,7 @@ public sealed partial class Chd
if(track.Type == TrackType.Audio && _swapAudio)
{
for(int i = 0; i < 2352; i += 2)
for(var i = 0; i < 2352; i += 2)
{
buffer[i + 1] = sector[i];
buffer[i] = sector[i + 1];
@@ -1764,7 +1747,7 @@ public sealed partial class Chd
if(track.Type == TrackType.Audio && _swapAudio)
{
for(int i = 0; i < 2352; i += 2)
for(var i = 0; i < 2352; i += 2)
{
buffer[i + 1] = sector[i];
buffer[i] = sector[i + 1];
@@ -1840,7 +1823,7 @@ public sealed partial class Chd
if(!_sectorCache.TryGetValue(sectorAddress, out byte[] sector))
{
track = GetTrack(sectorAddress);
uint sectorSize = (uint)track.RawBytesPerSector;
var sectorSize = (uint)track.RawBytesPerSector;
ulong hunkNo = sectorAddress / _sectorsPerHunk;
ulong secOff = sectorAddress * sectorSize % (_sectorsPerHunk * sectorSize);
@@ -1861,7 +1844,7 @@ public sealed partial class Chd
if(track.Type == TrackType.Audio && _swapAudio)
{
for(int i = 0; i < 2352; i += 2)
for(var i = 0; i < 2352; i += 2)
{
buffer[i + 1] = sector[i];
buffer[i] = sector[i + 1];
@@ -1874,7 +1857,7 @@ public sealed partial class Chd
{
case TrackType.CdMode1 when track.RawBytesPerSector == 2048:
{
byte[] fullSector = new byte[2352];
var fullSector = new byte[2352];
Array.Copy(buffer, 0, fullSector, 16, 2048);
_sectorBuilder.ReconstructPrefix(ref fullSector, TrackType.CdMode1, (long)sectorAddress);
@@ -1886,7 +1869,7 @@ public sealed partial class Chd
}
case TrackType.CdMode2Form1 when track.RawBytesPerSector == 2048:
{
byte[] fullSector = new byte[2352];
var fullSector = new byte[2352];
Array.Copy(buffer, 0, fullSector, 24, 2048);
_sectorBuilder.ReconstructPrefix(ref fullSector, TrackType.CdMode2Form1, (long)sectorAddress);
@@ -1898,7 +1881,7 @@ public sealed partial class Chd
}
case TrackType.CdMode2Form1 when track.RawBytesPerSector == 2324:
{
byte[] fullSector = new byte[2352];
var fullSector = new byte[2352];
Array.Copy(buffer, 0, fullSector, 24, 2324);
_sectorBuilder.ReconstructPrefix(ref fullSector, TrackType.CdMode2Form2, (long)sectorAddress);
@@ -1910,7 +1893,7 @@ public sealed partial class Chd
}
case TrackType.CdMode2Formless when track.RawBytesPerSector == 2336:
{
byte[] fullSector = new byte[2352];
var fullSector = new byte[2352];
_sectorBuilder.ReconstructPrefix(ref fullSector, TrackType.CdMode2Formless, (long)sectorAddress);
Array.Copy(buffer, 0, fullSector, 16, 2336);

View File

@@ -32,6 +32,7 @@
using System.Diagnostics.CodeAnalysis;
using System.Runtime.InteropServices;
using Aaru.CommonTypes.Attributes;
namespace Aaru.Images;
@@ -63,35 +64,36 @@ public sealed partial class Chd
// Hunks are represented in a 64 bit integer with 44 bit as offset, 20 bits as length
// Sectors are fixed at 512 bytes/sector
[StructLayout(LayoutKind.Sequential, Pack = 1)]
readonly struct HeaderV1
[SwapEndian]
partial struct HeaderV1
{
/// <summary>Magic identifier, 'MComprHD'</summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
public readonly byte[] tag;
public byte[] tag;
/// <summary>Length of header</summary>
public readonly uint length;
public uint length;
/// <summary>Image format version</summary>
public readonly uint version;
public uint version;
/// <summary>Image flags, <see cref="Flags" /></summary>
public readonly uint flags;
public uint flags;
/// <summary>Compression algorithm, <see cref="Compression" /></summary>
public readonly uint compression;
public uint compression;
/// <summary>Sectors per hunk</summary>
public readonly uint hunksize;
public uint hunksize;
/// <summary>Total # of hunk in image</summary>
public readonly uint totalhunks;
public uint totalhunks;
/// <summary>Cylinders on disk</summary>
public readonly uint cylinders;
public uint cylinders;
/// <summary>Heads per cylinder</summary>
public readonly uint heads;
public uint heads;
/// <summary>Sectors per track</summary>
public readonly uint sectors;
public uint sectors;
/// <summary>MD5 of raw data</summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
public readonly byte[] md5;
public byte[] md5;
/// <summary>MD5 of parent file</summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
public readonly byte[] parentmd5;
public byte[] parentmd5;
}
#endregion
@@ -100,37 +102,38 @@ public sealed partial class Chd
// Hunks are represented in a 64 bit integer with 44 bit as offset, 20 bits as length
[StructLayout(LayoutKind.Sequential, Pack = 1)]
readonly struct HeaderV2
[SwapEndian]
partial struct HeaderV2
{
/// <summary>Magic identifier, 'MComprHD'</summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
public readonly byte[] tag;
public byte[] tag;
/// <summary>Length of header</summary>
public readonly uint length;
public uint length;
/// <summary>Image format version</summary>
public readonly uint version;
public uint version;
/// <summary>Image flags, <see cref="Flags" /></summary>
public readonly uint flags;
public uint flags;
/// <summary>Compression algorithm, <see cref="Compression" /></summary>
public readonly uint compression;
public uint compression;
/// <summary>Sectors per hunk</summary>
public readonly uint hunksize;
public uint hunksize;
/// <summary>Total # of hunk in image</summary>
public readonly uint totalhunks;
public uint totalhunks;
/// <summary>Cylinders on disk</summary>
public readonly uint cylinders;
public uint cylinders;
/// <summary>Heads per cylinder</summary>
public readonly uint heads;
public uint heads;
/// <summary>Sectors per track</summary>
public readonly uint sectors;
public uint sectors;
/// <summary>MD5 of raw data</summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
public readonly byte[] md5;
public byte[] md5;
/// <summary>MD5 of parent file</summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
public readonly byte[] parentmd5;
public byte[] parentmd5;
/// <summary>Bytes per sector</summary>
public readonly uint seclen;
public uint seclen;
}
#endregion
@@ -138,39 +141,40 @@ public sealed partial class Chd
#region Nested type: HeaderV3
[StructLayout(LayoutKind.Sequential, Pack = 1)]
readonly struct HeaderV3
[SwapEndian]
partial struct HeaderV3
{
/// <summary>Magic identifier, 'MComprHD'</summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
public readonly byte[] tag;
public byte[] tag;
/// <summary>Length of header</summary>
public readonly uint length;
public uint length;
/// <summary>Image format version</summary>
public readonly uint version;
public uint version;
/// <summary>Image flags, <see cref="Flags" /></summary>
public readonly uint flags;
public uint flags;
/// <summary>Compression algorithm, <see cref="Compression" /></summary>
public readonly uint compression;
public uint compression;
/// <summary>Total # of hunk in image</summary>
public readonly uint totalhunks;
public uint totalhunks;
/// <summary>Total bytes in image</summary>
public readonly ulong logicalbytes;
public ulong logicalbytes;
/// <summary>Offset to first metadata blob</summary>
public readonly ulong metaoffset;
public ulong metaoffset;
/// <summary>MD5 of raw data</summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
public readonly byte[] md5;
public byte[] md5;
/// <summary>MD5 of parent file</summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
public readonly byte[] parentmd5;
public byte[] parentmd5;
/// <summary>Bytes per hunk</summary>
public readonly uint hunkbytes;
public uint hunkbytes;
/// <summary>SHA1 of raw data</summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 20)]
public readonly byte[] sha1;
public byte[] sha1;
/// <summary>SHA1 of parent file</summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 20)]
public readonly byte[] parentsha1;
public byte[] parentsha1;
}
#endregion
@@ -178,36 +182,37 @@ public sealed partial class Chd
#region Nested type: HeaderV4
[StructLayout(LayoutKind.Sequential, Pack = 1)]
readonly struct HeaderV4
[SwapEndian]
partial struct HeaderV4
{
/// <summary>Magic identifier, 'MComprHD'</summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
public readonly byte[] tag;
public byte[] tag;
/// <summary>Length of header</summary>
public readonly uint length;
public uint length;
/// <summary>Image format version</summary>
public readonly uint version;
public uint version;
/// <summary>Image flags, <see cref="Flags" /></summary>
public readonly uint flags;
public uint flags;
/// <summary>Compression algorithm, <see cref="Compression" /></summary>
public readonly uint compression;
public uint compression;
/// <summary>Total # of hunk in image</summary>
public readonly uint totalhunks;
public uint totalhunks;
/// <summary>Total bytes in image</summary>
public readonly ulong logicalbytes;
public ulong logicalbytes;
/// <summary>Offset to first metadata blob</summary>
public readonly ulong metaoffset;
public ulong metaoffset;
/// <summary>Bytes per hunk</summary>
public readonly uint hunkbytes;
public uint hunkbytes;
/// <summary>SHA1 of raw+meta data</summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 20)]
public readonly byte[] sha1;
public byte[] sha1;
/// <summary>SHA1 of parent file</summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 20)]
public readonly byte[] parentsha1;
public byte[] parentsha1;
/// <summary>SHA1 of raw data</summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 20)]
public readonly byte[] rawsha1;
public byte[] rawsha1;
}
#endregion
@@ -215,42 +220,43 @@ public sealed partial class Chd
#region Nested type: HeaderV5
[StructLayout(LayoutKind.Sequential, Pack = 1)]
readonly struct HeaderV5
[SwapEndian]
partial struct HeaderV5
{
/// <summary>Magic identifier, 'MComprHD'</summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
public readonly byte[] tag;
public byte[] tag;
/// <summary>Length of header</summary>
public readonly uint length;
public uint length;
/// <summary>Image format version</summary>
public readonly uint version;
public uint version;
/// <summary>Compressor 0</summary>
public readonly uint compressor0;
public uint compressor0;
/// <summary>Compressor 1</summary>
public readonly uint compressor1;
public uint compressor1;
/// <summary>Compressor 2</summary>
public readonly uint compressor2;
public uint compressor2;
/// <summary>Compressor 3</summary>
public readonly uint compressor3;
public uint compressor3;
/// <summary>Total bytes in image</summary>
public readonly ulong logicalbytes;
public ulong logicalbytes;
/// <summary>Offset to hunk map</summary>
public readonly ulong mapoffset;
public ulong mapoffset;
/// <summary>Offset to first metadata blob</summary>
public readonly ulong metaoffset;
public ulong metaoffset;
/// <summary>Bytes per hunk</summary>
public readonly uint hunkbytes;
public uint hunkbytes;
/// <summary>Bytes per unit within hunk</summary>
public readonly uint unitbytes;
public uint unitbytes;
/// <summary>SHA1 of raw data</summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 20)]
public readonly byte[] rawsha1;
public byte[] rawsha1;
/// <summary>SHA1 of raw+meta data</summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 20)]
public readonly byte[] sha1;
public byte[] sha1;
/// <summary>SHA1 of parent file</summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 20)]
public readonly byte[] parentsha1;
public byte[] parentsha1;
}
#endregion
@@ -280,18 +286,19 @@ public sealed partial class Chd
#region Nested type: MapEntryV3
[StructLayout(LayoutKind.Sequential, Pack = 1)]
readonly struct MapEntryV3
[SwapEndian]
partial struct MapEntryV3
{
/// <summary>Offset to hunk from start of image</summary>
public readonly ulong offset;
public ulong offset;
/// <summary>CRC32 of uncompressed hunk</summary>
public readonly uint crc;
public uint crc;
/// <summary>Lower 16 bits of length</summary>
public readonly ushort lengthLsb;
public ushort lengthLsb;
/// <summary>Upper 8 bits of length</summary>
public readonly byte length;
public byte length;
/// <summary>Hunk flags</summary>
public readonly byte flags;
public byte flags;
}
#endregion
@@ -312,11 +319,12 @@ public sealed partial class Chd
#region Nested type: MetadataHeader
[StructLayout(LayoutKind.Sequential, Pack = 1)]
readonly struct MetadataHeader
[SwapEndian]
partial struct MetadataHeader
{
public readonly uint tag;
public readonly uint flagsAndLength;
public readonly ulong next;
public uint tag;
public uint flagsAndLength;
public ulong next;
}
#endregion