Replace Mono.Options with System.CommandLine

This commit is contained in:
2020-01-02 04:09:39 +00:00
parent 4a74de5843
commit 758d4dd364
30 changed files with 2389 additions and 2147 deletions

View File

@@ -32,6 +32,8 @@
using System;
using System.Collections.Generic;
using System.CommandLine;
using System.CommandLine.Invocation;
using System.IO;
using System.Linq;
using System.Xml.Serialization;
@@ -42,235 +44,271 @@ using DiscImageChef.CommonTypes.Metadata;
using DiscImageChef.CommonTypes.Structs;
using DiscImageChef.Console;
using DiscImageChef.Core;
using Mono.Options;
using Schemas;
using ImageInfo = DiscImageChef.CommonTypes.Structs.ImageInfo;
using Version = DiscImageChef.CommonTypes.Interop.Version;
namespace DiscImageChef.Commands
{
class ConvertImageCommand : Command
internal class ConvertImageCommand : Command
{
string cicmXml;
string comments;
int count = 64;
string creator;
string driveFirmwareRevision;
string driveManufacturer;
string driveModel;
string driveSerialNumber;
bool force;
string inputFile;
int lastMediaSequence;
string mediaBarcode;
string mediaManufacturer;
string mediaModel;
string mediaPartNumber;
int mediaSequence;
string mediaSerialNumber;
string mediaTitle;
string outputFile;
string outputOptions;
string resumeFile;
bool showHelp;
string wantedOutputFormat;
public ConvertImageCommand() : base("convert-image", "Converts one image to another format.")
{
Options = new OptionSet
Add(new Option(new[]
{
"--cicm-xml", "-x"
}, "Take metadata from existing CICM XML sidecar.")
{
Argument = new Argument<string>(() => null), Required = false
});
Add(new Option("--comments", "Image comments.")
{
$"{MainClass.AssemblyTitle} {MainClass.AssemblyVersion?.InformationalVersion}",
$"{MainClass.AssemblyCopyright}",
"",
$"usage: DiscImageChef {Name} [OPTIONS] inputimage outputimage",
"",
Help,
{"cicm-xml|x=", "Take metadata from existing CICM XML sidecar.", s => cicmXml = s},
{"comments=", "Image comments.", s => comments = s},
{"count|c=", "How many sectors to convert at once.", (int i) => count = i},
{"creator=", "Who (person) created the image?.", s => creator = s},
Argument = new Argument<string>(() => null), Required = false
});
Add(new Option(new[]
{
"drive-manufacturer=",
"Manufacturer of the drive used to read the media represented by the image.",
s => driveManufacturer = s
},
"--count", "-c"
}, "How many sectors to convert at once.")
{
"drive-model=", "Model of the drive used to read the media represented by the image.",
s => driveModel = s
},
Argument = new Argument<int>(() => 64), Required = false
});
Add(new Option("--creator", "Who (person) created the image?.")
{
Argument = new Argument<string>(() => null), Required = false
});
Add(new Option("--drive-manufacturer",
"Manufacturer of the drive used to read the media represented by the image.")
{
Argument = new Argument<string>(() => null), Required = false
});
Add(new Option("--drive-model", "Model of the drive used to read the media represented by the image.")
{
Argument = new Argument<string>(() => null), Required = false
});
Add(new Option("--drive-revision",
"Firmware revision of the drive used to read the media represented by the image.")
{
Argument = new Argument<string>(() => null), Required = false
});
Add(new Option("--drive-serial",
"Serial number of the drive used to read the media represented by the image.")
{
Argument = new Argument<string>(() => null), Required = false
});
Add(new Option(new[]
{
"drive-revision=",
"Firmware revision of the drive used to read the media represented by the image.",
s => driveFirmwareRevision = s
},
"--force", "-f"
}, "Continue conversion even if sector or media tags will be lost in the process.")
{
"drive-serial=", "Serial number of the drive used to read the media represented by the image.",
s => driveSerialNumber = s
},
Argument = new Argument<bool>(() => false), Required = false
});
Add(new Option(new[]
{
"--format", "-p"
},
"Format of the output image, as plugin name or plugin id. If not present, will try to detect it from output image extension.")
{
Argument = new Argument<string>(() => null), Required = false
});
Add(new Option("--media-barcode", "Barcode of the media represented by the image.")
{
Argument = new Argument<string>(() => null), Required = false
});
Add(new Option("--media-lastsequence",
"Last media of the sequence the media represented by the image corresponds to.")
{
Argument = new Argument<int>(() => 0), Required = false
});
Add(new Option("--media-manufacturer", "Manufacturer of the media represented by the image.")
{
Argument = new Argument<string>(() => null), Required = false
});
Add(new Option("--media-model", "Model of the media represented by the image.")
{
Argument = new Argument<string>(() => null), Required = false
});
Add(new Option("--media-partnumber", "Part number of the media represented by the image.")
{
Argument = new Argument<string>(() => null), Required = false
});
Add(new Option("--media-sequence", "Number in sequence for the media represented by the image.")
{
Argument = new Argument<int>(() => 0), Required = false
});
Add(new Option("--media-serial", "Serial number of the media represented by the image.")
{
Argument = new Argument<string>(() => null), Required = false
});
Add(new Option("--media-title", "Title of the media represented by the image.")
{
Argument = new Argument<string>(() => null), Required = false
});
Add(new Option(new[]
{
"force|f", "Continue conversion even if sector or media tags will be lost in the process.",
b => force = b != null
},
"--options", "-O"
}, "Comma separated name=value pairs of options to pass to output image plugin.")
{
"format|p=",
"Format of the output image, as plugin name or plugin id. If not present, will try to detect it from output image extension.",
s => wantedOutputFormat = s
},
{"media-barcode=", "Barcode of the media represented by the image.", s => mediaBarcode = s},
Argument = new Argument<string>(() => null), Required = false
});
Add(new Option(new[]
{
"media-lastsequence=",
"Last media of the sequence the media represented by the image corresponds to.",
(int i) => lastMediaSequence = i
},
"--resume-file", "-r"
}, "Take list of dump hardware from existing resume file.")
{
"media-manufacturer=", "Manufacturer of the media represented by the image.",
s => mediaManufacturer = s
},
{"media-model=", "Model of the media represented by the image.", s => mediaModel = s},
{
"media-partnumber=", "Part number of the media represented by the image.",
s => mediaPartNumber = s
},
{
"media-sequence=", "Number in sequence for the media represented by the image.",
(int i) => mediaSequence = i
},
{
"media-serial=", "Serial number of the media represented by the image.",
s => mediaSerialNumber = s
},
{"media-title=", "Title of the media represented by the image.", s => mediaTitle = s},
{
"options|O=", "Comma separated name=value pairs of options to pass to output image plugin.",
s => outputOptions = s
},
{"resume-file|r=", "Take list of dump hardware from existing resume file.", s => resumeFile = s},
{"help|h|?", "Show this message and exit.", v => showHelp = v != null}
};
Argument = new Argument<string>(() => null), Required = false
});
AddArgument(new Argument<string>
{
Arity = ArgumentArity.ExactlyOne, Description = "Input image path", Name = "input-path"
});
AddArgument(new Argument<string>
{
Arity = ArgumentArity.ExactlyOne, Description = "Output image path", Name = "output-path"
});
Handler = CommandHandler.Create(GetType().GetMethod(nameof(Invoke)));
}
public override int Invoke(IEnumerable<string> arguments)
static int Invoke(bool verbose, bool debug, string cicmXml, string comments, int count, string creator,
string driveFirmwareRevision, string driveManufacturer, string driveModel,
string driveSerialNumber, bool force, string inputPath, int lastMediaSequence,
string mediaBarcode, string mediaManufacturer, string mediaModel, string mediaPartNumber,
int mediaSequence, string mediaSerialNumber, string mediaTitle, string outputPath,
string outputOptions, string resumeFile, string format)
{
List<string> extra = Options.Parse(arguments);
if(showHelp)
{
Options.WriteOptionDescriptions(CommandSet.Out);
return (int)ErrorNumber.HelpRequested;
}
MainClass.PrintCopyright();
if(MainClass.Debug) DicConsole.DebugWriteLineEvent += System.Console.Error.WriteLine;
if(MainClass.Verbose) DicConsole.VerboseWriteLineEvent += System.Console.WriteLine;
if(debug)
DicConsole.DebugWriteLineEvent += System.Console.Error.WriteLine;
if(verbose)
DicConsole.VerboseWriteLineEvent += System.Console.WriteLine;
Statistics.AddCommand("convert-image");
if(extra.Count > 2)
{
DicConsole.ErrorWriteLine("Too many arguments.");
return (int)ErrorNumber.UnexpectedArgumentCount;
}
if(extra.Count <= 1)
{
DicConsole.ErrorWriteLine("Missing input image.");
return (int)ErrorNumber.MissingArgument;
}
inputFile = extra[0];
outputFile = extra[1];
DicConsole.DebugWriteLine("Analyze command", "--cicm-xml={0}", cicmXml);
DicConsole.DebugWriteLine("Analyze command", "--comments={0}", comments);
DicConsole.DebugWriteLine("Analyze command", "--count={0}", count);
DicConsole.DebugWriteLine("Analyze command", "--creator={0}", creator);
DicConsole.DebugWriteLine("Analyze command", "--debug={0}", MainClass.Debug);
DicConsole.DebugWriteLine("Analyze command", "--cicm-xml={0}", cicmXml);
DicConsole.DebugWriteLine("Analyze command", "--comments={0}", comments);
DicConsole.DebugWriteLine("Analyze command", "--count={0}", count);
DicConsole.DebugWriteLine("Analyze command", "--creator={0}", creator);
DicConsole.DebugWriteLine("Analyze command", "--debug={0}", debug);
DicConsole.DebugWriteLine("Analyze command", "--drive-manufacturer={0}", driveManufacturer);
DicConsole.DebugWriteLine("Analyze command", "--drive-model={0}", driveModel);
DicConsole.DebugWriteLine("Analyze command", "--drive-revision={0}", driveFirmwareRevision);
DicConsole.DebugWriteLine("Analyze command", "--drive-serial={0}", driveSerialNumber);
DicConsole.DebugWriteLine("Analyze command", "--force={0}", force);
DicConsole.DebugWriteLine("Analyze command", "--format={0}", wantedOutputFormat);
DicConsole.DebugWriteLine("Analyze command", "--input={0}", inputFile);
DicConsole.DebugWriteLine("Analyze command", "--media-barcode={0}", mediaBarcode);
DicConsole.DebugWriteLine("Analyze command", "--drive-model={0}", driveModel);
DicConsole.DebugWriteLine("Analyze command", "--drive-revision={0}", driveFirmwareRevision);
DicConsole.DebugWriteLine("Analyze command", "--drive-serial={0}", driveSerialNumber);
DicConsole.DebugWriteLine("Analyze command", "--force={0}", force);
DicConsole.DebugWriteLine("Analyze command", "--format={0}", format);
DicConsole.DebugWriteLine("Analyze command", "--input={0}", inputPath);
DicConsole.DebugWriteLine("Analyze command", "--media-barcode={0}", mediaBarcode);
DicConsole.DebugWriteLine("Analyze command", "--media-lastsequence={0}", lastMediaSequence);
DicConsole.DebugWriteLine("Analyze command", "--media-manufacturer={0}", mediaManufacturer);
DicConsole.DebugWriteLine("Analyze command", "--media-model={0}", mediaModel);
DicConsole.DebugWriteLine("Analyze command", "--media-partnumber={0}", mediaPartNumber);
DicConsole.DebugWriteLine("Analyze command", "--media-sequence={0}", mediaSequence);
DicConsole.DebugWriteLine("Analyze command", "--media-serial={0}", mediaSerialNumber);
DicConsole.DebugWriteLine("Analyze command", "--media-title={0}", mediaTitle);
DicConsole.DebugWriteLine("Analyze command", "--options={0}", outputOptions);
DicConsole.DebugWriteLine("Analyze command", "--output={0}", outputFile);
DicConsole.DebugWriteLine("Analyze command", "--resume-file={0}", resumeFile);
DicConsole.DebugWriteLine("Analyze command", "--verbose={0}", MainClass.Verbose);
DicConsole.DebugWriteLine("Analyze command", "--media-model={0}", mediaModel);
DicConsole.DebugWriteLine("Analyze command", "--media-partnumber={0}", mediaPartNumber);
DicConsole.DebugWriteLine("Analyze command", "--media-sequence={0}", mediaSequence);
DicConsole.DebugWriteLine("Analyze command", "--media-serial={0}", mediaSerialNumber);
DicConsole.DebugWriteLine("Analyze command", "--media-title={0}", mediaTitle);
DicConsole.DebugWriteLine("Analyze command", "--options={0}", outputOptions);
DicConsole.DebugWriteLine("Analyze command", "--output={0}", outputPath);
DicConsole.DebugWriteLine("Analyze command", "--resume-file={0}", resumeFile);
DicConsole.DebugWriteLine("Analyze command", "--verbose={0}", verbose);
Dictionary<string, string> parsedOptions = Core.Options.Parse(outputOptions);
DicConsole.DebugWriteLine("Analyze command", "Parsed options:");
foreach(KeyValuePair<string, string> parsedOption in parsedOptions)
DicConsole.DebugWriteLine("Analyze command", "{0} = {1}", parsedOption.Key, parsedOption.Value);
if(count == 0)
{
DicConsole.ErrorWriteLine("Need to specify more than 0 sectors to copy at once");
return (int)ErrorNumber.InvalidArgument;
return(int)ErrorNumber.InvalidArgument;
}
Resume resume = null;
CICMMetadataType sidecar = null;
XmlSerializer xs = new XmlSerializer(typeof(CICMMetadataType));
var xs = new XmlSerializer(typeof(CICMMetadataType));
if(cicmXml != null)
if(File.Exists(cicmXml))
try
{
StreamReader sr = new StreamReader(cicmXml);
var sr = new StreamReader(cicmXml);
sidecar = (CICMMetadataType)xs.Deserialize(sr);
sr.Close();
}
catch
{
DicConsole.ErrorWriteLine("Incorrect metadata sidecar file, not continuing...");
return (int)ErrorNumber.InvalidSidecar;
return(int)ErrorNumber.InvalidSidecar;
}
else
{
DicConsole.ErrorWriteLine("Could not find metadata sidecar, not continuing...");
return (int)ErrorNumber.FileNotFound;
return(int)ErrorNumber.FileNotFound;
}
xs = new XmlSerializer(typeof(Resume));
if(resumeFile != null)
if(File.Exists(resumeFile))
try
{
StreamReader sr = new StreamReader(resumeFile);
var sr = new StreamReader(resumeFile);
resume = (Resume)xs.Deserialize(sr);
sr.Close();
}
catch
{
DicConsole.ErrorWriteLine("Incorrect resume file, not continuing...");
return (int)ErrorNumber.InvalidResume;
return(int)ErrorNumber.InvalidResume;
}
else
{
DicConsole.ErrorWriteLine("Could not find resume file, not continuing...");
return (int)ErrorNumber.FileNotFound;
return(int)ErrorNumber.FileNotFound;
}
FiltersList filtersList = new FiltersList();
IFilter inputFilter = filtersList.GetFilter(inputFile);
var filtersList = new FiltersList();
IFilter inputFilter = filtersList.GetFilter(inputPath);
if(inputFilter == null)
{
DicConsole.ErrorWriteLine("Cannot open specified file.");
return (int)ErrorNumber.CannotOpenFile;
return(int)ErrorNumber.CannotOpenFile;
}
if(File.Exists(outputFile))
if(File.Exists(outputPath))
{
DicConsole.ErrorWriteLine("Output file already exists, not continuing.");
return (int)ErrorNumber.DestinationExists;
return(int)ErrorNumber.DestinationExists;
}
PluginBase plugins = GetPluginBase.Instance;
@@ -279,13 +317,15 @@ namespace DiscImageChef.Commands
if(inputFormat == null)
{
DicConsole.WriteLine("Input image format not identified, not proceeding with conversion.");
return (int)ErrorNumber.UnrecognizedFormat;
return(int)ErrorNumber.UnrecognizedFormat;
}
if(MainClass.Verbose)
if(verbose)
DicConsole.VerboseWriteLine("Input image format identified by {0} ({1}).", inputFormat.Name,
inputFormat.Id);
else DicConsole.WriteLine("Input image format identified by {0}.", inputFormat.Name);
else
DicConsole.WriteLine("Input image format identified by {0}.", inputFormat.Name);
try
{
@@ -293,13 +333,17 @@ namespace DiscImageChef.Commands
{
DicConsole.WriteLine("Unable to open image format");
DicConsole.WriteLine("No error given");
return (int)ErrorNumber.CannotOpenFormat;
return(int)ErrorNumber.CannotOpenFormat;
}
DicConsole.DebugWriteLine("Convert-image command", "Correctly opened image file.");
DicConsole.DebugWriteLine("Convert-image command", "Image without headers is {0} bytes.",
inputFormat.Info.ImageSize);
DicConsole.DebugWriteLine("Convert-image command", "Image has {0} sectors.", inputFormat.Info.Sectors);
DicConsole.DebugWriteLine("Convert-image command", "Image identifies media type as {0}.",
inputFormat.Info.MediaType);
@@ -312,85 +356,101 @@ namespace DiscImageChef.Commands
DicConsole.ErrorWriteLine("Unable to open image format");
DicConsole.ErrorWriteLine("Error: {0}", ex.Message);
DicConsole.DebugWriteLine("Convert-image command", "Stack trace: {0}", ex.StackTrace);
return (int)ErrorNumber.CannotOpenFormat;
return(int)ErrorNumber.CannotOpenFormat;
}
List<IWritableImage> candidates = new List<IWritableImage>();
// Try extension
if(string.IsNullOrEmpty(wantedOutputFormat))
if(string.IsNullOrEmpty(format))
candidates.AddRange(plugins.WritableImages.Values.Where(t =>
t.KnownExtensions
.Contains(Path.GetExtension(outputFile))));
t.KnownExtensions.
Contains(Path.GetExtension(outputPath))));
// Try Id
else if(Guid.TryParse(wantedOutputFormat, out Guid outId))
else if(Guid.TryParse(format, out Guid outId))
candidates.AddRange(plugins.WritableImages.Values.Where(t => t.Id.Equals(outId)));
// Try name
else
candidates.AddRange(plugins.WritableImages.Values.Where(t => string.Equals(t.Name, wantedOutputFormat,
StringComparison
.InvariantCultureIgnoreCase)));
candidates.AddRange(plugins.WritableImages.Values.Where(t => string.Equals(t.Name, format,
StringComparison.
InvariantCultureIgnoreCase)));
if(candidates.Count == 0)
{
DicConsole.WriteLine("No plugin supports requested extension.");
return (int)ErrorNumber.FormatNotFound;
return(int)ErrorNumber.FormatNotFound;
}
if(candidates.Count > 1)
{
DicConsole.WriteLine("More than one plugin supports requested extension.");
return (int)ErrorNumber.TooManyFormats;
return(int)ErrorNumber.TooManyFormats;
}
IWritableImage outputFormat = candidates[0];
if(MainClass.Verbose)
if(verbose)
DicConsole.VerboseWriteLine("Output image format: {0} ({1}).", outputFormat.Name, outputFormat.Id);
else DicConsole.WriteLine("Output image format: {0}.", outputFormat.Name);
else
DicConsole.WriteLine("Output image format: {0}.", outputFormat.Name);
if(!outputFormat.SupportedMediaTypes.Contains(inputFormat.Info.MediaType))
{
DicConsole.ErrorWriteLine("Output format does not support media type, cannot continue...");
return (int)ErrorNumber.UnsupportedMedia;
return(int)ErrorNumber.UnsupportedMedia;
}
foreach(MediaTagType mediaTag in inputFormat.Info.ReadableMediaTags)
{
if(outputFormat.SupportedMediaTags.Contains(mediaTag) || force) continue;
if(outputFormat.SupportedMediaTags.Contains(mediaTag) || force)
continue;
DicConsole.ErrorWriteLine("Converting image will lose media tag {0}, not continuing...", mediaTag);
DicConsole.ErrorWriteLine("If you don't care, use force option.");
return (int)ErrorNumber.DataWillBeLost;
return(int)ErrorNumber.DataWillBeLost;
}
bool useLong = inputFormat.Info.ReadableSectorTags.Count != 0;
foreach(SectorTagType sectorTag in inputFormat.Info.ReadableSectorTags)
{
if(outputFormat.SupportedSectorTags.Contains(sectorTag)) continue;
if(outputFormat.SupportedSectorTags.Contains(sectorTag))
continue;
if(force)
{
if(sectorTag != SectorTagType.CdTrackFlags && sectorTag != SectorTagType.CdTrackIsrc &&
sectorTag != SectorTagType.CdSectorSubchannel) useLong = false;
if(sectorTag != SectorTagType.CdTrackFlags &&
sectorTag != SectorTagType.CdTrackIsrc &&
sectorTag != SectorTagType.CdSectorSubchannel)
useLong = false;
continue;
}
DicConsole.ErrorWriteLine("Converting image will lose sector tag {0}, not continuing...", sectorTag);
DicConsole
.ErrorWriteLine("If you don't care, use force option. This will skip all sector tags converting only user data.");
return (int)ErrorNumber.DataWillBeLost;
DicConsole.
ErrorWriteLine("If you don't care, use force option. This will skip all sector tags converting only user data.");
return(int)ErrorNumber.DataWillBeLost;
}
if(!outputFormat.Create(outputFile, inputFormat.Info.MediaType, parsedOptions, inputFormat.Info.Sectors,
if(!outputFormat.Create(outputPath, inputFormat.Info.MediaType, parsedOptions, inputFormat.Info.Sectors,
inputFormat.Info.SectorSize))
{
DicConsole.ErrorWriteLine("Error {0} creating output image.", outputFormat.ErrorMessage);
return (int)ErrorNumber.CannotCreateFormat;
return(int)ErrorNumber.CannotCreateFormat;
}
ImageInfo metadata = new ImageInfo
var metadata = new ImageInfo
{
Application = "DiscImageChef",
ApplicationVersion = Version.GetVersion(),
@@ -413,10 +473,12 @@ namespace DiscImageChef.Commands
if(!outputFormat.SetMetadata(metadata))
{
DicConsole.ErrorWrite("Error {0} setting metadata, ", outputFormat.ErrorMessage);
if(!force)
{
DicConsole.ErrorWriteLine("not continuing...");
return (int)ErrorNumber.WriteError;
return(int)ErrorNumber.WriteError;
}
DicConsole.ErrorWriteLine("continuing...");
@@ -427,11 +489,14 @@ namespace DiscImageChef.Commands
foreach(MediaTagType mediaTag in inputFormat.Info.ReadableMediaTags)
{
if(force && !outputFormat.SupportedMediaTags.Contains(mediaTag)) continue;
if(force && !outputFormat.SupportedMediaTags.Contains(mediaTag))
continue;
DicConsole.WriteLine("Converting media tag {0}", mediaTag);
byte[] tag = inputFormat.ReadDiskTag(mediaTag);
if(outputFormat.WriteMediaTag(tag, mediaTag)) continue;
if(outputFormat.WriteMediaTag(tag, mediaTag))
continue;
if(force)
DicConsole.ErrorWriteLine("Error {0} writing media tag, continuing...", outputFormat.ErrorMessage);
@@ -439,35 +504,41 @@ namespace DiscImageChef.Commands
{
DicConsole.ErrorWriteLine("Error {0} writing media tag, not continuing...",
outputFormat.ErrorMessage);
return (int)ErrorNumber.WriteError;
return(int)ErrorNumber.WriteError;
}
}
DicConsole.WriteLine("{0} sectors to convert", inputFormat.Info.Sectors);
ulong doneSectors = 0;
if(inputFormat is IOpticalMediaImage inputOptical && outputFormat is IWritableOpticalImage outputOptical &&
if(inputFormat is IOpticalMediaImage inputOptical &&
outputFormat is IWritableOpticalImage outputOptical &&
inputOptical.Tracks != null)
{
if(!outputOptical.SetTracks(inputOptical.Tracks))
{
DicConsole.ErrorWriteLine("Error {0} sending tracks list to output image.",
outputFormat.ErrorMessage);
return (int)ErrorNumber.WriteError;
return(int)ErrorNumber.WriteError;
}
foreach(Track track in inputOptical.Tracks)
{
doneSectors = 0;
ulong trackSectors = track.TrackEndSector - track.TrackStartSector + 1;
ulong trackSectors = (track.TrackEndSector - track.TrackStartSector) + 1;
while(doneSectors < trackSectors)
{
byte[] sector;
uint sectorsToDo;
if(trackSectors - doneSectors >= (ulong)count) sectorsToDo = (uint)count;
else sectorsToDo = (uint)(trackSectors - doneSectors);
if(trackSectors - doneSectors >= (ulong)count)
sectorsToDo = (uint)count;
else
sectorsToDo = (uint)(trackSectors - doneSectors);
DicConsole.Write("\rConverting sectors {0} to {1} in track {3} ({2:P2} done)",
doneSectors + track.TrackStartSector,
@@ -476,6 +547,7 @@ namespace DiscImageChef.Commands
track.TrackSequence);
bool result;
if(useLong)
if(sectorsToDo == 1)
{
@@ -485,6 +557,7 @@ namespace DiscImageChef.Commands
else
{
sector = inputFormat.ReadSectorsLong(doneSectors + track.TrackStartSector, sectorsToDo);
result = outputFormat.WriteSectorsLong(sector, doneSectors + track.TrackStartSector,
sectorsToDo);
}
@@ -498,6 +571,7 @@ namespace DiscImageChef.Commands
else
{
sector = inputFormat.ReadSectors(doneSectors + track.TrackStartSector, sectorsToDo);
result = outputFormat.WriteSectors(sector, doneSectors + track.TrackStartSector,
sectorsToDo);
}
@@ -511,7 +585,8 @@ namespace DiscImageChef.Commands
{
DicConsole.ErrorWriteLine("Error {0} writing sector {1}, not continuing...",
outputFormat.ErrorMessage, doneSectors);
return (int)ErrorNumber.WriteError;
return(int)ErrorNumber.WriteError;
}
doneSectors += sectorsToDo;
@@ -520,11 +595,13 @@ namespace DiscImageChef.Commands
DicConsole.Write("\rConverting sectors {0} to {1} in track {3} ({2:P2} done)", inputFormat.Info.Sectors,
inputFormat.Info.Sectors, 1.0, inputOptical.Tracks.Count);
DicConsole.WriteLine();
foreach(SectorTagType tag in inputFormat.Info.ReadableSectorTags.OrderBy(t => t))
{
if(!useLong) break;
if(!useLong)
break;
switch(tag)
{
@@ -540,12 +617,13 @@ namespace DiscImageChef.Commands
continue;
}
if(force && !outputFormat.SupportedSectorTags.Contains(tag)) continue;
if(force && !outputFormat.SupportedSectorTags.Contains(tag))
continue;
foreach(Track track in inputOptical.Tracks)
{
doneSectors = 0;
ulong trackSectors = track.TrackEndSector - track.TrackStartSector + 1;
ulong trackSectors = (track.TrackEndSector - track.TrackStartSector) + 1;
byte[] sector;
bool result;
@@ -556,8 +634,10 @@ namespace DiscImageChef.Commands
DicConsole.Write("\rConverting tag {0} in track {1} ({2:P2} done).", tag,
track.TrackSequence,
track.TrackSequence / (double)inputOptical.Tracks.Count);
sector = inputFormat.ReadSectorTag(track.TrackStartSector, tag);
result = outputFormat.WriteSectorTag(sector, track.TrackStartSector, tag);
if(!result)
if(force)
DicConsole.ErrorWriteLine("Error {0} writing tag, continuing...",
@@ -566,7 +646,8 @@ namespace DiscImageChef.Commands
{
DicConsole.ErrorWriteLine("Error {0} writing tag, not continuing...",
outputFormat.ErrorMessage);
return (int)ErrorNumber.WriteError;
return(int)ErrorNumber.WriteError;
}
continue;
@@ -575,10 +656,11 @@ namespace DiscImageChef.Commands
while(doneSectors < trackSectors)
{
uint sectorsToDo;
if(trackSectors - doneSectors >= (ulong)count) sectorsToDo = (uint)count;
if(trackSectors - doneSectors >= (ulong)count)
sectorsToDo = (uint)count;
else
sectorsToDo =
(uint)(trackSectors - doneSectors);
sectorsToDo = (uint)(trackSectors - doneSectors);
DicConsole.Write("\rConverting tag {4} for sectors {0} to {1} in track {3} ({2:P2} done)",
doneSectors + track.TrackStartSector,
@@ -595,6 +677,7 @@ namespace DiscImageChef.Commands
{
sector = inputFormat.ReadSectorsTag(doneSectors + track.TrackStartSector, sectorsToDo,
tag);
result = outputFormat.WriteSectorsTag(sector, doneSectors + track.TrackStartSector,
sectorsToDo, tag);
}
@@ -607,7 +690,8 @@ namespace DiscImageChef.Commands
{
DicConsole.ErrorWriteLine("Error {0} writing tag for sector {1}, not continuing...",
outputFormat.ErrorMessage, doneSectors);
return (int)ErrorNumber.WriteError;
return(int)ErrorNumber.WriteError;
}
doneSectors += sectorsToDo;
@@ -620,11 +704,13 @@ namespace DiscImageChef.Commands
case SectorTagType.CdTrackIsrc:
DicConsole.Write("\rConverting tag {0} in track {1} ({2:P2} done).", tag,
inputOptical.Tracks.Count, 1.0);
break;
default:
DicConsole.Write("\rConverting tag {4} for sectors {0} to {1} in track {3} ({2:P2} done)",
inputFormat.Info.Sectors, inputFormat.Info.Sectors, 1.0,
inputOptical.Tracks.Count, tag);
break;
}
@@ -636,6 +722,7 @@ namespace DiscImageChef.Commands
DicConsole.WriteLine("Setting geometry to {0} cylinders, {1} heads and {2} sectors per track",
inputFormat.Info.Cylinders, inputFormat.Info.Heads,
inputFormat.Info.SectorsPerTrack);
if(!outputFormat.SetGeometry(inputFormat.Info.Cylinders, inputFormat.Info.Heads,
inputFormat.Info.SectorsPerTrack))
DicConsole.ErrorWriteLine("Error {0} setting geometry, image may be incorrect, continuing...",
@@ -646,15 +733,17 @@ namespace DiscImageChef.Commands
byte[] sector;
uint sectorsToDo;
if(inputFormat.Info.Sectors - doneSectors >= (ulong)count) sectorsToDo = (uint)count;
if(inputFormat.Info.Sectors - doneSectors >= (ulong)count)
sectorsToDo = (uint)count;
else
sectorsToDo =
(uint)(inputFormat.Info.Sectors - doneSectors);
sectorsToDo = (uint)(inputFormat.Info.Sectors - doneSectors);
DicConsole.Write("\rConverting sectors {0} to {1} ({2:P2} done)", doneSectors,
doneSectors + sectorsToDo, doneSectors / (double)inputFormat.Info.Sectors);
bool result;
if(useLong)
if(sectorsToDo == 1)
{
@@ -688,7 +777,8 @@ namespace DiscImageChef.Commands
{
DicConsole.ErrorWriteLine("Error {0} writing sector {1}, not continuing...",
outputFormat.ErrorMessage, doneSectors);
return (int)ErrorNumber.WriteError;
return(int)ErrorNumber.WriteError;
}
doneSectors += sectorsToDo;
@@ -696,11 +786,13 @@ namespace DiscImageChef.Commands
DicConsole.Write("\rConverting sectors {0} to {1} ({2:P2} done)", inputFormat.Info.Sectors,
inputFormat.Info.Sectors, 1.0);
DicConsole.WriteLine();
foreach(SectorTagType tag in inputFormat.Info.ReadableSectorTags)
{
if(!useLong) break;
if(!useLong)
break;
switch(tag)
{
@@ -716,24 +808,28 @@ namespace DiscImageChef.Commands
continue;
}
if(force && !outputFormat.SupportedSectorTags.Contains(tag)) continue;
if(force && !outputFormat.SupportedSectorTags.Contains(tag))
continue;
doneSectors = 0;
while(doneSectors < inputFormat.Info.Sectors)
{
byte[] sector;
uint sectorsToDo;
if(inputFormat.Info.Sectors - doneSectors >= (ulong)count) sectorsToDo = (uint)count;
if(inputFormat.Info.Sectors - doneSectors >= (ulong)count)
sectorsToDo = (uint)count;
else
sectorsToDo =
(uint)(inputFormat.Info.Sectors - doneSectors);
sectorsToDo = (uint)(inputFormat.Info.Sectors - doneSectors);
DicConsole.Write("\rConverting tag {2} for sectors {0} to {1} ({2:P2} done)", doneSectors,
doneSectors + sectorsToDo, doneSectors / (double)inputFormat.Info.Sectors,
tag);
bool result;
if(sectorsToDo == 1)
{
sector = inputFormat.ReadSectorTag(doneSectors, tag);
@@ -753,7 +849,8 @@ namespace DiscImageChef.Commands
{
DicConsole.ErrorWriteLine("Error {0} writing sector {1}, not continuing...",
outputFormat.ErrorMessage, doneSectors);
return (int)ErrorNumber.WriteError;
return(int)ErrorNumber.WriteError;
}
doneSectors += sectorsToDo;
@@ -761,24 +858,37 @@ namespace DiscImageChef.Commands
DicConsole.Write("\rConverting tag {2} for sectors {0} to {1} ({2:P2} done)",
inputFormat.Info.Sectors, inputFormat.Info.Sectors, 1.0, tag);
DicConsole.WriteLine();
}
}
bool ret = false;
if(resume != null || dumpHardware != null)
if(resume != null ||
dumpHardware != null)
{
if(resume != null) ret = outputFormat.SetDumpHardware(resume.Tries);
else if(dumpHardware != null) ret = outputFormat.SetDumpHardware(dumpHardware);
if(ret) DicConsole.WriteLine("Written dump hardware list to output image.");
if(resume != null)
ret = outputFormat.SetDumpHardware(resume.Tries);
else if(dumpHardware != null)
ret = outputFormat.SetDumpHardware(dumpHardware);
if(ret)
DicConsole.WriteLine("Written dump hardware list to output image.");
}
ret = false;
if(sidecar != null || cicmMetadata != null)
if(sidecar != null ||
cicmMetadata != null)
{
if(sidecar != null) ret = outputFormat.SetCicmMetadata(sidecar);
else if(cicmMetadata != null) ret = outputFormat.SetCicmMetadata(cicmMetadata);
if(ret) DicConsole.WriteLine("Written CICM XML metadata to output image.");
if(sidecar != null)
ret = outputFormat.SetCicmMetadata(sidecar);
else if(cicmMetadata != null)
ret = outputFormat.SetCicmMetadata(cicmMetadata);
if(ret)
DicConsole.WriteLine("Written CICM XML metadata to output image.");
}
DicConsole.WriteLine("Closing output image.");
@@ -790,7 +900,7 @@ namespace DiscImageChef.Commands
DicConsole.WriteLine();
DicConsole.WriteLine("Conversion done.");
return (int)ErrorNumber.NoError;
return(int)ErrorNumber.NoError;
}
}
}