5
// Lluis Sanchez Gual <lluis@novell.com>
7
// Copyright (c) 2011 Novell, Inc (http://www.novell.com)
9
// Permission is hereby granted, free of charge, to any person obtaining a copy
10
// of this software and associated documentation files (the "Software"), to deal
11
// in the Software without restriction, including without limitation the rights
12
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13
// copies of the Software, and to permit persons to whom the Software is
14
// furnished to do so, subject to the following conditions:
16
// The above copyright notice and this permission notice shall be included in
17
// all copies or substantial portions of the Software.
19
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
28
using System.Collections.Generic;
29
using System.Diagnostics;
33
using System.Threading;
35
using MonoDevelop.Core.FileSystem;
37
namespace MonoDevelop.Core
40
public struct FilePath: IComparable<FilePath>, IComparable, IEquatable<FilePath>
44
public static readonly FilePath Null = new FilePath (null);
45
public static readonly FilePath Empty = new FilePath (string.Empty);
47
public FilePath (string name)
53
get { return fileName == null; }
56
public bool IsNullOrEmpty {
57
get { return string.IsNullOrEmpty (fileName); }
60
public bool IsNotNull {
61
get { return fileName != null; }
65
get { return fileName != null && fileName.Length == 0; }
68
public FilePath FullPath {
70
return new FilePath (!string.IsNullOrEmpty (fileName) ? Path.GetFullPath (fileName) : "");
75
/// Returns a path in standard form, which can be used to be compared
76
/// for equality with other canonical paths. It is similar to FullPath,
77
/// but unlike FullPath, the directory "/a/b" is considered equal to "/a/b/"
79
public FilePath CanonicalPath {
81
string fp = Path.GetFullPath (fileName);
82
if (fp.Length > 0 && fp[fp.Length - 1] == Path.DirectorySeparatorChar)
83
return fp.TrimEnd (Path.DirectorySeparatorChar);
89
public string FileName {
91
return Path.GetFileName (fileName);
95
public string Extension {
97
return Path.GetExtension (fileName);
101
public bool HasExtension (string extension)
103
return fileName.Length > extension.Length
104
&& fileName.EndsWith (extension, StringComparison.OrdinalIgnoreCase)
105
&& fileName[fileName.Length - extension.Length - 1] != Path.PathSeparator;
108
public string FileNameWithoutExtension {
110
return Path.GetFileNameWithoutExtension (fileName);
114
public FilePath ParentDirectory {
116
return new FilePath (Path.GetDirectoryName (fileName));
120
public bool IsAbsolute {
121
get { return Path.IsPathRooted (fileName); }
124
public bool IsChildPathOf (FilePath basePath)
126
StringComparison sc = PropertyService.IsWindows ? StringComparison.OrdinalIgnoreCase : StringComparison.Ordinal;
127
if (basePath.fileName [basePath.fileName.Length - 1] != Path.DirectorySeparatorChar)
128
return fileName.StartsWith (basePath.fileName + Path.DirectorySeparatorChar, sc);
130
return fileName.StartsWith (basePath.fileName, sc);
133
public FilePath ChangeExtension (string ext)
135
return Path.ChangeExtension (fileName, ext);
138
public FilePath Combine (params FilePath[] paths)
140
string path = fileName;
141
foreach (FilePath p in paths)
142
path = Path.Combine (path, p.fileName);
143
return new FilePath (path);
146
public FilePath Combine (params string[] paths)
148
string path = fileName;
149
foreach (string p in paths)
150
path = Path.Combine (path, p);
151
return new FilePath (path);
155
/// Builds a path by combining all provided path sections
157
public static FilePath Build (params string[] paths)
159
return Empty.Combine (paths);
162
public static FilePath GetCommonRootPath (IEnumerable<FilePath> paths)
164
FilePath root = FilePath.Null;
165
foreach (FilePath p in paths) {
170
else if (root.IsChildPathOf (p))
173
while (!root.IsNullOrEmpty && !p.IsChildPathOf (root))
174
root = root.ParentDirectory;
180
public FilePath ToAbsolute (FilePath basePath)
185
return Combine (basePath, this).FullPath;
188
public FilePath ToRelative (FilePath basePath)
190
return FileService.AbsoluteToRelativePath (basePath, fileName);
193
public static implicit operator FilePath (string name)
195
return new FilePath (name);
198
public static implicit operator string (FilePath filePath)
200
return filePath.fileName;
203
public static bool operator == (FilePath name1, FilePath name2)
205
if (PropertyService.IsWindows)
206
return string.Equals (name1.fileName, name2.fileName, StringComparison.OrdinalIgnoreCase);
208
return string.Equals (name1.fileName, name2.fileName, StringComparison.Ordinal);
211
public static bool operator != (FilePath name1, FilePath name2)
213
return !(name1 == name2);
216
public override bool Equals (object obj)
218
if (!(obj is FilePath))
221
FilePath fn = (FilePath) obj;
225
public override int GetHashCode ( )
227
if (fileName == null)
229
if (PropertyService.IsWindows)
230
return fileName.ToLower ().GetHashCode ();
232
return fileName.GetHashCode ();
235
public override string ToString ( )
240
public int CompareTo (FilePath filePath)
242
return string.Compare (fileName, filePath.fileName, PropertyService.IsWindows);
245
int IComparable.CompareTo (object obj)
247
if (!(obj is FilePath))
249
return CompareTo ((FilePath) obj);
252
#region IEquatable<FilePath> Members
254
bool IEquatable<FilePath>.Equals (FilePath other)
256
return this == other;
262
public static class FilePathUtil
264
public static string[] ToStringArray (this FilePath[] paths)
266
string[] array = new string[paths.Length];
267
for (int n = 0; n < paths.Length; n++)
268
array[n] = paths[n].ToString ();
272
public static FilePath[] ToFilePathArray (this string[] paths)
274
var array = new FilePath[paths.Length];
275
for (int n = 0; n < paths.Length; n++)
280
public static IEnumerable<string> ToPathStrings (this IEnumerable<FilePath> paths)
282
foreach (FilePath p in paths)
283
yield return p.ToString ();