Click here to Skip to main content
15,892,643 members
Articles / Security / Encryption

Enhanced String Handling II

Rate me:
Please Sign up or sign in to vote.
3.76/5 (11 votes)
16 Dec 2010CPOL2 min read 36.2K   213   15  
Overcoming limitations of: Enhanced String Handling
using System;
using System.Text.RegularExpressions;
using System.IO;
using EnhancedStringEvaluate;


namespace TestEvaluation.ProcessEvaluate
{
	/// <summary>
	/// Process a construct like:
	///		{ForeignKey::fullpath or UNC path or relative path::key}
	///	This class is very similar to the ProcessKey class in the sense 
	///	that, evaluating the key does not guarantee that the result will
	///	need no further evaluations.
	///	
	/// It expects the middle section to point to a flat file having the format
	/// of:
	///		key=value
	/// 
	/// A static key evaluation
	/// </summary>
	public sealed class ProcessForeignKey : IProcessEvaluate
	{
		/// <summary>
		/// Need a place holder for the calling class (Config) data dictionary
		/// </summary>
		private readonly Regex _reKey;
		private readonly Regex _reForeignKey;
		private readonly IDelimitersAndSeparator _delim;

		public ProcessForeignKey() : this(DelimitersAndSeparator.DefaultDelimitedString) {}
		public ProcessForeignKey(IDelimitersAndSeparator delim)
		{
			_delim = delim;

			//string pattern = @"({)\s*ForeignKey\s*::(?<path>([^{}])*?)::(?<Name>([^{}])*?)(})";
			string pattern = string.Format(@"({0})\s*ForeignKey\s*::(?<path>([^{0}{1}])*?)::(?<Name>([^{0}{1}])*?)({1})",
				_delim.OpenDelimEquivalent, _delim.CloseDelimEquivalent);
			RegexOptions reo = RegexOptions.Singleline | RegexOptions.IgnoreCase;
			_reKey = new Regex(pattern, reo);

			string foreignPat = @"^(?<key>.*?)=(?<value>.*)$";
			_reForeignKey = new Regex(foreignPat, reo);
		}

		#region IProcessEvaluate Members

		/// <summary>
		/// The function takes a value like "{ForeignKey::path::EnvSpecific}"
		/// and returns the value as it appears in the file (specified by path).
		/// The routine will look for constructs within the file (specified by path)
		/// that is ForeignKey=value.
		/// </summary>
		/// <param name="src"></param>
		/// <param name="ea"></param>
		public void Evaluate(object src, EnhancedStringEventArgs ea)
		{
			// Initialize return code
			ea.IsHandled = false;

			// Evaluate Task 1
			string text = ea.EhancedPairElem.Value;
			if (string.IsNullOrWhiteSpace(text)) return;

			bool rc = _reKey.IsMatch(text);
			if (!rc) return;

			string replacement = _reKey.Replace(text, KeyReplace);
			if (replacement == null) return;
			if (replacement == text) return;

			// Evaluate Task 2: Announce that expression was successfully handled
			ea.IsHandled = true;

			// Evaluate Task 3: Keep new value
			ea.EhancedPairElem.Value = replacement;
			return;
		}

		#endregion

		private string KeyReplace(Match m)
		{
			string fileNm = m.Groups["path"].Value;
			string key = m.Groups["Name"].Value;

			fileNm = fileNm.ExtendToFullPath();
			if (!File.Exists(fileNm))
				return null;

			// Substitute a different key if one exists
			//
			// I make the assumption that the number of keys needed from
			// the provided path is small enough that opening and closing
			// the file for each foreign key fetch is not a performance
			// problem.  If this assumption is not a good one then we need
			// to modify the code to open the file once and close it once.
			using (StreamReader sr = new StreamReader(fileNm))
			{
				while (!sr.EndOfStream)
				{
					string line = sr.ReadLine();
					Match mForeign = _reForeignKey.Match(line);
					if (mForeign.Success)
					{
						if (string.Compare(key, mForeign.Groups["key"].Value, true) == 0)
							return mForeign.Groups["value"].Value;
					}
				}
			}

			return m.ToString();
		}
	}
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
United States United States
avifarah@gmail.com

Comments and Discussions