using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using DICUI.Utilities;
namespace DICUI.Data
{
public abstract class BaseParameters
{
///
/// Path to the executable
///
public string ExecutablePath { get; set; }
///
/// Program that this set of parameters represents
///
public InternalProgram InternalProgram { get; set; }
///
/// Process to track external program
///
private Process process;
///
/// Populate a Parameters object from a param string
///
/// String possibly representing a set of parameters
public BaseParameters(string parameters)
{
// If any parameters are not valid, wipe out everything
if (!ValidateAndSetParameters(parameters))
{
ResetValues();
}
}
///
/// Generate parameters based on a set of known inputs
///
/// KnownSystem value to use
/// MediaType value to use
/// Drive letter to use
/// Filename to use
/// Drive speed to use
/// Enable paranoid mode (safer dumping)
/// Enable quiet mode (no beeps)
/// User-defined reread count
public BaseParameters(KnownSystem? system, MediaType? type, char driveLetter, string filename, int? driveSpeed, bool paranoid, bool quietMode, int retryCount)
{
SetDefaultParameters(system, type, driveLetter, filename, driveSpeed, paranoid, retryCount);
}
///
/// Blindly generate a parameter string based on the inputs
///
/// Correctly formatted parameter string, null on error
public abstract string GenerateParameters();
///
/// Get the input path from the implementation
///
/// String representing the path, null on error
public abstract string InputPath();
///
/// Get the output path from the implementation
///
/// String representing the path, null on error
public abstract string OutputPath();
///
/// Get the processing speed from the implementation
///
/// int? representing the speed, null on error
public abstract int? GetSpeed();
///
/// Set the processing speed int the implementation
///
/// int? representing the speed
public abstract void SetSpeed(int? speed);
///
/// Get the MediaType from the current set of parameters
///
/// MediaType value if successful, null on error
public abstract MediaType? GetMediaType();
///
/// Gets if the current command is considered a dumping command or not
///
/// True if it's a dumping command, false otherwise
public abstract bool IsDumpingCommand();
///
/// Returns if the current Parameter object is valid
///
///
public bool IsValid()
{
return GenerateParameters() != null;
}
///
/// Reset all special variables to have default values
///
protected abstract void ResetValues();
///
/// Set default parameters for a given system and media type
///
/// KnownSystem value to use
/// MediaType value to use
/// Drive letter to use
/// Filename to use
/// Drive speed to use
/// Enable paranoid mode (safer dumping)
/// User-defined reread count
protected abstract void SetDefaultParameters(
KnownSystem? system,
MediaType? type,
char driveLetter,
string filename,
int? driveSpeed,
bool paranoid,
int retryCount);
///
/// Scan a possible parameter string and populate whatever possible
///
/// String possibly representing parameters
///
protected abstract bool ValidateAndSetParameters(string parameters);
///
/// Validate if all required output files exist
///
/// Base filename and path to use for checking
/// KnownSystem type representing the media
/// MediaType type representing the media
///
public abstract bool CheckAllOutputFilesExist(string basePath, KnownSystem? system, MediaType? type);
///
/// Generate a SubmissionInfo for the output files
///
/// Base submission info to fill in specifics for
/// Base filename and path to use for checking
/// KnownSystem type representing the media
/// MediaType type representing the media
/// Drive representing the disc to get information from
public abstract void GenerateSubmissionInfo(SubmissionInfo submissionInfo, string basePath, KnownSystem? system, MediaType? type, Drive drive);
///
/// Run internal program
///
public void ExecuteInternalProgram()
{
process = new Process()
{
StartInfo = new ProcessStartInfo()
{
FileName = ExecutablePath,
Arguments = GenerateParameters() ?? "",
},
};
process.Start();
process.WaitForExit();
}
///
/// Run internal program async with an input set of parameters
///
///
/// Standard output from commandline window
public async Task ExecuteInternalProgram(BaseParameters parameters)
{
Process childProcess;
string output = await Task.Run(() =>
{
childProcess = new Process()
{
StartInfo = new ProcessStartInfo()
{
FileName = parameters.ExecutablePath,
Arguments = parameters.GenerateParameters(),
CreateNoWindow = true,
UseShellExecute = false,
RedirectStandardInput = true,
RedirectStandardOutput = true,
},
};
childProcess.Start();
childProcess.WaitForExit(1000);
// Just in case, we want to push a button 5 times to clear any errors
for (int i = 0; i < 5; i++)
childProcess.StandardInput.WriteLine("Y");
string stdout = childProcess.StandardOutput.ReadToEnd();
childProcess.Dispose();
return stdout;
});
return output;
}
///
/// Cancel an in-progress dumping process
///
public void KillInternalProgram()
{
try
{
if (process != null && !process.HasExited)
process.Kill();
}
catch
{ }
}
///
/// Returns whether or not the selected item exists
///
/// List of parameters to check against
/// Current index
/// True if the next item exists, false otherwise
protected bool DoesExist(List parameters, int index)
{
if (index >= parameters.Count)
return false;
return true;
}
///
/// Get the full lines from the input file, if possible
///
/// file location
/// True if should read as binary, false otherwise (default)
/// Full text of the file, null on error
protected string GetFullFile(string filename, bool binary = false)
{
// If the file doesn't exist, we can't get info from it
if (!File.Exists(filename))
return null;
// If we're reading as binary
if (binary)
{
string hex = string.Empty;
using (BinaryReader br = new BinaryReader(File.OpenRead(filename)))
{
while (br.BaseStream.Position < br.BaseStream.Length)
{
hex += Convert.ToString(br.ReadByte(), 16);
}
}
return hex;
}
return string.Join("\n", File.ReadAllLines(filename));
}
///
/// Returns whether a string is a flag (starts with '/')
///
/// String value to check
/// True if it's a flag, false otherwise
protected bool IsFlag(string parameter)
{
if (parameter.Trim('\"').StartsWith("/"))
return true;
return false;
}
///
/// Returns whether a string is a valid drive letter
///
/// String value to check
/// True if it's a valid drive letter, false otherwise
protected bool IsValidDriveLetter(string parameter)
{
if (!Regex.IsMatch(parameter, @"^[A-Z]:?\\?$"))
return false;
return true;
}
///
/// Returns whether a string is a valid bool
///
/// String value to check
/// True if it's a valid bool, false otherwise
protected bool IsValidBool(string parameter)
{
return bool.TryParse(parameter, out bool temp);
}
///
/// Returns whether a string is a valid byte
///
/// String value to check
/// Lower bound (>=)
/// Upper bound (<=)
/// True if it's a valid byte, false otherwise
protected bool IsValidInt8(string parameter, sbyte lowerBound = -1, sbyte upperBound = -1)
{
if (!sbyte.TryParse(parameter, out sbyte temp))
return false;
else if (lowerBound != -1 && temp < lowerBound)
return false;
else if (upperBound != -1 && temp > upperBound)
return false;
return true;
}
///
/// Returns whether a string is a valid Int16
///
/// String value to check
/// Lower bound (>=)
/// Upper bound (<=)
/// True if it's a valid Int16, false otherwise
protected bool IsValidInt16(string parameter, short lowerBound = -1, short upperBound = -1)
{
if (!short.TryParse(parameter, out short temp))
return false;
else if (lowerBound != -1 && temp < lowerBound)
return false;
else if (upperBound != -1 && temp > upperBound)
return false;
return true;
}
///
/// Returns whether a string is a valid Int32
///
/// String value to check
/// Lower bound (>=)
/// Upper bound (<=)
/// True if it's a valid Int32, false otherwise
protected bool IsValidInt32(string parameter, int lowerBound = -1, int upperBound = -1)
{
if (!int.TryParse(parameter, out int temp))
return false;
else if (lowerBound != -1 && temp < lowerBound)
return false;
else if (upperBound != -1 && temp > upperBound)
return false;
return true;
}
///
/// Returns whether a string is a valid Int64
///
/// String value to check
/// Lower bound (>=)
/// Upper bound (<=)
/// True if it's a valid Int64, false otherwise
protected bool IsValidInt64(string parameter, long lowerBound = -1, long upperBound = -1)
{
if (!long.TryParse(parameter, out long temp))
return false;
else if (lowerBound != -1 && temp < lowerBound)
return false;
else if (upperBound != -1 && temp > upperBound)
return false;
return true;
}
}
}