Refactor IOpticalMediaImage.ReadSector(s) to return error status instead of buffer.

This commit is contained in:
2021-09-21 01:38:54 +01:00
parent 34df6087ce
commit b7fa638410
19 changed files with 281 additions and 274 deletions

View File

@@ -118,7 +118,14 @@ namespace Aaru.Core
UpdateProgress2Event?.Invoke($"Entropying sector {i + 1} of track {currentTrack.Sequence}",
(long)(i + 1), (long)currentTrack.EndSector);
byte[] sector = opticalMediaImage.ReadSector(i, currentTrack.Sequence);
ErrorNumber errno = opticalMediaImage.ReadSector(i, currentTrack.Sequence, out byte[] sector);
if(errno != ErrorNumber.NoError)
{
AaruConsole.ErrorWriteLine($"Error {errno} while reading sector {i}, continuing...");
continue;
}
if(duplicatedSectors)
{

View File

@@ -515,8 +515,16 @@ namespace Aaru.Gui.ViewModels.Windows
if(sectors - doneSectors >= SECTORS_TO_READ)
{
sector = opticalMediaImage.ReadSectors(doneSectors, SECTORS_TO_READ,
currentTrack.Sequence);
errno = opticalMediaImage.ReadSectors(doneSectors, SECTORS_TO_READ,
currentTrack.Sequence, out sector);
if(errno != ErrorNumber.NoError)
{
AaruConsole.ErrorWriteLine($"Error {errno} reading sector {doneSectors}");
_cancel = true;
continue;
}
ulong doneSectorsToInvoke = doneSectors;
@@ -532,8 +540,16 @@ namespace Aaru.Gui.ViewModels.Windows
}
else
{
sector = opticalMediaImage.ReadSectors(doneSectors, (uint)(sectors - doneSectors),
currentTrack.Sequence);
errno = opticalMediaImage.ReadSectors(doneSectors, (uint)(sectors - doneSectors),
currentTrack.Sequence, out sector);
if(errno != ErrorNumber.NoError)
{
AaruConsole.ErrorWriteLine($"Error {errno} reading sector {doneSectors}");
_cancel = true;
continue;
}
ulong doneSectorsToInvoke = doneSectors;

View File

@@ -1607,19 +1607,17 @@ namespace Aaru.DiscImages
ReadSectorsTag(sectorAddress, 1, tag, out buffer);
/// <inheritdoc />
public byte[] ReadSector(ulong sectorAddress, uint track)
public ErrorNumber ReadSector(ulong sectorAddress, uint track, out byte[] buffer)
{
buffer = null;
if(_imageInfo.XmlMediaType != XmlMediaType.OpticalDisc)
throw new FeatureNotPresentImageException("Feature not present in image");
return ErrorNumber.NotSupported;
Track trk = Tracks.FirstOrDefault(t => t.Sequence == track);
if(trk?.Sequence != track)
throw new ArgumentOutOfRangeException(nameof(track), "Track does not exist in disc image");
ReadSector(trk.StartSector + sectorAddress, out byte[] sector);
return sector;
return trk?.Sequence != track ? ErrorNumber.SectorNotFound
: ReadSector(trk.StartSector + sectorAddress, out buffer);
}
/// <inheritdoc />
@@ -1949,23 +1947,20 @@ namespace Aaru.DiscImages
}
/// <inheritdoc />
public byte[] ReadSectors(ulong sectorAddress, uint length, uint track)
public ErrorNumber ReadSectors(ulong sectorAddress, uint length, uint track, out byte[] buffer)
{
buffer = null;
if(_imageInfo.XmlMediaType != XmlMediaType.OpticalDisc)
throw new FeatureNotPresentImageException("Feature not present in image");
return ErrorNumber.NotSupported;
Track trk = Tracks.FirstOrDefault(t => t.Sequence == track);
if(trk?.Sequence != track)
throw new ArgumentOutOfRangeException(nameof(track), "Track does not exist in disc image");
return ErrorNumber.SectorNotFound;
if(trk.StartSector + sectorAddress + length > trk.EndSector + 1)
throw new ArgumentOutOfRangeException(nameof(length),
$"Requested more sectors ({length + sectorAddress}) than present in track ({trk.EndSector - trk.StartSector + 1}), won't cross tracks");
ReadSectors(trk.StartSector + sectorAddress, length, out byte[] buffer);
return buffer;
return trk.StartSector + sectorAddress + length > trk.EndSector + 1 ? ErrorNumber.OutOfRange
: ReadSectors(trk.StartSector + sectorAddress, length, out buffer);
}
/// <inheritdoc />

View File

@@ -789,7 +789,8 @@ namespace Aaru.DiscImages
ReadSectorsTag(sectorAddress, 1, tag, out buffer);
/// <inheritdoc />
public byte[] ReadSector(ulong sectorAddress, uint track) => ReadSectors(sectorAddress, 1, track);
public ErrorNumber ReadSector(ulong sectorAddress, uint track, out byte[] buffer) =>
ReadSectors(sectorAddress, 1, track, out buffer);
/// <inheritdoc />
public byte[] ReadSectorTag(ulong sectorAddress, uint track, SectorTagType tag) =>
@@ -811,9 +812,7 @@ namespace Aaru.DiscImages
if(sectorAddress - kvp.Value >= extra.sectors + extra.pregap)
continue;
buffer = ReadSectors(sectorAddress - kvp.Value, length, kvp.Key);
return ErrorNumber.NoError;
return ReadSectors(sectorAddress - kvp.Value, length, kvp.Key, out buffer);
}
return ErrorNumber.SectorNotFound;
@@ -844,15 +843,16 @@ namespace Aaru.DiscImages
}
/// <inheritdoc />
public byte[] ReadSectors(ulong sectorAddress, uint length, uint track)
public ErrorNumber ReadSectors(ulong sectorAddress, uint length, uint track, out byte[] buffer)
{
buffer = null;
if(!_alcTracks.TryGetValue((int)track, out Track alcTrack) ||
!_alcTrackExtras.TryGetValue((int)track, out TrackExtra alcExtra))
throw new ArgumentOutOfRangeException(nameof(track), "Track does not exist in disc image");
return ErrorNumber.OutOfRange;
if(length + sectorAddress > alcExtra.sectors + alcExtra.pregap)
throw new ArgumentOutOfRangeException(nameof(length),
$"Requested more sectors ({length + sectorAddress}) than present in track ({alcExtra.sectors + alcExtra.pregap}), won't cross tracks");
return ErrorNumber.OutOfRange;
uint sectorOffset;
uint sectorSize;
@@ -904,7 +904,7 @@ namespace Aaru.DiscImages
break;
}
default: throw new FeatureSupportedButNotImplementedImageException("Unsupported track type");
default: return ErrorNumber.NotSupported;
}
switch(alcTrack.subMode)
@@ -917,16 +917,16 @@ namespace Aaru.DiscImages
sectorSkip += 96;
break;
default: throw new FeatureSupportedButNotImplementedImageException("Unsupported subchannel type");
default: return ErrorNumber.NotSupported;
}
byte[] buffer = new byte[sectorSize * length];
buffer = new byte[sectorSize * length];
if(alcTrack.point == 1 &&
alcExtra.pregap > 150)
{
if(sectorAddress + 150 < alcExtra.pregap)
return buffer;
return ErrorNumber.NoError;
sectorAddress -= alcExtra.pregap - 150;
}
@@ -971,7 +971,7 @@ namespace Aaru.DiscImages
Array.Copy(sector, 0, buffer, i * sectorSize, sectorSize);
}
return buffer;
return ErrorNumber.NoError;
}
/// <inheritdoc />

