using System;
using System.Text;
using System.Diagnostics;
using System.IO;
using System.Text.RegularExpressions;
namespace Analizator9000
{
///
/// Runs dealer generator and captures its output.
///
class DealerWrapper
{
///
/// Calling user interfaces instance.
///
private Form1 debugForm;
///
/// Name of the input script file.
///
private String scriptname;
///
/// Stream to the generation results output file.
///
private StreamWriter outputFile;
///
/// Flag ensuring only one instance of dealer is running.
///
private bool running = false;
///
/// Number of lines (deals) to produce.
///
private long produce = 0;
///
/// Number of lines (deals) already produced.
///
private long lineCount = 0;
///
/// Dealer wrapper class constructor.
///
/// Input script file name.
/// Calling interface form.
/// Number of deals to produce.
public DealerWrapper(String scriptname, Form1 debugForm, long produce)
{
if (!File.Exists(scriptname))
{
throw new Exception(Form1.GetResourceManager().GetString("DealerWrapper_errorFileNotFound", Form1.GetCulture()) + ": " + scriptname);
}
if (produce < 1)
{
throw new Exception(Form1.GetResourceManager().GetString("DealerWrapper_errorInvalidDealCount", Form1.GetCulture()));
}
this.scriptname = scriptname;
this.debugForm = debugForm;
this.produce = produce;
}
///
/// Sends a single line to debug field of the calling form.
///
/// Message to be appended to the debug output.
private void debugWriteLine(String line) {
this.debugForm.addStatusLine(line);
}
///
/// Processes a chunk of dealer output.
///
/// Output string of dealer instance.
/// TRUE if dealer it still running, FALSE if null string arrived -> process ended.
private bool handleData(string data)
{
if (data != null)
{
String[] dataLines = data.Split('\n');
foreach (String line in dataLines)
{
Match lineMatch = Regex.Match(line.Trim(), @"^n\s*(\S*)\s*e\s*(\S*)\s*s\s*(\S*)\s*w\s*(\S*)$");
if (lineMatch.Success)
{
this.lineCount++;
this.outputFile.Write(this.lineCount);
this.outputFile.WriteLine(lineMatch.Result(": ${1} ${2} ${3} ${4}"));
}
}
int progress = ((int)(100 * this.lineCount / this.produce));
this.debugForm.setProgress(progress);
this.debugWriteLine(data);
return true;
}
return false;
}
///
/// Closes the output file stream.
///
public void closeFile()
{
this.outputFile.Close();
}
///
/// Delegate for process end callback invocation.
///
/// Output file name.
private delegate void onEndDelegate(String filename);
///
/// Worker method for dealer generating.
///
/// Callback to the function which takes output file name as a parameter.
public void run(Action onEnd)
{
if (!this.running)
{
this.running = true;
this.lineCount = 0;
String filename = Utils.getFilename("deals");
this.outputFile = new StreamWriter(@"files\"+filename);
ProcessStartInfo pInfo = new ProcessStartInfo();
pInfo.FileName = @"bin\dealer.exe";
pInfo.WindowStyle = ProcessWindowStyle.Hidden;
pInfo.CreateNoWindow = true;
pInfo.Arguments = "\"" + this.scriptname + "\"";
pInfo.UseShellExecute = false;
pInfo.RedirectStandardOutput = true;
pInfo.RedirectStandardError = true;
pInfo.StandardOutputEncoding = pInfo.StandardErrorEncoding = Encoding.UTF8;
this.debugWriteLine(pInfo.FileName + " " + pInfo.Arguments);
Process dealerProc = new Process();
dealerProc.StartInfo = pInfo;
dealerProc.OutputDataReceived += (sender, output) =>
{
if (output != null)
{
if (!this.handleData(output.Data))
{
this.closeFile();
(new onEndDelegate(onEnd)).Invoke(filename);
}
}
};
dealerProc.ErrorDataReceived += (sender, error) => { if (error != null) { this.debugWriteLine(error.Data); } };
dealerProc.Start();
dealerProc.BeginErrorReadLine();
dealerProc.BeginOutputReadLine();
}
}
}
}