From 5fe7a9cbcd5a35cbe9f1ca8b9b6257b8ff7cd1fc Mon Sep 17 00:00:00 2001 From: Natalia Portillo Date: Sun, 12 Oct 2025 14:28:15 +0100 Subject: [PATCH] [AaruFormat] Implement methods that require track as a parameter. --- Aaru.Images/AaruFormat/Read.cs | 89 +++++++++++++++++++++++++ Aaru.Images/AaruFormat/Unimplemented.cs | 26 -------- Aaru.Images/AaruFormat/Verify.cs | 47 +++++++++++++ 3 files changed, 136 insertions(+), 26 deletions(-) diff --git a/Aaru.Images/AaruFormat/Read.cs b/Aaru.Images/AaruFormat/Read.cs index f6f68c109..2cae671f5 100644 --- a/Aaru.Images/AaruFormat/Read.cs +++ b/Aaru.Images/AaruFormat/Read.cs @@ -1,8 +1,10 @@ using System; using System.IO; +using System.Linq; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using Aaru.CommonTypes.Enums; +using Aaru.CommonTypes.Structs; namespace Aaru.Images; @@ -169,6 +171,93 @@ public sealed partial class AaruFormat return ErrorNumber.NoError; } + /// + public ErrorNumber ReadSectorTag(ulong sectorAddress, uint track, SectorTagType tag, out byte[] buffer) + { + buffer = null; + + if(_imageInfo.MetadataMediaType != MetadataMediaType.OpticalDisc) return ErrorNumber.NotSupported; + + if(Tracks == null) return ErrorNumber.SectorNotFound; + + Track trk = Tracks.FirstOrDefault(t => t.Sequence == track); + + return trk?.Sequence != track + ? ErrorNumber.SectorNotFound + : ReadSectorTag(trk.StartSector + sectorAddress, tag, out buffer); + } + + /// + public ErrorNumber ReadSectors(ulong sectorAddress, uint length, uint track, out byte[] buffer) + { + buffer = null; + + if(_imageInfo.MetadataMediaType != MetadataMediaType.OpticalDisc) return ErrorNumber.NotSupported; + + if(Tracks == null) return ErrorNumber.SectorNotFound; + + Track trk = Tracks.FirstOrDefault(t => t.Sequence == track); + + if(trk?.Sequence != track) return ErrorNumber.SectorNotFound; + + return trk.StartSector + sectorAddress + length > trk.EndSector + 1 + ? ErrorNumber.OutOfRange + : ReadSectors(trk.StartSector + sectorAddress, length, out buffer); + } + + /// + public ErrorNumber ReadSectorsTag(ulong sectorAddress, uint length, uint track, SectorTagType tag, + out byte[] buffer) + { + buffer = null; + + if(_imageInfo.MetadataMediaType != MetadataMediaType.OpticalDisc) return ErrorNumber.NotSupported; + + if(Tracks == null) return ErrorNumber.SectorNotFound; + + Track trk = Tracks.FirstOrDefault(t => t.Sequence == track); + + return trk?.Sequence != track + ? ErrorNumber.SectorNotFound + : trk.StartSector + sectorAddress + length > trk.EndSector + 1 + ? ErrorNumber.OutOfRange + : ReadSectorsTag(trk.StartSector + sectorAddress, length, tag, out buffer); + } + + /// + public ErrorNumber ReadSectorLong(ulong sectorAddress, uint track, out byte[] buffer) + { + buffer = null; + + if(_imageInfo.MetadataMediaType != MetadataMediaType.OpticalDisc) return ErrorNumber.NotSupported; + + if(Tracks == null) return ErrorNumber.SectorNotFound; + + Track trk = Tracks.FirstOrDefault(t => t.Sequence == track); + + return trk?.Sequence != track + ? ErrorNumber.SectorNotFound + : ReadSectorLong(trk.StartSector + sectorAddress, out buffer); + } + + /// + public ErrorNumber ReadSectorsLong(ulong sectorAddress, uint length, uint track, out byte[] buffer) + { + buffer = null; + + if(_imageInfo.MetadataMediaType != MetadataMediaType.OpticalDisc) return ErrorNumber.NotSupported; + + if(Tracks == null) return ErrorNumber.SectorNotFound; + + Track trk = Tracks.FirstOrDefault(t => t.Sequence == track); + + return trk?.Sequence != track + ? ErrorNumber.SectorNotFound + : trk.StartSector + sectorAddress + length > trk.EndSector + 1 + ? ErrorNumber.OutOfRange + : ReadSectorsLong(trk.StartSector + sectorAddress, length, out buffer); + } + #endregion // AARU_EXPORT int32_t AARU_CALL aaruf_read_media_tag(void *context, uint8_t *data, const int32_t tag, uint32_t *length) diff --git a/Aaru.Images/AaruFormat/Unimplemented.cs b/Aaru.Images/AaruFormat/Unimplemented.cs index f31b070d9..d5d3cab8d 100644 --- a/Aaru.Images/AaruFormat/Unimplemented.cs +++ b/Aaru.Images/AaruFormat/Unimplemented.cs @@ -2,7 +2,6 @@ using System; using System.Collections.Generic; using Aaru.CommonTypes; using Aaru.CommonTypes.AaruMetadata; -using Aaru.CommonTypes.Enums; using Aaru.CommonTypes.Structs; using TapeFile = Aaru.CommonTypes.Structs.TapeFile; using TapePartition = Aaru.CommonTypes.Structs.TapePartition; @@ -24,31 +23,6 @@ public sealed partial class AaruFormat /// public bool SetImageInfo(ImageInfo imageInfo) => throw new NotImplementedException(); - /// - public ErrorNumber ReadSectorTag(ulong sectorAddress, uint track, SectorTagType tag, out byte[] buffer) => - throw new NotImplementedException(); - - /// - public ErrorNumber ReadSectors(ulong sectorAddress, uint length, uint track, out byte[] buffer) => - throw new NotImplementedException(); - - /// - public ErrorNumber ReadSectorsTag(ulong sectorAddress, uint length, uint track, SectorTagType tag, - out byte[] buffer) => throw new NotImplementedException(); - - /// - public ErrorNumber ReadSectorLong(ulong sectorAddress, uint track, out byte[] buffer) => - throw new NotImplementedException(); - - /// - public ErrorNumber ReadSectorsLong(ulong sectorAddress, uint length, uint track, out byte[] buffer) => - throw new NotImplementedException(); - - - /// - public bool? VerifySectors(ulong sectorAddress, uint length, uint track, out List failingLbas, - out List unknownLbas) => throw new NotImplementedException(); - /// public bool SetTracks(List tracks) => throw new NotImplementedException(); diff --git a/Aaru.Images/AaruFormat/Verify.cs b/Aaru.Images/AaruFormat/Verify.cs index 158a5adc9..410c4033c 100644 --- a/Aaru.Images/AaruFormat/Verify.cs +++ b/Aaru.Images/AaruFormat/Verify.cs @@ -81,6 +81,53 @@ public sealed partial class AaruFormat return failingLbas.Count <= 0; } + /// + public bool? VerifySectors(ulong sectorAddress, uint length, uint track, out List failingLbas, + out List unknownLbas) + { + // Right now only CompactDisc sectors are verifiable + if(_imageInfo.MetadataMediaType != MetadataMediaType.OpticalDisc || Tracks == null) + { + failingLbas = []; + unknownLbas = []; + + for(ulong i = sectorAddress; i < sectorAddress + length; i++) unknownLbas.Add(i); + + return null; + } + + failingLbas = []; + unknownLbas = []; + + ErrorNumber errno = ReadSectorsLong(sectorAddress, length, track, out byte[] buffer); + + if(errno != ErrorNumber.NoError) return null; + + var bps = (int)(buffer.Length / length); + var sector = new byte[bps]; + + for(var i = 0; i < length; i++) + { + Array.Copy(buffer, i * bps, sector, 0, bps); + bool? sectorStatus = CdChecksums.CheckCdSector(sector); + + switch(sectorStatus) + { + case null: + unknownLbas.Add((ulong)i + sectorAddress); + + break; + case false: + failingLbas.Add((ulong)i + sectorAddress); + + break; + } + } + + if(unknownLbas.Count > 0) return null; + + return failingLbas.Count <= 0; + } #endregion