View File

@@ -840,7 +840,8 @@ namespace Aaru.DiscImages
ReadSectorsTag(sectorAddress, 1, tag, out buffer);
/// <inheritdoc />
public byte[] ReadSector(ulong sectorAddress, uint track) => ReadSectors(sectorAddress, 1, track);
public ErrorNumber ReadSector(ulong sectorAddress, uint track, out byte[] buffer) =>
ReadSectors(sectorAddress, 1, track, out buffer);
/// <inheritdoc />
public byte[] ReadSectorTag(ulong sectorAddress, uint track, SectorTagType tag) =>
@@ -855,11 +856,7 @@ namespace Aaru.DiscImages
from track in Tracks where track.Sequence == kvp.Key
where sectorAddress - kvp.Value <
track.EndSector - track.StartSector + 1 select kvp)
{
buffer = ReadSectors(sectorAddress - kvp.Value, length, kvp.Key);
return ErrorNumber.NoError;
}
return ReadSectors(sectorAddress - kvp.Value, length, kvp.Key, out buffer);
return ErrorNumber.SectorNotFound;
}
@@ -883,26 +880,16 @@ namespace Aaru.DiscImages
}
/// <inheritdoc />
public byte[] ReadSectors(ulong sectorAddress, uint length, uint track)
public ErrorNumber ReadSectors(ulong sectorAddress, uint length, uint track, out byte[] buffer)
{
var aaruTrack = new Track
{
Sequence = 0
};
foreach(Track bwTrack in Tracks.Where(bwTrack => bwTrack.Sequence == track))
{
aaruTrack = bwTrack;
break;
}
buffer = null;
Track? aaruTrack = Tracks.FirstOrDefault(bwTrack => bwTrack.Sequence == track);
if(aaruTrack is null)
throw new ArgumentOutOfRangeException(nameof(track), "Track does not exist in disc image");
return ErrorNumber.SectorNotFound;
if(length + sectorAddress > aaruTrack.EndSector - aaruTrack.StartSector + 1)
throw new ArgumentOutOfRangeException(nameof(length),
$"Requested more sectors ({length + sectorAddress}) than present in track ({aaruTrack.EndSector - aaruTrack.StartSector + 1}), won't cross tracks");
return ErrorNumber.OutOfRange;
uint sectorOffset;
uint sectorSize;
@@ -944,10 +931,10 @@ namespace Aaru.DiscImages
break;
}
default: throw new FeatureSupportedButNotImplementedImageException("Unsupported track type");
default: return ErrorNumber.NotSupported;
}
byte[] buffer = new byte[sectorSize * length];
buffer = new byte[sectorSize * length];
_imageStream = aaruTrack.Filter.GetDataForkStream();
var br = new BinaryReader(_imageStream);
@@ -985,7 +972,7 @@ namespace Aaru.DiscImages
Array.Copy(sector, 0, buffer, i * sectorSize, sectorSize);
}
return buffer;
return ErrorNumber.NoError;
}
/// <inheritdoc />

View File

