Files
Aaru/Aaru.Core/Image/Convert/Sectors.cs

233 lines
9.1 KiB
C#

using System.Linq;
using Aaru.CommonTypes.Enums;
using Aaru.Localization;
using Aaru.Logging;
namespace Aaru.Core.Image;
public partial class Convert
{
ErrorNumber ConvertSectors(bool useLong, bool isTape)
{
if(_aborted) return ErrorNumber.NoError;
InitProgress?.Invoke();
ErrorNumber errno = ErrorNumber.NoError;
ulong doneSectors = 0;
while(doneSectors < _inputImage.Info.Sectors)
{
byte[] sector;
uint sectorsToDo;
if(isTape)
sectorsToDo = 1;
else if(_inputImage.Info.Sectors - doneSectors >= _count)
sectorsToDo = _count;
else
sectorsToDo = (uint)(_inputImage.Info.Sectors - doneSectors);
UpdateProgress?.Invoke(string.Format(UI.Converting_sectors_0_to_1, doneSectors, doneSectors + sectorsToDo),
(long)doneSectors,
(long)_inputImage.Info.Sectors);
bool result;
SectorStatus sectorStatus = SectorStatus.NotDumped;
var sectorStatusArray = new SectorStatus[1];
if(useLong)
{
errno = sectorsToDo == 1
? _inputImage.ReadSectorLong(doneSectors, false, out sector, out sectorStatus)
: _inputImage.ReadSectorsLong(doneSectors,
false,
sectorsToDo,
out sector,
out sectorStatusArray);
if(errno == ErrorNumber.NoError)
{
result = sectorsToDo == 1
? _outputImage.WriteSectorLong(sector, doneSectors, false, sectorStatus)
: _outputImage.WriteSectorsLong(sector,
doneSectors,
false,
sectorsToDo,
sectorStatusArray);
}
else
{
result = true;
if(_force)
ErrorMessage?.Invoke(string.Format(UI.Error_0_reading_sector_1_continuing, errno, doneSectors));
else
{
StoppingErrorMessage?.Invoke(string.Format(UI.Error_0_reading_sector_1_not_continuing,
errno,
doneSectors));
return errno;
}
}
}
else
{
errno = sectorsToDo == 1
? _inputImage.ReadSector(doneSectors, false, out sector, out sectorStatus)
: _inputImage.ReadSectors(doneSectors,
false,
sectorsToDo,
out sector,
out sectorStatusArray);
if(errno == ErrorNumber.NoError)
{
result = sectorsToDo == 1
? _outputImage.WriteSector(sector, doneSectors, false, sectorStatus)
: _outputImage.WriteSectors(sector,
doneSectors,
false,
sectorsToDo,
sectorStatusArray);
}
else
{
result = true;
if(_force)
ErrorMessage?.Invoke(string.Format(UI.Error_0_reading_sector_1_continuing, errno, doneSectors));
else
{
StoppingErrorMessage?.Invoke(string.Format(UI.Error_0_reading_sector_1_not_continuing,
errno,
doneSectors));
return errno;
}
}
}
if(!result)
{
if(_force)
{
ErrorMessage?.Invoke(string.Format(UI.Error_0_writing_sector_1_continuing,
_outputImage.ErrorMessage,
doneSectors));
}
else
{
StoppingErrorMessage?.Invoke(string.Format(UI.Error_0_writing_sector_1_not_continuing,
_outputImage.ErrorMessage,
doneSectors));
return ErrorNumber.WriteError;
}
}
doneSectors += sectorsToDo;
}
return ErrorNumber.NoError;
}
ErrorNumber ConvertSectorsTags(bool useLong)
{
if(_aborted) return ErrorNumber.NoError;
foreach(SectorTagType tag in _inputImage.Info.ReadableSectorTags.TakeWhile(_ => useLong))
{
switch(tag)
{
case SectorTagType.AppleSonyTag:
case SectorTagType.AppleProfileTag:
case SectorTagType.PriamDataTowerTag:
case SectorTagType.CdSectorSync:
case SectorTagType.CdSectorHeader:
case SectorTagType.CdSectorSubHeader:
case SectorTagType.CdSectorEdc:
case SectorTagType.CdSectorEccP:
case SectorTagType.CdSectorEccQ:
case SectorTagType.CdSectorEcc:
// These tags are inline in long sector
continue;
}
if(_force && !_outputImage.SupportedSectorTags.Contains(tag)) continue;
ulong doneSectors = 0;
ErrorNumber errno;
InitProgress?.Invoke();
while(doneSectors < _inputImage.Info.Sectors)
{
uint sectorsToDo;
if(_inputImage.Info.Sectors - doneSectors >= _count)
sectorsToDo = _count;
else
sectorsToDo = (uint)(_inputImage.Info.Sectors - doneSectors);
UpdateProgress?.Invoke(string.Format(UI.Converting_tag_2_for_sectors_0_to_1,
doneSectors,
doneSectors + sectorsToDo,
tag),
(long)doneSectors,
(long)_inputImage.Info.Sectors);
bool result;
errno = sectorsToDo == 1
? _inputImage.ReadSectorTag(doneSectors, false, tag, out byte[] sector)
: _inputImage.ReadSectorsTag(doneSectors, false, sectorsToDo, tag, out sector);
if(errno == ErrorNumber.NoError)
{
result = sectorsToDo == 1
? _outputImage.WriteSectorTag(sector, doneSectors, false, tag)
: _outputImage.WriteSectorsTag(sector, doneSectors, false, sectorsToDo, tag);
}
else
{
result = true;
if(_force)
AaruLogging.Error(UI.Error_0_reading_sector_1_continuing, errno, doneSectors);
else
{
AaruLogging.Error(UI.Error_0_reading_sector_1_not_continuing, errno, doneSectors);
return errno;
}
}
if(!result)
{
if(_force)
{
AaruLogging.Error(UI.Error_0_writing_sector_1_continuing,
_outputImage.ErrorMessage,
doneSectors);
}
else
{
AaruLogging.Error(UI.Error_0_writing_sector_1_not_continuing,
_outputImage.ErrorMessage,
doneSectors);
return ErrorNumber.WriteError;
}
}
doneSectors += sectorsToDo;
}
EndProgress?.Invoke();
}
return ErrorNumber.NoError;
}
}