123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316 |
- using System;
- using System.Globalization;
- using System.Reflection;
- using System.Runtime.InteropServices;
- namespace WinSCP
- {
- [Guid("70253534-C5DC-4EF3-9C98-65C57D79C324")]
- [ClassInterface(Constants.ClassInterface)]
- [ComVisible(true)]
- public sealed class RemotePath : IReflect
- {
- public static string EscapeFileMask(string fileMask)
- {
- if (fileMask == null)
- {
- throw new ArgumentNullException(nameof(fileMask));
- }
- int lastSlash = fileMask.LastIndexOf('/');
- string path = lastSlash > 0 ? fileMask.Substring(0, lastSlash + 1) : string.Empty;
- string mask = lastSlash > 0 ? fileMask.Substring(lastSlash + 1) : fileMask;
- // Keep in sync with EscapeFileMask in GenerateUrl.cpp
- mask = mask.Replace("[", "[[]").Replace("*", "[*]").Replace("?", "[?]").Replace("<", "<<").Replace(">", ">>");
- return path + mask;
- }
- public static string EscapeOperationMask(string operationMask)
- {
- if (operationMask == null)
- {
- throw new ArgumentNullException(nameof(operationMask));
- }
- int lastSlash = operationMask.LastIndexOf('/');
- string path = lastSlash > 0 ? operationMask.Substring(0, lastSlash + 1) : string.Empty;
- string mask = lastSlash > 0 ? operationMask.Substring(lastSlash + 1) : operationMask;
- mask = mask.Replace("\\", "\\\\").Replace("*", "\\*").Replace("?", "\\?");
- return path + mask;
- }
- [Obsolete("Use RemotePath.Combine method")]
- public static string CombinePaths(string path1, string path2)
- {
- return Combine(path1, path2);
- }
- public static string Combine(string path1, string path2)
- {
- if (path1 == null)
- {
- throw new ArgumentNullException(nameof(path1));
- }
- if (path2 == null)
- {
- throw new ArgumentNullException(nameof(path2));
- }
- string result;
- if (path2.StartsWith("/", StringComparison.Ordinal))
- {
- result = path2;
- }
- else
- {
- result =
- path1 +
- ((path1.Length == 0) || (path2.Length == 0) || path1.EndsWith("/", StringComparison.Ordinal) ? string.Empty : "/") +
- path2;
- }
- return result;
- }
- public static string TranslateRemotePathToLocal(string remotePath, string remoteRoot, string localRoot)
- {
- if (remotePath == null)
- {
- throw new ArgumentNullException(nameof(remotePath));
- }
- if (remoteRoot == null)
- {
- throw new ArgumentNullException(nameof(remoteRoot));
- }
- if (localRoot == null)
- {
- throw new ArgumentNullException(nameof(localRoot));
- }
- localRoot = AddSeparator(localRoot, @"\");
- remoteRoot = AddSeparator(remoteRoot, "/");
- string localPath;
- // special case
- if (AddSeparator(remotePath, "/") == remoteRoot)
- {
- localPath = localRoot;
- }
- else
- {
- if (!remotePath.StartsWith(remoteRoot, StringComparison.Ordinal))
- {
- throw new InvalidOperationException(string.Format(CultureInfo.CurrentCulture, "{0} does not start with {1}", remotePath, remoteRoot));
- }
- string subPath = remotePath.Substring(remoteRoot.Length);
- // can happen only when remoteRoot is empty
- if (subPath.StartsWith("/", StringComparison.Ordinal))
- {
- subPath = subPath.Substring(1);
- }
- subPath = subPath.Replace('/', '\\');
- localPath = localRoot + subPath;
- }
- return localPath;
- }
- private static string AddSeparator(string path, string separator)
- {
- // not adding to empty root paths, because the path may not even start with slash
- if ((path.Length > 0) && !path.EndsWith(separator, StringComparison.Ordinal))
- {
- path += separator;
- }
- return path;
- }
- public static string TranslateLocalPathToRemote(string localPath, string localRoot, string remoteRoot)
- {
- if (localPath == null)
- {
- throw new ArgumentNullException(nameof(localPath));
- }
- if (localRoot == null)
- {
- throw new ArgumentNullException(nameof(localRoot));
- }
- if (remoteRoot == null)
- {
- throw new ArgumentNullException(nameof(remoteRoot));
- }
- localRoot = AddSeparator(localRoot, @"\");
- remoteRoot = AddSeparator(remoteRoot, "/");
- string remotePath;
- // special case
- if (AddSeparator(localPath, @"\") == localRoot)
- {
- remotePath = remoteRoot;
- }
- else
- {
- if (!localPath.StartsWith(localRoot, StringComparison.Ordinal))
- {
- throw new InvalidOperationException(string.Format(CultureInfo.CurrentCulture, "{0} does not start with {1}", localPath, localRoot));
- }
- string subPath = localPath.Substring(localRoot.Length);
- // can happen only when localRoot is empty
- if (subPath.StartsWith("\\", StringComparison.Ordinal))
- {
- subPath = subPath.Substring(1);
- }
- subPath = subPath.Replace('\\', '/');
- remotePath = remoteRoot + subPath;
- }
- return remotePath;
- }
- public static string GetDirectoryName(string path)
- {
- string result;
- if (path == null)
- {
- result = null;
- }
- else if (path.Length == 0)
- {
- throw new ArgumentException("Path cannot be empty", nameof(path));
- }
- else
- {
- int i = path.LastIndexOf('/');
- if (i < 0)
- {
- result = string.Empty;
- }
- else if (i == 0)
- {
- if (path.Length == 1)
- {
- result = null;
- }
- else
- {
- result = "/";
- }
- }
- else
- {
- result = path.Substring(0, i);
- }
- }
- return result;
- }
- public static string AddDirectorySeparator(string path)
- {
- if (string.IsNullOrEmpty(path))
- {
- throw new ArgumentException("Path cannot be empty", nameof(path));
- }
- if (!path.EndsWith("/", StringComparison.Ordinal))
- {
- path += "/";
- }
- return path;
- }
- public static string GetFileName(string path)
- {
- string result;
- if (string.IsNullOrEmpty(path))
- {
- result = null;
- }
- else
- {
- int i = path.LastIndexOf('/');
- if (i >= 0)
- {
- result = path.Substring(i + 1);
- }
- else
- {
- result = path;
- }
- }
- return result;
- }
- FieldInfo IReflect.GetField(string name, BindingFlags bindingAttr)
- {
- return GetType().GetField(name, bindingAttr);
- }
- FieldInfo[] IReflect.GetFields(BindingFlags bindingAttr)
- {
- return GetType().GetFields(bindingAttr);
- }
- MemberInfo[] IReflect.GetMember(string name, BindingFlags bindingAttr)
- {
- return GetType().GetMember(name, bindingAttr);
- }
- MemberInfo[] IReflect.GetMembers(BindingFlags bindingAttr)
- {
- return GetType().GetMembers(bindingAttr);
- }
- MethodInfo IReflect.GetMethod(string name, BindingFlags bindingAttr)
- {
- return GetType().GetMethod(name, bindingAttr);
- }
- MethodInfo IReflect.GetMethod(string name, BindingFlags bindingAttr, Binder binder, Type[] types, ParameterModifier[] modifiers)
- {
- return GetType().GetMethod(name, bindingAttr, binder, types, modifiers);
- }
- MethodInfo[] IReflect.GetMethods(BindingFlags bindingAttr)
- {
- return GetType().GetMethods(bindingAttr);
- }
- PropertyInfo[] IReflect.GetProperties(BindingFlags bindingAttr)
- {
- return GetType().GetProperties(bindingAttr);
- }
- PropertyInfo IReflect.GetProperty(string name, BindingFlags bindingAttr, Binder binder, Type returnType, Type[] types, ParameterModifier[] modifiers)
- {
- return GetType().GetProperty(name, bindingAttr, binder, returnType, types, modifiers);
- }
- PropertyInfo IReflect.GetProperty(string name, BindingFlags bindingAttr)
- {
- return GetType().GetProperty(name, bindingAttr);
- }
- object IReflect.InvokeMember(string name, BindingFlags invokeAttr, Binder binder, object target, object[] args, ParameterModifier[] modifiers, CultureInfo culture, string[] namedParameters)
- {
- if (target == null)
- {
- throw new ArgumentNullException(nameof(target));
- }
- Type type = target.GetType();
- // This trivial implementation allows calling static methods over COM
- return type.InvokeMember(name, invokeAttr, binder, target, args, modifiers, culture, namedParameters);
- }
- Type IReflect.UnderlyingSystemType
- {
- get { return GetType(); }
- }
- }
- }
|