@@ -1441,7 +1441,8 @@ namespace Aaru.DiscImages
ReadSectorsTag(sectorAddress, 1, tag, out buffer);
/// <inheritdoc />
public byte[] ReadSector(ulong sectorAddress, uint track) => ReadSectors(sectorAddress, 1, track);
public ErrorNumber ReadSector(ulong sectorAddress, uint track, out byte[] buffer) =>
ReadSectors(sectorAddress, 1, track, out buffer);
/// <inheritdoc />
public byte[] ReadSectorTag(ulong sectorAddress, uint track, SectorTagType tag) =>
@@ -1456,11 +1457,7 @@ namespace Aaru.DiscImages
from track in Tracks where track.Sequence == kvp.Key
where sectorAddress - kvp.Value <
track.EndSector - track.StartSector + 1 select kvp)
{
buffer = ReadSectors(sectorAddress - kvp.Value, length, kvp.Key);
return ErrorNumber.NoError;
}
return ReadSectors(sectorAddress - kvp.Value, length, kvp.Key, out buffer);
return ErrorNumber.SectorNotFound;
}
@@ -1484,27 +1481,18 @@ namespace Aaru.DiscImages
}
/// <inheritdoc />
public byte[] ReadSectors(ulong sectorAddress, uint length, uint track)
public ErrorNumber ReadSectors(ulong sectorAddress, uint length, uint track, out byte[] buffer)
{
buffer = null;
// TODO: Cross data files
var aaruTrack = new Track
{
Sequence = 0
};
foreach(Track bwTrack in Tracks.Where(bwTrack => bwTrack.Sequence == track))
{
aaruTrack = bwTrack;
break;
}
Track? aaruTrack = Tracks.FirstOrDefault(bwTrack => bwTrack.Sequence == track);
if(aaruTrack is null)
throw new ArgumentOutOfRangeException(nameof(track), "Track does not exist in disc image");
return ErrorNumber.SectorNotFound;
if(length + sectorAddress > aaruTrack.EndSector - aaruTrack.StartSector + 1)
throw new ArgumentOutOfRangeException(nameof(length),
$"Requested more sectors ({length + sectorAddress}) than present in track ({aaruTrack.EndSector - aaruTrack.StartSector + 1}), won't cross tracks");
return ErrorNumber.OutOfRange;
DataFileCharacteristics chars = (from characteristics in _filePaths let firstSector =
characteristics.StartLba let lastSector =
@@ -1515,7 +1503,7 @@ namespace Aaru.DiscImages
if(string.IsNullOrEmpty(chars.FilePath) ||
chars.FileFilter == null)
throw new ArgumentOutOfRangeException(nameof(chars.FileFilter), "Track does not exist in disc image");
return ErrorNumber.SectorNotFound;
uint sectorOffset;
uint sectorSize;
@@ -1559,7 +1547,7 @@ namespace Aaru.DiscImages
break;
}
default: throw new FeatureSupportedButNotImplementedImageException("Unsupported track type");
default: return ErrorNumber.NotSupported;
}
switch(chars.Subchannel)
@@ -1576,10 +1564,10 @@ namespace Aaru.DiscImages
sectorSkip += 96;
break;
default: throw new FeatureSupportedButNotImplementedImageException("Unsupported subchannel type");
default: return ErrorNumber.NotSupported;
}
byte[] buffer = new byte[sectorSize * length];
buffer = new byte[sectorSize * length];
_imageStream = chars.FileFilter.GetDataForkStream();
var br = new BinaryReader(_imageStream);
@@ -1616,7 +1604,7 @@ namespace Aaru.DiscImages
Array.Copy(sector, 0, buffer, i * sectorSize, sectorSize);
}
return buffer;
return ErrorNumber.NoError;
}
/// <inheritdoc />

View File

@@ -921,7 +921,8 @@ namespace Aaru.DiscImages
ReadSectorsTag(sectorAddress, 1, tag, out buffer);
/// <inheritdoc />
public byte[] ReadSector(ulong sectorAddress, uint track) => ReadSectors(sectorAddress, 1, track);
public ErrorNumber ReadSector(ulong sectorAddress, uint track, out byte[] buffer) =>
ReadSectors(sectorAddress, 1, track, out buffer);
/// <inheritdoc />
public byte[] ReadSectorTag(ulong sectorAddress, uint track, SectorTagType tag) =>
@@ -936,11 +937,7 @@ namespace Aaru.DiscImages
from cdrdaoTrack in _discimage.Tracks
where cdrdaoTrack.Sequence == kvp.Key
where sectorAddress - kvp.Value < cdrdaoTrack.Sectors select kvp)
{
buffer = ReadSectors(sectorAddress - kvp.Value, length, kvp.Key);
return ErrorNumber.NoError;
}
return ReadSectors(sectorAddress - kvp.Value, length, kvp.Key, out buffer);
return ErrorNumber.SectorNotFound;
}
@@ -964,8 +961,10 @@ namespace Aaru.DiscImages
}
/// <inheritdoc />
public byte[] ReadSectors(ulong sectorAddress, uint length, uint track)
public ErrorNumber ReadSectors(ulong sectorAddress, uint length, uint track, out byte[] buffer)
{
buffer = null;
var aaruTrack = new CdrdaoTrack
{
Sequence = 0
@@ -979,11 +978,10 @@ namespace Aaru.DiscImages
}
if(aaruTrack.Sequence == 0)
throw new ArgumentOutOfRangeException(nameof(track), "Track does not exist in disc image");
return ErrorNumber.SectorNotFound;
if(length > aaruTrack.Sectors)
throw new ArgumentOutOfRangeException(nameof(length),
"Requested more sectors than present in track, won't cross tracks");
return ErrorNumber.OutOfRange;
uint sectorOffset;
uint sectorSize;
@@ -1044,13 +1042,13 @@ namespace Aaru.DiscImages
break;
}
default: throw new FeatureSupportedButNotImplementedImageException("Unsupported track type");
default: return ErrorNumber.NotSupported;
}
if(aaruTrack.Subchannel)
sectorSkip += 96;
byte[] buffer = new byte[sectorSize * length];
buffer = new byte[sectorSize * length];
_imageStream = aaruTrack.Trackfile.Datafilter.GetDataForkStream();
var br = new BinaryReader(_imageStream);
@@ -1089,7 +1087,7 @@ namespace Aaru.DiscImages
// cdrdao audio tracks are endian swapped corresponding to Aaru
if(aaruTrack.Tracktype != CDRDAO_TRACK_TYPE_AUDIO)
return buffer;
return ErrorNumber.NoError;
byte[] swapped = new byte[buffer.Length];
@@ -1099,7 +1097,9 @@ namespace Aaru.DiscImages
swapped[i + 1] = buffer[i];
}
return swapped;
buffer = swapped;
return ErrorNumber.NoError;
}
/// <inheritdoc />

