176 lines
6.0 KiB
C#
176 lines
6.0 KiB
C#
// Decompiled with JetBrains decompiler
|
|
// Type: SEGATools.Scanner.FileScanner
|
|
// Assembly: SEGATools, Version=1.0.3.0, Culture=neutral, PublicKeyToken=611be24fdeb07e08
|
|
// MVID: D631183F-57B1-40A1-B502-5364D288307A
|
|
// Assembly location: SEGATools.dll
|
|
|
|
using SEGATools.UserProcess;
|
|
using SEGATools.VirtualFile;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.ComponentModel;
|
|
using System.IO;
|
|
using System.Text;
|
|
using System.Text.RegularExpressions;
|
|
|
|
namespace SEGATools.Scanner
|
|
{
|
|
public class FileScanner : UserProcessBase
|
|
{
|
|
private static readonly int MAX_ASCII_STRING_LENGTH = 128;
|
|
|
|
public event AsyncOperationProgressChangedEventHandler FileScanningProgressChanged
|
|
{
|
|
add => this.AsyncOperationProgressChanged += value;
|
|
remove => this.AsyncOperationProgressChanged -= value;
|
|
}
|
|
|
|
public event AsyncOperationCompletedEventHandler FileScanningCompleted
|
|
{
|
|
add => this.AsyncOperationCompleted += value;
|
|
remove => this.AsyncOperationCompleted -= value;
|
|
}
|
|
|
|
public FileScanner()
|
|
{
|
|
}
|
|
|
|
public FileScanner(IContainer container)
|
|
: base(container)
|
|
{
|
|
}
|
|
|
|
public List<T> ScanFile<T>(
|
|
IVirtualFile file,
|
|
FileScannerPattern pattern,
|
|
IFileScannerResultConverter<T> resultConverter)
|
|
{
|
|
return this.DoFileScanning<T>(file, new List<FileScannerPattern>()
|
|
{
|
|
pattern
|
|
}, resultConverter, (AsyncOperation) null)[pattern];
|
|
}
|
|
|
|
public void ScanFileAsync<T>(
|
|
IVirtualFile file,
|
|
FileScannerPattern pattern,
|
|
IFileScannerResultConverter<T> resultConverter,
|
|
object taskId)
|
|
{
|
|
this.ScanFilesAsync<T>(file, new List<FileScannerPattern>()
|
|
{
|
|
pattern
|
|
}, resultConverter, taskId);
|
|
}
|
|
|
|
public void ScanFileAsync<T>(
|
|
IVirtualFile file,
|
|
List<FileScannerPattern> patterns,
|
|
IFileScannerResultConverter<T> resultConverter,
|
|
object taskId)
|
|
{
|
|
this.ScanFilesAsync<T>(file, patterns, resultConverter, taskId);
|
|
}
|
|
|
|
public void ScanFilesAsync<T>(
|
|
IVirtualFile file,
|
|
List<FileScannerPattern> patterns,
|
|
IFileScannerResultConverter<T> resultConverter,
|
|
object taskId)
|
|
{
|
|
AsyncOperation asyncOperation = this.CreateAsyncOperation(taskId);
|
|
new FileScanner.FileScannerWorkerEventHandler<T>(this.FileScannerWorker<T>).BeginInvoke(file, patterns, resultConverter, asyncOperation, (AsyncCallback) null, (object) null);
|
|
}
|
|
|
|
private void FileScannerWorker<T>(
|
|
IVirtualFile file,
|
|
List<FileScannerPattern> patterns,
|
|
IFileScannerResultConverter<T> resultConverter,
|
|
AsyncOperation asyncOp)
|
|
{
|
|
Exception exception = (Exception) null;
|
|
try
|
|
{
|
|
this.CheckArguments(file, patterns);
|
|
this.DoFileScanning<T>(file, patterns, resultConverter, asyncOp);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
exception = ex;
|
|
UserProcessBase.logger.DebugFormat("Unable to scan file {0}: {1}", (object) file.VirtualName, (object) ex);
|
|
}
|
|
if (!this.TaskCanceled(asyncOp))
|
|
;
|
|
this.ReportCompletion(string.Empty, exception, asyncOp);
|
|
}
|
|
|
|
private void CheckArguments(IVirtualFile file, List<FileScannerPattern> patterns)
|
|
{
|
|
if (patterns == null || patterns.Count == 0)
|
|
throw FileScannerWrongArgumentsException.aNotValidArgument(nameof (patterns));
|
|
if (file == null || file.FileInputStream == null)
|
|
throw FileScannerWrongArgumentsException.aNotValidArgument(nameof (file));
|
|
}
|
|
|
|
private Dictionary<FileScannerPattern, List<T>> DoFileScanning<T>(
|
|
IVirtualFile file,
|
|
List<FileScannerPattern> patterns,
|
|
IFileScannerResultConverter<T> resultConverter,
|
|
AsyncOperation asyncOp)
|
|
{
|
|
Dictionary<FileScannerPattern, List<T>> dictionary = new Dictionary<FileScannerPattern, List<T>>(patterns.Count);
|
|
foreach (FileScannerPattern pattern in patterns)
|
|
dictionary[pattern] = new List<T>();
|
|
UserProcessBase.logger.DebugFormat("Scanning {0}...", (object) file.VirtualName);
|
|
foreach (FileScannerPattern pattern in patterns)
|
|
{
|
|
using (BinaryReader binaryReader = new BinaryReader(file.FileInputStream, Encoding.ASCII))
|
|
{
|
|
binaryReader.BaseStream.Seek(0L, SeekOrigin.Begin);
|
|
while (binaryReader.BaseStream.Position < binaryReader.BaseStream.Length)
|
|
{
|
|
try
|
|
{
|
|
int count = Math.Min(Convert.ToInt32(binaryReader.BaseStream.Length - binaryReader.BaseStream.Position), FileScanner.MAX_ASCII_STRING_LENGTH);
|
|
string input = new string(binaryReader.ReadChars(count));
|
|
if (pattern.Match(input))
|
|
{
|
|
UserProcessBase.logger.DebugFormat("Found string for pattern {0}: {1}", (object) pattern, (object) pattern.CapturedString);
|
|
T obj = this.ConvertResult<T>(pattern.MatchResult, resultConverter);
|
|
if ((object) obj != null)
|
|
dictionary[pattern].Add(obj);
|
|
}
|
|
else if (count > 0)
|
|
binaryReader.BaseStream.Seek((long) (-count + 1), SeekOrigin.Current);
|
|
}
|
|
catch (OverflowException ex)
|
|
{
|
|
UserProcessBase.logger.ErrorFormat("Unable to compute the number of remaining bytes in the stream: {0}", (object) ex);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return dictionary;
|
|
}
|
|
|
|
private T ConvertResult<T>(Match match, IFileScannerResultConverter<T> resultConverter)
|
|
{
|
|
try
|
|
{
|
|
return resultConverter.ToResult(match);
|
|
}
|
|
catch (FileScannerResultConverterException ex)
|
|
{
|
|
UserProcessBase.logger.ErrorFormat("Unable to convert match result with to {0}: {1}", (object) resultConverter.GetType().AssemblyQualifiedName, (object) ex);
|
|
}
|
|
return default (T);
|
|
}
|
|
|
|
private delegate void FileScannerWorkerEventHandler<T>(
|
|
IVirtualFile file,
|
|
List<FileScannerPattern> patterns,
|
|
IFileScannerResultConverter<T> resultConverter,
|
|
AsyncOperation asyncOp);
|
|
}
|
|
}
|