PageRenderTime 25ms CodeModel.GetById 26ms RepoModel.GetById 1ms app.codeStats 0ms

/src/Castle.Services.Transaction/IO/Path.cs

https://github.com/gusgorman/Castle.Services.Transaction
C# | 258 lines | 160 code | 23 blank | 75 comment | 45 complexity | fcdab2584cfac4b11042ed5f8cede02e MD5 | raw file
  1. #region License
  2. // Copyright 2004-2010 Castle Project - http://www.castleproject.org/
  3. //
  4. // Licensed under the Apache License, Version 2.0 (the "License");
  5. // you may not use this file except in compliance with the License.
  6. // You may obtain a copy of the License at
  7. //
  8. // http://www.apache.org/licenses/LICENSE-2.0
  9. //
  10. // Unless required by applicable law or agreed to in writing, software
  11. // distributed under the License is distributed on an "AS IS" BASIS,
  12. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. // See the License for the specific language governing permissions and
  14. // limitations under the License.
  15. //
  16. #endregion
  17. namespace Castle.Services.Transaction.IO
  18. {
  19. using System;
  20. using System.Collections.Generic;
  21. using System.Text;
  22. ///<summary>
  23. /// Utility class meant to replace the <see cref="System.IO.Path"/> class completely. This class handles these types of paths:
  24. /// <list>
  25. /// <item>UNC network paths: \\server\folder</item>
  26. /// <item>UNC-specified network paths: \\?\UNC\server\folder</item>
  27. /// <item>IPv4 network paths: \\192.168.3.22\folder</item>
  28. /// <item>Rooted paths: /dev/cdrom0</item>
  29. /// <item>Rooted paths: C:\folder</item>
  30. /// <item>UNC-rooted paths: \\?\C:\folder\file</item>
  31. /// <item>Fully expanded IPv6 paths</item>
  32. /// </list>
  33. ///</summary>
  34. public static class Path
  35. {
  36. // can of worms shut!
  37. // TODO: 2001:0db8::1428:57ab and 2001:0db8:0:0::1428:57ab are not matched!
  38. // ip6: thanks to http://blogs.msdn.com/mpoulson/archive/2005/01/10/350037.aspx
  39. private static readonly List<char> _InvalidChars;
  40. static Path()
  41. {
  42. // _Reserved = new List<string>("CON|PRN|AUX|NUL|COM1|COM2|COM3|COM4|COM5|COM6|COM7|COM8|COM9|LPT1|LPT2|LPT3|LPT4|LPT5|LPT6|LPT7|LPT8|LPT9"
  43. // .Split('|'));
  44. _InvalidChars = new List<char>(GetInvalidPathChars());
  45. }
  46. ///<summary>
  47. /// Returns whether the path is rooted.
  48. ///</summary>
  49. ///<param name="path">Gets whether the path is rooted or relative.</param>
  50. ///<returns>Whether the path is rooted or not.</returns>
  51. ///<exception cref="ArgumentNullException">If the passed argument is null.</exception>
  52. public static bool IsRooted(string path)
  53. {
  54. if (path == null) throw new ArgumentNullException("path");
  55. if (path == string.Empty) return false;
  56. return PathInfo.Parse(path).Root != string.Empty;
  57. }
  58. /// <summary>
  59. /// Gets the path root, i.e. e.g. \\?\C:\ if the passed argument is \\?\C:\a\b\c.abc.
  60. /// </summary>
  61. /// <param name="path">The path to get the root for.</param>
  62. /// <returns>The string denoting the root.</returns>
  63. public static string GetPathRoot(string path)
  64. {
  65. if (path == null) throw new ArgumentNullException("path");
  66. if (path == string.Empty) throw new ArgumentException("path was empty.");
  67. if (ContainsInvalidChars(path)) throw new ArgumentException("path contains invalid characters.");
  68. return PathInfo.Parse(path).Root;
  69. }
  70. private static bool ContainsInvalidChars(string path)
  71. {
  72. int c = _InvalidChars.Count;
  73. int l = path.Length;
  74. for (int i = 0; i < l; i++)
  75. for (int j = 0; j < c; j++)
  76. if (path[i] == _InvalidChars[j])
  77. return true;
  78. return false;
  79. }
  80. ///<summary>
  81. /// Gets a path without root.
  82. ///</summary>
  83. ///<param name="path"></param>
  84. ///<returns></returns>
  85. ///<exception cref="ArgumentNullException"></exception>
  86. public static string GetPathWithoutRoot(string path)
  87. {
  88. if (path == null) throw new ArgumentNullException("path");
  89. if (path.Length == 0) return string.Empty;
  90. return path.Substring(GetPathRoot(path).Length);
  91. }
  92. ///<summary>
  93. /// Normalize all the directory separation chars.
  94. /// Also removes empty space in beginning and end of string.
  95. ///</summary>
  96. ///<param name="pathWithAlternatingChars"></param>
  97. ///<returns>The directory string path with all occurrances of the alternating chars
  98. /// replaced for that specified in <see cref="System.IO.Path.DirectorySeparatorChar"/></returns>
  99. public static string NormDirSepChars(string pathWithAlternatingChars)
  100. {
  101. var sb = new StringBuilder();
  102. for (int i = 0; i < pathWithAlternatingChars.Length; i++)
  103. if ((pathWithAlternatingChars[i] == '\\') || (pathWithAlternatingChars[i] == '/'))
  104. sb.Append(DirectorySeparatorChar);
  105. else
  106. sb.Append(pathWithAlternatingChars[i]);
  107. return sb.ToString().Trim(new[] { ' ' });
  108. }
  109. ///<summary>
  110. /// Gets path info (drive and non root path)
  111. ///</summary>
  112. ///<param name="path">The path to get the info from.</param>
  113. ///<returns></returns>
  114. ///<exception cref="ArgumentNullException"></exception>
  115. public static PathInfo GetPathInfo(string path)
  116. {
  117. if (path == null) throw new ArgumentNullException("path");
  118. return PathInfo.Parse(path);
  119. }
  120. ///<summary>
  121. /// Gets the full path for a given path.
  122. ///</summary>
  123. ///<param name="path"></param>
  124. ///<returns>The full path string</returns>
  125. ///<exception cref="ArgumentNullException">if path is null</exception>
  126. public static string GetFullPath(string path)
  127. {
  128. if (path == null) throw new ArgumentNullException("path");
  129. if (path.StartsWith("\\\\?\\") || path.StartsWith("\\\\.\\")) return System.IO.Path.GetFullPath(path.Substring(4));
  130. if (path.StartsWith("\\\\?\\UNC\\")) return System.IO.Path.GetFullPath(path.Substring(8));
  131. if (path.StartsWith("file:///")) return new Uri(path).LocalPath;
  132. return System.IO.Path.GetFullPath(path);
  133. }
  134. /// <summary>
  135. /// Removes the last directory/file off the path.
  136. ///
  137. /// For a path "/a/b/c" would return "/a/b"
  138. /// or for "\\?\C:\folderA\folder\B\C\d.txt" would return "\\?\C:\folderA\folder\B\C"
  139. /// </summary>
  140. /// <param name="path">The path string to modify</param>
  141. /// <returns></returns>
  142. public static string GetPathWithoutLastBit(string path)
  143. {
  144. if (path == null) throw new ArgumentNullException("path");
  145. var chars = new List<char>(new[] {DirectorySeparatorChar, AltDirectorySeparatorChar});
  146. bool endsWithSlash = false;
  147. int secondLast = -1;
  148. int last = -1;
  149. char lastType = chars[0];
  150. for (int i = 0; i < path.Length; i++)
  151. {
  152. if (i == path.Length - 1 && chars.Contains(path[i]))
  153. endsWithSlash = true;
  154. if (!chars.Contains(path[i])) continue;
  155. secondLast = last;
  156. last = i;
  157. lastType = path[i];
  158. }
  159. if (last == -1)
  160. throw new ArgumentException(string.Format("Could not find a path separator character in the path \"{0}\"", path));
  161. var res = path.Substring(0, endsWithSlash ? secondLast : last);
  162. return res == string.Empty ? new string(lastType, 1) : res;
  163. }
  164. public static string GetFileName(string path)
  165. {
  166. if (path == null) throw new ArgumentNullException("path");
  167. if (path == string.Empty) throw new ArgumentException("path musn't be null", "path");
  168. if (path.EndsWith("/") || path.EndsWith("\\")) return string.Empty;
  169. var nonRoot = PathInfo.Parse(path).FolderAndFiles;
  170. int strIndex;
  171. // resharper is wrong that you can transform this to a ternary operator.
  172. if ((strIndex = nonRoot.LastIndexOfAny(new[] {
  173. DirectorySeparatorChar, AltDirectorySeparatorChar })) != -1)
  174. return nonRoot.Substring(strIndex+1);
  175. return nonRoot;
  176. }
  177. public static bool HasExtension(string path)
  178. {
  179. if (path == null)throw new ArgumentNullException("path");
  180. if (path == string.Empty) throw new ArgumentException("Path musn't be empty.", "path");
  181. return GetFileName(path).Length != GetFileNameWithoutExtension(path).Length;
  182. }
  183. public static string GetExtension(string path)
  184. {
  185. if (path == null) throw new ArgumentNullException("path");
  186. if (path == string.Empty) throw new ArgumentException("Path musn't be empty.", "path");
  187. var fn = GetFileName(path);
  188. var lastPeriod = fn.LastIndexOf('.');
  189. return lastPeriod == -1 ? string.Empty : fn.Substring(lastPeriod + 1);
  190. }
  191. public static string GetFileNameWithoutExtension(string path)
  192. {
  193. if (path == null) throw new ArgumentNullException("path");
  194. var filename = GetFileName(path);
  195. var lastPeriod = filename.LastIndexOf('.');
  196. return lastPeriod == -1 ? filename : filename.Substring(0, lastPeriod);
  197. }
  198. public static string GetRandomFileName()
  199. {
  200. return System.IO.Path.GetRandomFileName();
  201. }
  202. public static char[] GetInvalidPathChars()
  203. {
  204. return System.IO.Path.GetInvalidPathChars();
  205. }
  206. public static char[] GetInvalidFileNameChars()
  207. {
  208. return System.IO.Path.GetInvalidFileNameChars();
  209. }
  210. public static char DirectorySeparatorChar
  211. {
  212. get { return System.IO.Path.DirectorySeparatorChar; }
  213. }
  214. public static char AltDirectorySeparatorChar
  215. {
  216. get { return System.IO.Path.AltDirectorySeparatorChar; }
  217. }
  218. public static char[] GetDirectorySeparatorChars()
  219. {
  220. return new[] { DirectorySeparatorChar, AltDirectorySeparatorChar};
  221. }
  222. }
  223. }