View File

@@ -1588,7 +1588,8 @@ namespace Aaru.DiscImages
ReadSectorsTag(sectorAddress, 1, tag, out buffer);
/// <inheritdoc />
public byte[] ReadSector(ulong sectorAddress, uint track) => ReadSectors(sectorAddress, 1, track);
public ErrorNumber ReadSector(ulong sectorAddress, uint track, out byte[] buffer) =>
ReadSectors(sectorAddress, 1, track, out buffer);
/// <inheritdoc />
public byte[] ReadSectorTag(ulong sectorAddress, uint track, SectorTagType tag) =>
@@ -1603,11 +1604,7 @@ namespace Aaru.DiscImages
from cdrwinTrack in _discImage.Tracks
where cdrwinTrack.Sequence == kvp.Key
where sectorAddress - kvp.Value < cdrwinTrack.Sectors select kvp)
{
buffer = ReadSectors(sectorAddress - kvp.Value, length, kvp.Key);
return ErrorNumber.NoError;
}
return ReadSectors(sectorAddress - kvp.Value, length, kvp.Key, out buffer);
return ErrorNumber.SectorNotFound;
}
@@ -1639,26 +1636,16 @@ namespace Aaru.DiscImages
}
/// <inheritdoc />
public byte[] ReadSectors(ulong sectorAddress, uint length, uint track)
public ErrorNumber ReadSectors(ulong sectorAddress, uint length, uint track, out byte[] buffer)
{
var aaruTrack = new CdrWinTrack
{
Sequence = 0
};
buffer = null;
CdrWinTrack? aaruTrack = _discImage.Tracks.FirstOrDefault(cdrwinTrack => cdrwinTrack.Sequence == track);
foreach(CdrWinTrack cdrwinTrack in _discImage.Tracks.Where(cdrwinTrack => cdrwinTrack.Sequence == track))
{
aaruTrack = cdrwinTrack;
break;
}
if(aaruTrack.Sequence == 0)
throw new ArgumentOutOfRangeException(nameof(track), "Track does not exist in disc image");
if(aaruTrack is null)
return ErrorNumber.SectorNotFound;
if(length > aaruTrack.Sectors)
throw new ArgumentOutOfRangeException(nameof(length),
"Requested more sectors than present in track, won't cross tracks");
return ErrorNumber.OutOfRange;
uint sectorOffset;
uint sectorSize;
@@ -1728,10 +1715,10 @@ namespace Aaru.DiscImages
break;
}
default: throw new FeatureSupportedButNotImplementedImageException("Unsupported track type");
default: return ErrorNumber.NotSupported;
}
byte[] buffer = new byte[sectorSize * length];
buffer = new byte[sectorSize * length];
// If it's the lost pregap
if(track == 1 &&
@@ -1741,14 +1728,19 @@ namespace Aaru.DiscImages
{
// If we need to mix lost with present data
if(sectorAddress + length <= _lostPregap)
return buffer;
return ErrorNumber.NoError;
ulong pregapPos = _lostPregap - sectorAddress;
byte[] presentData = ReadSectors(_lostPregap, (uint)(length - pregapPos), track);
ErrorNumber errno =
ReadSectors(_lostPregap, (uint)(length - pregapPos), track, out byte[] presentData);
if(errno != ErrorNumber.NoError)
return errno;
Array.Copy(presentData, 0, buffer, (long)(pregapPos * sectorSize), presentData.Length);
return buffer;
return ErrorNumber.NoError;
}
sectorAddress -= _lostPregap;
@@ -1789,7 +1781,7 @@ namespace Aaru.DiscImages
Array.Copy(sector, 0, buffer, i * sectorSize, sectorSize);
}
return buffer;
return ErrorNumber.NoError;
}
/// <inheritdoc />
@@ -2009,7 +2001,12 @@ namespace Aaru.DiscImages
ulong pregapPos = _lostPregap - sectorAddress;
byte[] presentData = ReadSectors(_lostPregap, (uint)(length - pregapPos), track);
ErrorNumber errno =
ReadSectors(_lostPregap, (uint)(length - pregapPos), track, out byte[] presentData);
if(errno != ErrorNumber.NoError)
return null;
Array.Copy(presentData, 0, buffer, (long)(pregapPos * sectorSize), presentData.Length);
return buffer;
@@ -2069,7 +2066,11 @@ namespace Aaru.DiscImages
public byte[] ReadSectorsLong(ulong sectorAddress, uint length, uint track)
{
if(!_isCd)
return ReadSectors(sectorAddress, length, track);
{
ErrorNumber errno = ReadSectors(sectorAddress, length, track, out byte[] nonCdBuffer);
return errno != ErrorNumber.NoError ? null : nonCdBuffer;
}
var aaruTrack = new CdrWinTrack
{
@@ -2158,7 +2159,12 @@ namespace Aaru.DiscImages
ulong pregapPos = _lostPregap - sectorAddress;
byte[] presentData = ReadSectors(_lostPregap, (uint)(length - pregapPos), track);
ErrorNumber errno =
ReadSectors(_lostPregap, (uint)(length - pregapPos), track, out byte[] presentData);
if(errno != ErrorNumber.NoError)
return null;
Array.Copy(presentData, 0, buffer, (long)(pregapPos * sectorSize), presentData.Length);
return buffer;

View File

@@ -1939,14 +1939,11 @@ namespace Aaru.DiscImages
}
/// <inheritdoc />
public byte[] ReadSector(ulong sectorAddress, uint track)
public ErrorNumber ReadSector(ulong sectorAddress, uint track, out byte[] buffer)
{
if(_isHdd)
throw new FeaturedNotSupportedByDiscImageException("Cannot access optical tracks on a hard disk image");
buffer = null;
ErrorNumber errno = ReadSector(GetAbsoluteSector(sectorAddress, track), out byte[] buffer);
return errno == ErrorNumber.NoError ? buffer : null;
return _isHdd ? ErrorNumber.NotSupported : ReadSector(GetAbsoluteSector(sectorAddress, track), out buffer);
}
/// <inheritdoc />
@@ -1961,14 +1958,12 @@ namespace Aaru.DiscImages
}
/// <inheritdoc />
public byte[] ReadSectors(ulong sectorAddress, uint length, uint track)
public ErrorNumber ReadSectors(ulong sectorAddress, uint length, uint track, out byte[] buffer)
{
if(_isHdd)
throw new FeaturedNotSupportedByDiscImageException("Cannot access optical tracks on a hard disk image");
buffer = null;
ErrorNumber errno = ReadSectors(GetAbsoluteSector(sectorAddress, track), length, out byte[] buffer);
return errno == ErrorNumber.NoError ? buffer : null;
return _isHdd ? ErrorNumber.NotSupported
: ReadSectors(GetAbsoluteSector(sectorAddress, track), length, out buffer);
}
/// <inheritdoc />

