namespace Nuri.FasterTemplate { public interface IFasterTemplate { string ID { get; } void Render(System.IO.TextWriter writer, IRuntimeValues runtimeValues); IRuntimeValues GetRuntimeValuesPrototype(); } }
namespace Nuri.FasterTemplate { public interface IRuntimeValues { bool AddValue(string tokenName, string value); bool AddValues(IEnumerable values); string[] GetAllowedValues(); IRuntimeValues GetCopy(); bool IsAlowed(string tokenName); string this[string tokenName] { get; } string ID { get; } } }
namespace Nuri.FasterTemplate { public static class FasterTempateFactory { public static IFasterTemplate GetFasterTemplate(TokenConfiguration config, ref string template) { string id = Guid.NewGuid().ToString(); TemplateParts templateParts = processTemplateParts(id, config, ref template); IRuntimeValues runtimeValuesPrototype = processTokens(id, templateParts); IFasterTemplate result = new FasterTemplate(id, templateParts, runtimeValuesPrototype); return result; } private static IRuntimeValues processTokens(string id, TemplateParts templateParts) { RuntimeValues result = new RuntimeValues(id); for (int i = 0; i < templateParts.Count; i++) if (templateParts[i].IsToken) result[templateParts[i].Value] = string.Empty; return result; } private static TemplateParts processTemplateParts(string id, TokenConfiguration config, ref string template) { TemplateParts result = new TemplateParts(); char currentChar; bool isToken = false; StringBuilder sbText = new StringBuilder(template.Length / 2); StringBuilder sbToken = new StringBuilder(64); for (int idx = 0; idx < template.Length; idx++) { currentChar = template[idx]; if (currentChar == config.TokenStartMarker) { isToken = true; result.Add(new TemplatePart(sbText.ToString(), false)); sbText.Length = 0; } else if (currentChar == config.TokenEndMarker) { isToken = false; result.Add(new TemplatePart(sbToken.ToString(), true)); sbToken.Length = 0; } else { if (isToken) sbToken.Append(currentChar); else sbText.Append(currentChar); } } if (isToken == true) throw new ArgumentException("Template has unclosed token marker"); if (sbText.Length > 0) result.Add(new TemplatePart(sbText.ToString(), false)); return result; } } }
namespace Nuri.FasterTemplate { internal class FasterTemplate : IFasterTemplate { private string _ID; private TemplateParts _TemplateParts; private IRuntimeValues _RuntimeValuesPrototype; internal FasterTemplate(string ID, TemplateParts templateParts, IRuntimeValues runtimeValuesPrototype) { _ID = ID; _TemplateParts = templateParts; _RuntimeValuesPrototype = runtimeValuesPrototype; } public IRuntimeValues GetRuntimeValuesPrototype() { return _RuntimeValuesPrototype.GetCopy(); } public string ID { get { return _ID; } } public void Render(System.IO.TextWriter writer, IRuntimeValues runtimeValues) { if (runtimeValues.ID != this._ID) throw new ArgumentException("The runtime values supplied are not compatible with this template! Ensure you got the runtime values object from the template with ID " + this._ID); for (int i = 0, count = _TemplateParts.Count; i < count; i++) { TemplatePart part = _TemplateParts[i]; if (part.IsToken) { writer.Write(runtimeValues[part.Value]); } else { writer.Write(part.Value); } } } } }
namespace Nuri.FasterTemplate { internal class RuntimeValues : Nuri.FasterTemplate.IRuntimeValues { private Dictionary<string,string> _AllowedValues; internal string _ID; internal RuntimeValues(string ID, int capacity) { _AllowedValues = new Dictionary<string, string>(capacity); _ID = ID; } internal RuntimeValues(string ID) : this(ID, 0x10) { } internal Dictionary<string,string> AllowedValues { get { return _AllowedValues; } } public string[] GetAllowedValues() { string[] result = new string[_AllowedValues.Count]; int i = 0; foreach (string key in _AllowedValues.Keys) { result[i++] = key; } return result; } public bool IsAlowed(string tokenName) { return _AllowedValues.ContainsKey(tokenName); } public bool AddValue(string tokenName, string value) { if (_AllowedValues.ContainsKey(tokenName)) { _AllowedValues[tokenName] = value; return true; } else return false; }
public bool AddValues(IEnumerable values) { bool result = true; foreach (KeyValuePair<string, string> pair in values) { result = result && this.AddValue(pair.Key, pair.Value); } return result; } public string this[string tokenName] { get { return _AllowedValues[tokenName]; } internal set { _AllowedValues[tokenName] = value; } } public IRuntimeValues GetCopy() { RuntimeValues result = new RuntimeValues(this._ID, _AllowedValues.Count); foreach (string key in _AllowedValues.Keys) result.AllowedValues[key] = string.Empty;
return result; } public string ID { get { return _ID; } } } }
namespace Nuri.FasterTemplate { internal struct TemplatePart { public bool IsToken; public string Value; public TemplatePart(string value, bool isToken) { this.Value = value; this.IsToken = isToken; } } }
namespace Nuri.FasterTemplate { class TemplateParts : List<TemplatePart> { } }
namespace Nuri.FasterTemplate { public struct TokenConfiguration { public readonly char TokenStartMarker; public readonly char TokenEndMarker; public TokenConfiguration(char tokenStartMarker, char tokenEndMarker) { TokenStartMarker = tokenStartMarker; TokenEndMarker = tokenEndMarker; } } }
|