Click here to Skip to main content
Click here to Skip to main content
Add your own
alternative version

Enhanced String Handling II

, 16 Dec 2010 CPOL
Overcoming limitations of: Enhanced String Handling
EnhancedStringEvaluate.zip
EnhancedStringEvaluate
bin
Debug
ConfigEvaluate.vshost.exe
ConfigEvaluate.vshost.exe.manifest
EnhancedStringEvaluate.dll
EnhancedStringEvaluate.pdb
ConcordPairEvaluate.csproj.vs10x
EnhancedStringEvaluate.csproj.user
EnhancedStringEvaluate.csproj.vs10x
obj
Debug
Decl
EnhancedStringEvaluate.dll
EnhancedStringEvaluate.pdb
DesignTimeResolveAssemblyReferencesInput.cache
EnhancedStringEvaluate.dll
EnhancedStringEvaluate.pdb
Refactor
ConfigEvaluate.dll
ResolveAssemblyReference.cache
TempPE
Properties
EvaluateTest
bin
Debug
EnhancedStringEvaluate.dll
EnhancedStringEvaluate.pdb
EvaluateSampleTest.dll
EvaluateSampleTest.pdb
EvaluateTest.dll
EvaluateTest.pdb
TestEvaluation.exe
TestEvaluation.pdb
EvaluateSampleTest.csproj.vs10x
EvaluateTest.csproj.vs10x
obj
Debug
Decl
EvaluateSampleTest.dll
EvaluateSampleTest.pdb
DesignTimeResolveAssemblyReferencesInput.cache
EvaluateSampleTest.dll
EvaluateSampleTest.pdb
EvaluateTest.dll
EvaluateTest.pdb
ResolveAssemblyReference.cache
TempPE
Properties
TestEvaluate
bin
Debug
abc.text
EnhancedStringEvaluate.dll
EnhancedStringEvaluate.pdb
TestEvaluate.exe
TestEvaluate.pdb
TestEvaluate.vshost.exe.manifest
TestEvaluation.exe
TestEvaluation.pdb
TestEvaluation.vshost.exe
TestEvaluation.vshost.exe.manifest
TestOnTheFlyConfig.vshost.exe
TestOnTheFlyConfig.vshost.exe.manifest
obj
Debug
Decl
TestEvaluation.exe
TestEvaluation.pdb
DesignTimeResolveAssemblyReferencesInput.cache
Refactor
ResolveAssemblyReference.cache
TempPE
TestEvaluate.exe
TestEvaluate.pdb
TestEvaluation.exe
TestEvaluation.pdb
ProcessEvaluate
Properties
TestEvaluate.csproj.vs10x
TestEvaluation.csproj.user
TestEvaluation.csproj.vs10x
TestOnTheFlyConfig.csproj.vs10x
Enhanced String Handling II.pdf
using System;
using System.Text.RegularExpressions;
using System.IO;


namespace TestEvaluation.ProcessEvaluate
{
	/// <summary>
	/// IO path and directory and file helper
	/// A helper class for file processing like ProcessForeignKey and ProcessIf
	/// </summary>
	public static class Util
	{
		/// <summary>Define a "good" relative path</summary>
		private static Regex _reGoodRelativePath;

		/// <summary>Define a "good" path</summary>
		private static Regex _reGoodPath;