View File

@@ -937,7 +937,8 @@ namespace Aaru.DiscImages
ReadSectorsTag(sectorAddress, 1, tag, out buffer);
/// <inheritdoc />
public byte[] ReadSector(ulong sectorAddress, uint track) => ReadSectors(sectorAddress, 1, track);
public ErrorNumber ReadSector(ulong sectorAddress, uint track, out byte[] buffer) =>
ReadSectors(sectorAddress, 1, track, out buffer);
/// <inheritdoc />
public byte[] ReadSectorTag(ulong sectorAddress, uint track, SectorTagType tag) =>
@@ -952,11 +953,7 @@ namespace Aaru.DiscImages
from track in Tracks where track.Sequence == kvp.Key
where sectorAddress - kvp.Value <
track.EndSector - track.StartSector + 1 select kvp)
{
buffer = ReadSectors(sectorAddress - kvp.Value, length, kvp.Key);
return ErrorNumber.NoError;
}
return ReadSectors(sectorAddress - kvp.Value, length, kvp.Key, out buffer);
return ErrorNumber.SectorNotFound;
}
@@ -985,29 +982,16 @@ namespace Aaru.DiscImages
}
/// <inheritdoc />
public byte[] ReadSectors(ulong sectorAddress, uint length, uint track)
public ErrorNumber ReadSectors(ulong sectorAddress, uint length, uint track, out byte[] buffer)
{
var aaruTrack = new Track
{
Sequence = 0
};
foreach(Track linqTrack in Tracks.Where(linqTrack => linqTrack.Sequence == track))
{
aaruTrack = linqTrack;
break;
}
buffer = null;
Track? aaruTrack = Tracks.FirstOrDefault(linqTrack => linqTrack.Sequence == track);
if(aaruTrack is null)
throw new ArgumentOutOfRangeException(nameof(track), "Track does not exist in disc image");
return ErrorNumber.SectorNotFound;
if(length + sectorAddress - 1 > aaruTrack.EndSector)
throw new ArgumentOutOfRangeException(nameof(length),
string.
Format("Requested more sectors ({0} {2}) than present in track ({1}), won't cross tracks",
length + sectorAddress, aaruTrack.EndSector,
sectorAddress));
return ErrorNumber.OutOfRange;
uint sectorOffset;
uint sectorSize;
@@ -1043,10 +1027,10 @@ namespace Aaru.DiscImages
break;
}
default: throw new FeatureSupportedButNotImplementedImageException("Unsupported track type");
default: return ErrorNumber.NotSupported;
}
byte[] buffer = new byte[sectorSize * length];
buffer = new byte[sectorSize * length];
_dataStream.Seek((long)(aaruTrack.FileOffset + (sectorAddress * 2352)), SeekOrigin.Begin);
@@ -1079,7 +1063,7 @@ namespace Aaru.DiscImages
Array.Copy(sector, 0, buffer, i * sectorSize, sectorSize);
}
return buffer;
return ErrorNumber.NoError;
}
/// <inheritdoc />

View File

