using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
using Chernobyl.Collections.Generic.Event;
namespace Chernobyl.Resources
{
///
/// Holds a set of each with a
/// file pattern that they can read or write. When this processor receives a
/// it first tries to cast it to a ,
/// grab the file path to the file it represents using
/// , and looks for the
/// that has a matching pattern.
/// If it finds one, it passes the processing onto that processor. Otherwise,
/// it sends the processing down to the
/// .
///
/// The type of resource to process.
public class FileStreamProcessor : ResourceProcessor
{
///
/// Constructor
///
/// The services object whose services will be injected
/// into this file stream processor.
public FileStreamProcessor(IEventCollection services)
{
FileStreamProcessors = new Dictionary>();
}
///
/// Attempts to load the resource by finding a resource processor with
/// a file pattern that matches the path of the
/// path.
///
/// The callback that will be invoked when the
/// resource has been loaded.
/// The stream to load the resource from.
/// Options for the loading or processing of the
/// resource. Available options for this processor:
///
///
///
public override void From(ResourceProcessCallback callback, Stream readFrom, params IOption[] options)
{
FileStream file = readFrom as FileStream;
if (file != null)
{
// get the search options, if their are any
IEnumerable option = options.OfType();
foreach (KeyValuePair> keyValues in FileStreamProcessors)
{
// if the user specified options, apply them
if (option.Count() == 0)
{
if (Regex.IsMatch(file.Name, keyValues.Key) == true)
keyValues.Value.From(callback, readFrom, options);
}
else
if (Regex.IsMatch(file.Name, keyValues.Key, option.First().RegexOptions) == true)
keyValues.Value.From(callback, readFrom, options);
}
}
else
CheckedNextFrom(callback, readFrom, options);
}
///
/// Attempts to write out the resource by finding a resource processor with
/// a file pattern that matches the path of the FileStream path.
///
/// The resource to write out.
/// The stream to write the resource to.
/// Options for the writing or processing of the resource.
/// Available options for this processor:
///
///
///
///
public override void To(TResource resource, Stream writeTo, params IOption[] options)
{
FileStream file = writeTo as FileStream;
if (file != null)
{
// get the search options, if their are any
IEnumerable option = options.OfType();
foreach (KeyValuePair> keyValues in FileStreamProcessors)
{
// if the user specified options, apply them
if (option.Count() == 0)
{
if (Regex.IsMatch(file.Name, keyValues.Key) == true)
keyValues.Value.To(resource, writeTo, options);
}
else
if (Regex.IsMatch(file.Name, keyValues.Key, option.First().RegexOptions) == true)
keyValues.Value.To(resource, writeTo, options);
}
}
else
CheckedNextTo(resource, writeTo, options);
}
///
/// Adds a resource processor that loads a particular extension.
///
/// The file extensions that
/// loads without the initial '.'.
/// For example: "xml", "png", etc. You can also combine multiple
/// extensions using the pipe character ('|') like so: "xml|png|pdf"
///
public void AddProcessor(string fileExtensions, IResourceProcessor resourceProcessor)
{
FileStreamProcessors.Add("^.*\\.(" + fileExtensions + ")$", resourceProcessor);
}
///
/// The resource processors and the file patterns (in regex form) that
/// they can process. If a resource processor has multiple file patterns
/// that it can process then it should add itself for each one or use a
/// regex pattern that can handle multiple file patterns.
///
public Dictionary> FileStreamProcessors { get; set; }
///
/// An option for the FileStreamResourceProcessor. Allows you to
/// specify the RegexOptions used to search for the file pattern.
///
public struct RegexSearchOption : IOption
{
///
/// Constructor.
///
/// The options to apply to the Regex.IsMatch()
/// search against the file pattern for the ResourceProcessor.
public RegexSearchOption(RegexOptions regexOptions) : this()
{
RegexOptions = regexOptions;
}
///
/// The options to apply to the Regex.IsMatch()
/// search against the file pattern for the ResourceProcessor.
///
public RegexOptions RegexOptions {get; set;}
}
}
}