public interface IStringsTransformInstanciator
{
IStringsTransform CreateInstance();
}
public class InvertCharsPerStringTransformInstanciator : IStringsTransformInstanciator
internal InvertCharsPerStringTransformInstanciator()
public IStringsTransform CreateInstance()
return new InvertCharsPerStringTransform();
public override string ToString()
return TransformResources.InvertCharsPerStringTransform;
public class NumberPerStringTransformInstanciator : IStringsTransformInstanciator
internal NumberPerStringTransformInstanciator()
return new NumberPerStringTransform();
return TransformResources.NumberPerStringTransform;
internal class CompositeStringsTransform : IStringsTransform
private List<IStringsTransformInstanciator> _transforms = new List<IStringsTransformInstanciator>();
public CompositeStringsTransform(IEnumerable<IStringsTransformInstanciator> transforms)
_transforms.AddRange(transforms);
public CompositeStringsTransform(params IStringsTransform[] transforms)
: this((IEnumerable<IStringsTransformInstanciator>)transforms)
public List<IStringsTransformInstanciator> Transforms
get { return _transforms; }
public IEnumerable<string> Do(IEnumerable<string> lines)
foreach (var transform in Transforms)
lines = transform.CreateInstance().Do(lines);
return lines;
var sb = new StringBuilder();
sb.Append(" & ");
sb.Append(transform);
return sb.ToString().Substring(3);
public static class FileTransform
private static Dictionary<string, BackgroundWorker> _transformsRunning =
new Dictionary<string, BackgroundWorker>();
private static object _lockObject = new object();
public static void Transform(string inFilePath, string outFilePath,
IEnumerable<IStringsTransformInstanciator> transforms, Action<string> showError,
Func<string, bool> showErrorWithRetry, Action<bool> transformDone)
if (!(File.Exists(inFilePath) || _transformsRunning.ContainsKey(inFilePath)))
FileNotFoundShowError(inFilePath, showError);
else if (!Directory.Exists(Path.GetDirectoryName(outFilePath)))
DirectoryNotFoundShowError(outFilePath, showError);
else
var bg = new BackgroundWorker();
bg.DoWork += (s, e) =>
e.Result = false;
while (true)
try
FileUtil.WriteLines(outFilePath,
new CompositeStringsTransform(transforms).Do(FileUtil.GetLines(inFilePath)));
e.Result = true;
catch (FileNotFoundException)
catch (DirectoryNotFoundException)
catch (IOException)
if (showErrorWithRetry(string.Format(ErrorResources.IOException, outFilePath)))
continue;
catch (Exception ex)
showError(string.Format(ErrorResources.FileNotFoundException,
string.Concat(ex.GetType(), " : ", ex.Message)));
break;
lock (_lockObject)
_transformsRunning.Remove(outFilePath);
};
bg.RunWorkerCompleted += (s, e) =>
if (transformDone != null)
transformDone((bool)e.Result);
StartBGAndCache(inFilePath, outFilePath, bg);
private static void StartBGAndCache(string inFilePath, string outFilePath, BackgroundWorker bg)
RunWorkerCompletedEventHandler runWorkerCompletedTryAgain = null;
Action<BackgroundWorker> tryAgain = (bgTryAgain) =>
bgTryAgain.RunWorkerCompleted -= runWorkerCompletedTryAgain;
if (_transformsRunning.ContainsKey(inFilePath))
var bgTryAgain = _transformsRunning[inFilePath];
runWorkerCompletedTryAgain = (s, e) => tryAgain(bgTryAgain);
bgTryAgain.RunWorkerCompleted += runWorkerCompletedTryAgain;
else if (_transformsRunning.ContainsKey(outFilePath))
var bgTryAgain = _transformsRunning[outFilePath];
_transformsRunning.Add(outFilePath, bg);
bg.RunWorkerAsync();
private static void DirectoryNotFoundShowError(string directoryPath, Action<string> showError)
showError(string.Format(ErrorResources.DirectoryNotFoundException, Path.GetDirectoryName(directoryPath)));
private static void FileNotFoundShowError(string filePath, Action<string> showError)
showError(string.Format(ErrorResources.FileNotFoundException, filePath));
StartBGAndCache(fileTransformInfo, bg, transformDone);
Func<int, int> fact = null;
fact = n => n == 0 ? 1 : n * fact(n - 1);
public static class Transforms
private static List<IStringsTransformInstanciator> _transforms;
public static List<IStringsTransformInstanciator> TransformsAllowed
get
if (_transforms == null)
_transforms = new List<IStringsTransformInstanciator>()
new NumberPerStringTransformInstanciator(),
new InvertCharsPerStringTransformInstanciator()
return _transforms;