@@ -816,7 +816,8 @@ namespace Aaru.DiscImages
ReadSectorsTag(sectorAddress, 1, tag, out buffer);
/// <inheritdoc />
public byte[] ReadSector(ulong sectorAddress, uint track) => ReadSectors(sectorAddress, 1, track);
public ErrorNumber ReadSector(ulong sectorAddress, uint track, out byte[] buffer) =>
ReadSectors(sectorAddress, 1, track, out buffer);
/// <inheritdoc />
public byte[] ReadSectorTag(ulong sectorAddress, uint track, SectorTagType tag) =>
@@ -831,11 +832,7 @@ namespace Aaru.DiscImages
from track in Tracks where track.Sequence == kvp.Key
where sectorAddress - kvp.Value <
track.EndSector - track.StartSector + 1 select kvp)
{
buffer = ReadSectors(sectorAddress - kvp.Value, length, kvp.Key);
return ErrorNumber.NoError;
}
return ReadSectors(sectorAddress - kvp.Value, length, kvp.Key, out buffer);
return ErrorNumber.SectorNotFound;
}
@@ -859,26 +856,17 @@ namespace Aaru.DiscImages
}
/// <inheritdoc />
public byte[] ReadSectors(ulong sectorAddress, uint length, uint track)
public ErrorNumber ReadSectors(ulong sectorAddress, uint length, uint track, out byte[] buffer)
{
var aaruTrack = new Track
{
Sequence = 0
};
buffer = null;
foreach(Track linqTrack in Tracks.Where(linqTrack => linqTrack.Sequence == track))
{
aaruTrack = linqTrack;
break;
}
Track? aaruTrack = Tracks.FirstOrDefault(linqTrack => linqTrack.Sequence == track);
if(aaruTrack is null)
throw new ArgumentOutOfRangeException(nameof(track), "Track does not exist in disc image");
return ErrorNumber.SectorNotFound;
if(length + sectorAddress > aaruTrack.EndSector - aaruTrack.StartSector + 1)
throw new ArgumentOutOfRangeException(nameof(length),
$"Requested more sectors ({length + sectorAddress}) than present in track ({aaruTrack.EndSector - aaruTrack.StartSector + 1}), won't cross tracks");
return ErrorNumber.OutOfRange;
uint sectorOffset;
uint sectorSize;
@@ -919,7 +907,7 @@ namespace Aaru.DiscImages
}
break;
default: throw new FeatureSupportedButNotImplementedImageException("Unsupported track type");
default: return ErrorNumber.NotSupported;
}
switch(aaruTrack.SubchannelType)
@@ -936,10 +924,10 @@ namespace Aaru.DiscImages
sectorSkip += 96;
break;
default: throw new FeatureSupportedButNotImplementedImageException("Unsupported subchannel type");
default: return ErrorNumber.NotSupported;
}
byte[] buffer = new byte[sectorSize * length];
buffer = new byte[sectorSize * length];
_imageStream.Seek((long)(aaruTrack.FileOffset + (sectorAddress * (sectorOffset + sectorSize + sectorSkip))),
SeekOrigin.Begin);
@@ -977,7 +965,7 @@ namespace Aaru.DiscImages
Array.Copy(sector, 0, buffer, i * sectorSize, sectorSize);
}
return buffer;
return ErrorNumber.NoError;
}
/// <inheritdoc />
@@ -1273,7 +1261,11 @@ namespace Aaru.DiscImages
public byte[] ReadSectorsLong(ulong sectorAddress, uint length, uint track)
{
if(!_isCd)
return ReadSectors(sectorAddress, length, track);
{
ErrorNumber errno = ReadSectors(sectorAddress, length, track, out byte[] nonCdBuffer);
return errno == ErrorNumber.NoError ? nonCdBuffer : null;
}
var aaruTrack = new Track
{

View File

@@ -332,7 +332,8 @@ namespace Aaru.DiscImages
ReadSectorsTag(sectorAddress, 1, tag, out buffer);
/// <inheritdoc />
public byte[] ReadSector(ulong sectorAddress, uint track) => ReadSectors(sectorAddress, 1, track);
public ErrorNumber ReadSector(ulong sectorAddress, uint track, out byte[] buffer) =>
ReadSectors(sectorAddress, 1, track, out buffer);
/// <inheritdoc />
public byte[] ReadSectorTag(ulong sectorAddress, uint track, SectorTagType tag) =>
@@ -347,11 +348,7 @@ namespace Aaru.DiscImages
from gdiTrack in _discImage.Tracks
where gdiTrack.Sequence == kvp.Key
where sectorAddress - kvp.Value < gdiTrack.Sectors select kvp)
{
buffer = ReadSectors(sectorAddress - kvp.Value, length, kvp.Key);
return ErrorNumber.NoError;
}
return ReadSectors(sectorAddress - kvp.Value, length, kvp.Key, out buffer);
_offsetMap.TryGetValue(0, out ulong transitionStart);
@@ -359,9 +356,7 @@ namespace Aaru.DiscImages
sectorAddress >= _densitySeparationSectors + transitionStart)
return ErrorNumber.SectorNotFound;
buffer = ReadSectors(sectorAddress - transitionStart, length, 0);
return ErrorNumber.NoError;
return ReadSectors(sectorAddress - transitionStart, length, 0, out buffer);
}
/// <inheritdoc />
@@ -391,15 +386,18 @@ namespace Aaru.DiscImages
}
/// <inheritdoc />
public byte[] ReadSectors(ulong sectorAddress, uint length, uint track)
public ErrorNumber ReadSectors(ulong sectorAddress, uint length, uint track, out byte[] buffer)
{
buffer = null;
if(track == 0)
{
if(sectorAddress + length > _densitySeparationSectors)
throw new ArgumentOutOfRangeException(nameof(length),
"Requested more sectors than present in track, won't cross tracks");
return ErrorNumber.OutOfRange;
return new byte[length * 2352];
buffer = new byte[length * 2352];
return ErrorNumber.NoError;
}
var aaruTrack = new GdiTrack
@@ -415,11 +413,10 @@ namespace Aaru.DiscImages
}
if(aaruTrack.Sequence == 0)
throw new ArgumentOutOfRangeException(nameof(track), "Track does not exist in disc image");
return ErrorNumber.SectorNotFound;
if(sectorAddress + length > aaruTrack.Sectors)
throw new ArgumentOutOfRangeException(nameof(length),
"Requested more sectors than present in track, won't cross tracks");
return ErrorNumber.OutOfRange;
uint sectorOffset;
uint sectorSize;
@@ -452,10 +449,10 @@ namespace Aaru.DiscImages
break;
}
default: throw new FeatureSupportedButNotImplementedImageException("Unsupported track type");
default: return ErrorNumber.NotSupported;
}
byte[] buffer = new byte[sectorSize * length];
buffer = new byte[sectorSize * length];
ulong remainingSectors = length;
@@ -468,7 +465,7 @@ namespace Aaru.DiscImages
}
if(remainingSectors == 0)
return buffer;
return ErrorNumber.NoError;
_imageStream = aaruTrack.TrackFilter.GetDataForkStream();
var br = new BinaryReader(_imageStream);
@@ -484,9 +481,7 @@ namespace Aaru.DiscImages
if(sectorOffset == 0 &&
sectorSkip == 0 &&
remainingSectors == length)
{
buffer = br.ReadBytes((int)(sectorSize * remainingSectors));
}
else if(sectorOffset == 0 &&
sectorSkip == 0)
{
@@ -507,7 +502,7 @@ namespace Aaru.DiscImages
}
}
return buffer;
return ErrorNumber.NoError;
}
/// <inheritdoc />