		/// <summary>
		/// .cctor
		/// </summary>
		static Util()
		{
			// FileName restricted character set (characters not allowed in a file name)
			char[] cR = Path.GetInvalidFileNameChars();

			// Convert the restricted characters to a Unicode string understood by the 
			// regular expression evaluator ("\u9999") and make a single string out of it.
			// Note that if your first instinct is to form a string like:
			//		string restricted = new string(cR);
			// or
			//		byte[] bR = Array.ConvertAll<char, byte>(cR, c => (byte)c);
			//		string restricted = Encoding.UTF8.GetString(bR);
			// Then resist this urge, it leads to nothing but trouble when running it through 
			// a regular expression pattern matching.  The string has characters like a back 
			// slash ("\") affecting regular expression pattern matching adversely.
			// Instead do the following:
			string[] sR = Array.ConvertAll<char, string>(cR, c => string.Format("\\u{0:X4}", (int)c));
			string restricted = string.Join(string.Empty, sR);

			// A relative path is one not starting with a back-slash ("\") and 
			// between back-slash characters it contains no restricted character
			string relativePattern = string.Format(@"[^{0}]+(\\[^{0}]+)*(\\)?", restricted);
			_reGoodRelativePath = new Regex(string.Format(@"^{0}$", relativePattern), RegexOptions.Singleline);

			// A full path starts with either a drive letter followed by a colon
			// or a double back-slash character
			// then followed by a relative path.
			string pathPattern = string.Format(@"^((\w:\\{0})|(\\{{2}}{0}))$", relativePattern);
			_reGoodPath = new Regex(pathPattern, RegexOptions.Singleline);
		}

		/// <summary>
		/// 
		/// </summary>
		/// <param name="testPath"></param>
		/// <returns></returns>
		public static bool IsValidRelativeFilePath(this string testPath)
		{
			return _reGoodRelativePath.IsMatch(testPath);
		}

		/// <summary>
		/// Makes sure that the path starts with either a drive letter 
		/// followed by a colon or starts with a double back slash ("\").
		/// </summary>
		/// <param name="testPath"></param>
		/// <returns></returns>
		public static bool IsValidFullPath(this string testPath)
		{
			return _reGoodPath.IsMatch(testPath);
		}

		/// <summary>
		/// Ensure that a file is created even if the system needs to create
		/// some of the path supporting the file name.  The routine is recursive
		/// in order to accomplish the goal of creating all the supporting 
		/// directories.
		/// </summary>
		/// <param name="fileNameFullPath"></param>
		/// <returns></returns>
		public static bool CreateDirectory(this string directoryName)
		{
			if (directoryName == null || directoryName == string.Empty)
				return false;

			bool bRc = Directory.Exists(directoryName);
			if (bRc)
				return true;

			DirectoryInfo di = null;
			try
			{
				di = Directory.GetParent(directoryName);
			}
			catch (Exception ex)
			{
				string msg = ex.Message;
				for (Exception iEx = ex.InnerException; iEx != null; iEx = iEx.InnerException)
					msg += string.Format("{0}\t{1}", Environment.NewLine, iEx.Message);

				Console.WriteLine("{0}, {1}", DateTime.Now, msg);
				return false;
			}

			string parent = di.FullName;
			bRc = parent.CreateDirectory();
			if (!bRc) return false;

			Directory.CreateDirectory(directoryName);
			return true;
		}

		public static string ExtendToFullPath(this string pathNm)
		{
			// If the path pointed to by pathNm is a full path then we are good to go and no 
			// further path processing is needed.  But if, on the other hand, the path is a 
			// relative path, then prepend pathNm with the path of the executing program's path.
			bool rc = pathNm.IsValidFullPath();
			if (rc) return pathNm;

			rc = pathNm.IsValidRelativeFilePath();
			if (!rc)
			{
				// A better choice for this exception would be a more specialized exception 
				// structure, potentially employing Enterprise Library.  However, worrying about 
				// the exception will take us away from our main topic.
				throw new ArgumentException(string.Format("Invalid file name path: {0}", pathNm), "pathNm");
			}

			// The fileNm is a valid relative path
			string basedir = AppDomain.CurrentDomain.BaseDirectory;
			pathNm = Path.Combine(basedir, pathNm);
			return pathNm;
		}
	}
}

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)

Share

About the Author

Avi Farah

United States United States
avifarah@gmail.com

| Advertise | Privacy | Terms of Use | Mobile
Web02 | 2.8.141216.1 | Last Updated 16 Dec 2010
Article Copyright 2010 by Avi Farah
Everything else Copyright © CodeProject, 1999-2014
Layout: fixed | fluid