Skip to content
This repository has been archived by the owner on May 27, 2019. It is now read-only.

Commit

Permalink
Refactor DatLoader
Browse files Browse the repository at this point in the history
  • Loading branch information
lucaspiller committed Aug 27, 2009
1 parent d785ca2 commit 0d15476
Show file tree
Hide file tree
Showing 5 changed files with 208 additions and 87 deletions.
16 changes: 11 additions & 5 deletions src/Ysfo.Core/Addons/AircraftAddon.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,19 @@ public class AircraftAddon : Addon
/// <param name="ysPath">The path to the base directory of YsFlight.</param>
public override void Load(String ysPath)
{
var regexes = new Dictionary<Regex, DatLoader.StringSetDelegate>
using (var loader = new DatLoader(ysPath, LstEntry))
{
{new Regex("IDENTIFY \"(.*)\""), delegate(String value) { Name = value; }},
{new Regex("CATEGORY (.*)"), delegate(String value) { Category = value; }}
};
// add regex
Regex nameRegex = loader.AddRegex("IDENTIFY \"(.*)\"");
Regex categoryRegex = loader.AddRegex("CATEGORY (.*)");

DatLoader.Load(ysPath, LstEntry, regexes);
// load
loader.Load();

// set values
Name = loader.GetValue(nameRegex);
Category = loader.GetValue(categoryRegex);
}
}
}
}
13 changes: 9 additions & 4 deletions src/Ysfo.Core/Addons/GroundAddon.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,17 @@ public class GroundAddon : Addon
/// <param name="ysPath">The path to the base directory of YsFlight.</param>
public override void Load(String ysPath)
{
var regexes = new Dictionary<Regex, DatLoader.StringSetDelegate>
using (var loader = new DatLoader(ysPath, LstEntry))
{
{ new Regex("IDENTIFY (.*)"), delegate(String value) { Name = value; } }
};
// add regex
Regex nameRegex = loader.AddRegex("IDENTIFY (.*)");

DatLoader.Load(ysPath, LstEntry, regexes);
// load
loader.Load();

// set values
Name = loader.GetValue(nameRegex);
}
}
}
}
162 changes: 126 additions & 36 deletions src/Ysfo.Core/Loaders/DatLoader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,74 +8,160 @@ namespace Ysfo.Core.Loaders
/// <summary>
/// Provides methods for parsing a .dat file.
/// </summary>
public static class DatLoader
public class DatLoader : IDisposable
{
private String _ysPath;
private String _lstEntry;

private Dictionary<Regex, String> _results;
private List<Regex> _regexs;

/// <summary>
/// Loads the details of a .dat file.
/// Creates a new addon collection.
/// </summary>
/// <param name="ysPath">The path to the ysFlight base directory.</param>
/// <param name="ysPath">The path to the YsFlight base directory.</param>
/// <param name="lstEntry">The lst entry for this object.</param>
/// <param name="regexes">A list of regular expressions to search for, and callbacks to return the result to.</param>
public static void Load(String ysPath, String lstEntry, Dictionary<Regex, StringSetDelegate> regexes)
/// <remarks>
/// If <paramref name="lstEntry"/> is invalid (wrong directory seperator)
/// for the execution platform, it will be converted.
/// </remarks>
/// <example>
/// var loader = new DatLoader(path, entry);
/// var nameRegex = loader.AddRegex("NAME (.*)");
/// loader.load();
/// String name = loader.GetValue(nameRegex);
/// </example>
public DatLoader(String ysPath, String lstEntry)
{
// get dat file
String datFile = GetDatFileFromLstEntry(lstEntry);
_ysPath = ysPath;
_lstEntry = lstEntry;

// check ysPath
if (ysPath == null)
{
throw new ArgumentException("ysPath is null.");
}
_results = new Dictionary<Regex, string>();
_regexs = new List<Regex>();
}

if (!Directory.Exists(ysPath))
{
throw new ArgumentException("Invalid ysPath; directory `" + ysPath + "' does not exist.");
}
/// <summary>
/// Adds a regex to the list of regexs to search for.
/// </summary>
/// <param name="regex">The Regex object to match.</param>
public void AddRegex(Regex regex)
{
// add to collection
_regexs.Add(regex);
}

/// <summary>
/// Adds a regex to the list of regexs to search for.
/// </summary>
/// <param name="pattern">The regular expression pattern to match.</param>
/// <returns>A Regex object for the pattern.</returns>
/// <remarks>
/// The return value from this should be passed to GetValue after
/// Load has been called, to get the value for that regex.
/// </remarks>
public Regex AddRegex(String pattern)
{
// create
Regex regex = new Regex(pattern);

// add to collection
AddRegex(regex);

return regex;
}

// combine dat file with base dir to get full path
datFile = Path.GetFullPath(Path.Combine(ysPath, datFile));
/// <summary>
/// Gets the value (if any) for the given regex.
/// </summary>
/// <param name="regex">The Regex object to get the value for.</param>
/// <returns>Value of the given regex, or <code>null</code>.</returns>
/// <exception cref="ArgumentOutOfRangeException"><paramref name="regex"/>
/// was not passed to AddRegex before Load was called.</exception>
public String GetValue(Regex regex)
{
// value
return _results[regex];
}

/// <summary>
/// Loads the dat file, parsing the regular expressions to extract data.
/// </summary>
/// <exception cref="DirectoryNotFoundException">Directory ysPath does not exist.</exception>
/// <exception cref="ArgumentNullException">ysPath or lstPath is <code>null</code>.</exception>
/// <exception cref="ArgumentException">lstEntry is invalid.</exception>
/// <exception cref="InvalidOperationException">Load called before AddRegex.</exception>
public void Load()
{
// don't bother if there are no regexs
if (_regexs.Count == 0)
throw new InvalidOperationException("Must call AddRegex at least once before calling Load.");

// get dat file
String datFile = GetDatFileFromLstEntry(_lstEntry);

// get dat file path
datFile = PathHelper.GetFullPath(_ysPath, datFile);

// open file
using (var file = File.OpenText(datFile))
{
// read each line, ensuring not null (EOF)
Boolean finished = false;
String line;
while ((line = file.ReadLine()) != null)
{
// skip if blank
if (line.Length == 0)
{
continue;
}

// for each regex
regexes.Keys.ForEach(r =>
{
// check if matches
Match m = r.Match(line);
if (m.Success)
{
// if so call delegate with result
regexes[r](m.Groups[1].Value);
}
});
_regexs.ForEach(regex =>
{
// check if matches
Match m = regex.Match(line);
if (m.Success)
{
// if so set result
_results[regex] = m.Groups[1].Value;
// check whether all values are set
finished = (_results.Count == _regexs.Count);
}
});

// yes, so exit loop
if (finished)
{
break;
}
}
}
}

public delegate void StringSetDelegate(String value);

/// <summary>
/// Parses a LstEntry to return the relative path to the .dat file.
/// </summary>
/// <param name="lstEntry">The entry in the .lst file for the object.</param>
/// <returns>The relative path to the .dat file from the YsFlight base directory.</returns>
/// <exception cref="ArgumentException">
/// Thrown when the .dat file cannot be detected in
/// the given lstEntry. See message for further details.
/// </exception>
/// <remarks>
/// If <paramref name="lstEntry"/> is invalid (wrong directory seperator)
/// for the execution platform, it will be converted.
/// </remarks>
/// <exception cref="ArgumentNullException"><paramref name="lstEntry"/> is <code>null</code>.</exception>
/// <exception cref="ArgumentException"><paramref name="lstEntry"/> is invalid.</exception>
public static String GetDatFileFromLstEntry(String lstEntry)
{
// check not null
if (lstEntry == null)
{
// no match
throw new ArgumentException("lstEntry is null.");
throw new ArgumentNullException("lstEntry");
}

// convert lst entry
lstEntry = PathHelper.ConvertLstEntryToNative(lstEntry);

// split lst
String[] split = lstEntry.Split(' ');

Expand All @@ -92,5 +178,9 @@ public static String GetDatFileFromLstEntry(String lstEntry)
// no match
throw new ArgumentException("No dat file found in lstEntry `" + lstEntry + "'.");
}

public void Dispose()
{
}
}
}
Loading

0 comments on commit 0d15476

Please sign in to comment.