View File

@@ -1593,7 +1593,8 @@ namespace Aaru.DiscImages
ReadSectorsTag(sectorAddress, 1, tag, out buffer);
/// <inheritdoc />
public byte[] ReadSector(ulong sectorAddress, uint track) => ReadSectors(sectorAddress, 1, track);
public ErrorNumber ReadSector(ulong sectorAddress, uint track, out byte[] buffer) =>
ReadSectors(sectorAddress, 1, track, out buffer);
/// <inheritdoc />
public byte[] ReadSectorTag(ulong sectorAddress, uint track, SectorTagType tag) =>
@@ -1608,11 +1609,7 @@ namespace Aaru.DiscImages
from track in Tracks where track.Sequence == kvp.Key
where sectorAddress - kvp.Value <=
track.EndSector - track.StartSector select kvp)
{
buffer = ReadSectors(sectorAddress - kvp.Value, length, kvp.Key);
return ErrorNumber.NoError;
}
return ReadSectors(sectorAddress - kvp.Value, length, kvp.Key, out buffer);
return ErrorNumber.SectorNotFound;
}
@@ -1636,14 +1633,15 @@ namespace Aaru.DiscImages
}
/// <inheritdoc />
public byte[] ReadSectors(ulong sectorAddress, uint length, uint track)
public ErrorNumber ReadSectors(ulong sectorAddress, uint length, uint track, out byte[] buffer)
{
buffer = null;
if(!_neroTracks.TryGetValue(track, out NeroTrack aaruTrack))
throw new ArgumentOutOfRangeException(nameof(track), "Track not found");
return ErrorNumber.SectorNotFound;
if(length > aaruTrack.Sectors)
throw new ArgumentOutOfRangeException(nameof(length),
$"Requested more sectors ({length}) than present in track ({aaruTrack.Sectors}), won't cross tracks");
return ErrorNumber.OutOfRange;
uint sectorOffset;
uint sectorSize;
@@ -1729,10 +1727,10 @@ namespace Aaru.DiscImages
break;
}
default: throw new FeatureSupportedButNotImplementedImageException("Unsupported track type");
default: return ErrorNumber.NotSupported;
}
byte[] buffer = new byte[sectorSize * length];
buffer = new byte[sectorSize * length];
_imageStream = _neroFilter.GetDataForkStream();
var br = new BinaryReader(_imageStream);
@@ -1769,7 +1767,7 @@ namespace Aaru.DiscImages
Array.Copy(sector, 0, buffer, i * sectorSize, sectorSize);
}
return buffer;
return ErrorNumber.NoError;
}
/// <inheritdoc />
@@ -2117,7 +2115,11 @@ namespace Aaru.DiscImages
public byte[] ReadSectorsLong(ulong sectorAddress, uint length, uint track)
{
if(!_isCd)
return ReadSectors(sectorAddress, length, track);
{
ErrorNumber errno = ReadSectors(sectorAddress, length, track, out byte[] nonCdBuffer);
return errno == ErrorNumber.NoError ? nonCdBuffer : null;
}
if(!_neroTracks.TryGetValue(track, out NeroTrack aaruTrack))
throw new ArgumentOutOfRangeException(nameof(track), "Track not found");

View File

@@ -1344,31 +1344,25 @@ namespace Aaru.DiscImages
}
/// <inheritdoc />
public byte[] ReadSector(ulong sectorAddress, uint track)
public ErrorNumber ReadSector(ulong sectorAddress, uint track, out byte[] buffer)
{
buffer = null;
if(_imageInfo.XmlMediaType != XmlMediaType.OpticalDisc)
throw new FeatureUnsupportedImageException("Feature not supported by image format");
return ErrorNumber.NotSupported;
if(track != 1)
throw new ArgumentOutOfRangeException(nameof(track), "Only a single track is supported");
ErrorNumber errno = ReadSector(sectorAddress, out byte[] buffer);
return errno == ErrorNumber.NoError ? buffer : null;
return track != 1 ? ErrorNumber.OutOfRange : ReadSector(sectorAddress, out buffer);
}
/// <inheritdoc />
public byte[] ReadSectors(ulong sectorAddress, uint length, uint track)
public ErrorNumber ReadSectors(ulong sectorAddress, uint length, uint track, out byte[] buffer)
{
buffer = null;
if(_imageInfo.XmlMediaType != XmlMediaType.OpticalDisc)
throw new FeatureUnsupportedImageException("Feature not supported by image format");
return ErrorNumber.NotSupported;
if(track != 1)
throw new ArgumentOutOfRangeException(nameof(track), "Only a single track is supported");
ErrorNumber errno = ReadSectors(sectorAddress, length, out byte[] buffer);
return errno == ErrorNumber.NoError ? buffer : null;
return track != 1 ? ErrorNumber.OutOfRange : ReadSectors(sectorAddress, length, out buffer);
}
/// <inheritdoc />

