//------------------------------------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 _AllowedValues;
internal string _ID;
internal RuntimeValues(string ID, int capacity)
{
_AllowedValues = new Dictionary(capacity);
_ID = ID;
}
internal RuntimeValues(string ID) : this(ID, 0x10) { }
internal Dictionary 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 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 class 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
{
}
}
//------------------------------------ namespace Nuri.FasterTemplate
{
public class TokenConfiguration
{
public readonly char TokenStartMarker;
public readonly char TokenEndMarker;
public TokenConfiguration(char tokenStartMarker, char tokenEndMarker)
{
TokenStartMarker = tokenStartMarker;
TokenEndMarker = tokenEndMarker;
}
}
}