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;} } } }