View File

@@ -344,25 +344,37 @@ namespace Aaru.Tests.Images
if(sectors - doneSectors >= SECTORS_TO_READ)
{
sector =
@long ? image.ReadSectorsLong(doneSectors, SECTORS_TO_READ,
currentTrack.Sequence)
: image.ReadSectors(doneSectors, SECTORS_TO_READ,
currentTrack.Sequence);
if(@long)
{
errno = ErrorNumber.NoError;
sector = image.ReadSectorsLong(doneSectors, SECTORS_TO_READ,
currentTrack.Sequence);
}
else
errno = image.ReadSectors(doneSectors, SECTORS_TO_READ,
currentTrack.Sequence, out sector);
doneSectors += SECTORS_TO_READ;
}
else
{
sector =
@long ? image.ReadSectorsLong(doneSectors, (uint)(sectors - doneSectors),
currentTrack.Sequence)
: image.ReadSectors(doneSectors, (uint)(sectors - doneSectors),
currentTrack.Sequence);
if(@long)
{
errno = ErrorNumber.NoError;
sector = image.ReadSectorsLong(doneSectors, (uint)(sectors - doneSectors),
currentTrack.Sequence);
}
else
errno = image.ReadSectors(doneSectors, (uint)(sectors - doneSectors),
currentTrack.Sequence, out sector);
doneSectors += sectors - doneSectors;
}
Assert.AreEqual(ErrorNumber.NoError, errno);
ctx.Update(sector);
}
}

View File

@@ -48,6 +48,7 @@ namespace Aaru.Tests.Issues
ulong previousTrackEnd = 0;
List<Track> inputTracks = opticalInput.Tracks;
ErrorNumber errno;
foreach(Track currentTrack in inputTracks)
{
@@ -60,18 +61,21 @@ namespace Aaru.Tests.Issues
if(sectors - doneSectors >= SECTORS_TO_READ)
{
sector = opticalInput.ReadSectors(doneSectors, SECTORS_TO_READ, currentTrack.Sequence);
errno = opticalInput.ReadSectors(doneSectors, SECTORS_TO_READ, currentTrack.Sequence,
out sector);
doneSectors += SECTORS_TO_READ;
}
else
{
sector = opticalInput.ReadSectors(doneSectors, (uint)(sectors - doneSectors),
currentTrack.Sequence);
errno = opticalInput.ReadSectors(doneSectors, (uint)(sectors - doneSectors),
currentTrack.Sequence, out sector);
doneSectors += sectors - doneSectors;
}
Assert.AreEqual(ErrorNumber.NoError, errno);
ctx.Update(sector);
}
}

View File

@@ -575,24 +575,37 @@ namespace Aaru.Tests.WritableImages
if(sectors - doneSectors >= SECTORS_TO_READ)
{
sector =
@long ? image.ReadSectorsLong(doneSectors, SECTORS_TO_READ,
currentTrack.Sequence)
: image.ReadSectors(doneSectors, SECTORS_TO_READ, currentTrack.Sequence);
if(@long)
{
sector = image.ReadSectorsLong(doneSectors, SECTORS_TO_READ,
currentTrack.Sequence);
errno = ErrorNumber.NoError;
}
else
errno = image.ReadSectors(doneSectors, SECTORS_TO_READ, currentTrack.Sequence,
out sector);
doneSectors += SECTORS_TO_READ;
}
else
{
sector =
@long ? image.ReadSectorsLong(doneSectors, (uint)(sectors - doneSectors),
currentTrack.Sequence)
: image.ReadSectors(doneSectors, (uint)(sectors - doneSectors),
currentTrack.Sequence);
if(@long)
{
sector = image.ReadSectorsLong(doneSectors, (uint)(sectors - doneSectors),
currentTrack.Sequence);
errno = ErrorNumber.NoError;
}
else
errno = image.ReadSectors(doneSectors, (uint)(sectors - doneSectors),
currentTrack.Sequence, out sector);
doneSectors += sectors - doneSectors;
}
Assert.AreEqual(ErrorNumber.NoError, errno);
ctx.Update(sector);
}
}

View File

@@ -369,26 +369,43 @@ namespace Aaru.Commands.Image
if(sectors - doneSectors >= SECTORS_TO_READ)
{
sector = opticalInput.ReadSectors(doneSectors, SECTORS_TO_READ,
currentTrack.Sequence);
errno = opticalInput.ReadSectors(doneSectors, SECTORS_TO_READ,
currentTrack.Sequence, out sector);
trackTask.Description =
string.Format("Hashing sectors {0} to {2} of track {1}",
doneSectors, currentTrack.Sequence,
doneSectors + SECTORS_TO_READ);
if(errno != ErrorNumber.NoError)
{
AaruConsole.
ErrorWriteLine($"Error {errno} while reading {SECTORS_TO_READ} sectors from sector {doneSectors}, not continuing...");
return;
}
doneSectors += SECTORS_TO_READ;
}
else
{
sector = opticalInput.ReadSectors(doneSectors,
(uint)(sectors - doneSectors), currentTrack.Sequence);
errno = opticalInput.ReadSectors(doneSectors,
(uint)(sectors - doneSectors), currentTrack.Sequence,
out sector);
trackTask.Description =
string.Format("Hashing sectors {0} to {2} of track {1}",
doneSectors, currentTrack.Sequence,
doneSectors + (sectors - doneSectors));
if(errno != ErrorNumber.NoError)
{
AaruConsole.
ErrorWriteLine($"Error {errno} while reading {sectors - doneSectors} sectors from sector {doneSectors}, not continuing...");
return;
}
doneSectors += sectors - doneSectors;
}