Преглед на файлове

Instance methods Session.EscapeFileMask, Session.CombinePaths, Session.TranslateLocalPathToRemote, Session.TranslateRemotePathToLocal, Session.AddDirectorySeparator, Session.GetDirectoryName, and Session.GetFileName replaced by static methods of the same name in class RemotePath

Source commit: 670abbe5d305c1bc99e0908a5b0db58792726684
Martin Prikryl преди 7 години
родител
ревизия
c6707774ff
променени са 4 файла, в които са добавени 321 реда и са изтрити 209 реда
  1. 7 0
      dotnet/GlobalSuppressions.cs
  2. 303 0
      dotnet/RemotePath.cs
  3. 10 209
      dotnet/Session.cs
  4. 1 0
      dotnet/WinSCPnet.csproj

+ 7 - 0
dotnet/GlobalSuppressions.cs

@@ -162,3 +162,10 @@ using System.Diagnostics.CodeAnalysis;
 [assembly: SuppressMessage("Microsoft.Security", "CA5122:PInvokesShouldNotBeSafeCriticalFxCopRule", Scope = "member", Target = "WinSCP.UnsafeNativeMethods.#RegGetValue(System.UIntPtr,System.String,System.String,WinSCP.RegistryFlags,WinSCP.RegistryType&,System.IntPtr,System.UInt32&)")]
 [assembly: SuppressMessage("Microsoft.Security", "CA2122:DoNotIndirectlyExposeMethodsWithLinkDemands", Scope = "member", Target = "WinSCP.ExeSessionProcess.#GetInstallationPath(Microsoft.Win32.RegistryHive,Microsoft.Win32.RegistryKey)")]
 [assembly: SuppressMessage("Microsoft.Globalization", "CA1303:Do not pass literals as localized parameters", MessageId = "WinSCP.Logger.DoWriteLine(System.String)", Scope = "member", Target = "WinSCP.Logger.#WriteException(System.Exception)")]
+[assembly: SuppressMessage("Microsoft.Interoperability", "CA1407:AvoidStaticMembersInComVisibleTypes", Scope = "member", Target = "WinSCP.RemotePath.#CombinePaths(System.String,System.String)")]
+[assembly: SuppressMessage("Microsoft.Interoperability", "CA1407:AvoidStaticMembersInComVisibleTypes", Scope = "member", Target = "WinSCP.RemotePath.#EscapeFileMask(System.String)")]
+[assembly: SuppressMessage("Microsoft.Interoperability", "CA1407:AvoidStaticMembersInComVisibleTypes", Scope = "member", Target = "WinSCP.RemotePath.#TranslateRemotePathToLocal(System.String,System.String,System.String)")]
+[assembly: SuppressMessage("Microsoft.Interoperability", "CA1407:AvoidStaticMembersInComVisibleTypes", Scope = "member", Target = "WinSCP.RemotePath.#TranslateLocalPathToRemote(System.String,System.String,System.String)")]
+[assembly: SuppressMessage("Microsoft.Interoperability", "CA1407:AvoidStaticMembersInComVisibleTypes", Scope = "member", Target = "WinSCP.RemotePath.#GetDirectoryName(System.String)")]
+[assembly: SuppressMessage("Microsoft.Interoperability", "CA1407:AvoidStaticMembersInComVisibleTypes", Scope = "member", Target = "WinSCP.RemotePath.#AddDirectorySeparator(System.String)")]
+[assembly: SuppressMessage("Microsoft.Interoperability", "CA1407:AvoidStaticMembersInComVisibleTypes", Scope = "member", Target = "WinSCP.RemotePath.#GetFileName(System.String)")]

+ 303 - 0
dotnet/RemotePath.cs

@@ -0,0 +1,303 @@
+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("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("?", "[?]");
+            return path + mask;
+        }
+
+        public static string CombinePaths(string path1, string path2)
+        {
+            if (path1 == null)
+            {
+                throw new ArgumentNullException("path1");
+            }
+
+            if (path2 == null)
+            {
+                throw new ArgumentNullException("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("remotePath");
+            }
+
+            if (remoteRoot == null)
+            {
+                throw new ArgumentNullException("remoteRoot");
+            }
+
+            if (localRoot == null)
+            {
+                throw new ArgumentNullException("localRoot");
+            }
+
+            if ((localRoot.Length > 0) && !localRoot.EndsWith("\\", StringComparison.Ordinal))
+            {
+                localRoot += "\\";
+            }
+
+            // not adding to empty root paths, because the path may not even start with slash
+            if ((remoteRoot.Length > 0) && !remoteRoot.EndsWith("/", StringComparison.Ordinal))
+            {
+                remoteRoot += "/";
+            }
+
+            string localPath;
+            // special case
+            if (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;
+        }
+
+        public static string TranslateLocalPathToRemote(string localPath, string localRoot, string remoteRoot)
+        {
+            if (localPath == null)
+            {
+                throw new ArgumentNullException("localPath");
+            }
+
+            if (localRoot == null)
+            {
+                throw new ArgumentNullException("localRoot");
+            }
+
+            if (remoteRoot == null)
+            {
+                throw new ArgumentNullException("remoteRoot");
+            }
+
+            if ((localRoot.Length > 0) && !localRoot.EndsWith("\\", StringComparison.Ordinal))
+            {
+                localRoot += "\\";
+            }
+
+            // not adding to empty root paths, because the path may not even start with slash
+            if ((remoteRoot.Length > 0) && !remoteRoot.EndsWith("/", StringComparison.Ordinal))
+            {
+                remoteRoot += "/";
+            }
+
+            string remotePath;
+            // special case
+            if (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", "path");
+            }
+            else
+            {
+                int i = path.LastIndexOf('/');
+                if (i < 0)
+                {
+                    result = null;
+                }
+                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", "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 = string.Empty;
+                }
+            }
+            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("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(); }
+        }
+    }
+}

+ 10 - 209
dotnet/Session.cs

@@ -548,7 +548,7 @@ namespace WinSCP
 
                         if (fileInfo.IsDirectory && allDirectories)
                         {
-                            foreach (RemoteFileInfo fileInfo2 in DoEnumerateRemoteFiles(CombinePaths(path, fileInfo.Name), regex, options, false))
+                            foreach (RemoteFileInfo fileInfo2 in DoEnumerateRemoteFiles(RemotePath.CombinePaths(path, fileInfo.Name), regex, options, false))
                             {
                                 yield return fileInfo2;
                             }
@@ -1052,7 +1052,7 @@ namespace WinSCP
             {
                 CheckOpened();
 
-                string sourceArgument = Tools.ArgumentEscape(EscapeFileMask(sourcePath));
+                string sourceArgument = Tools.ArgumentEscape(RemotePath.EscapeFileMask(sourcePath));
                 string targetArgument = Tools.ArgumentEscape(targetPath);
                 string command = string.Format(CultureInfo.InvariantCulture, "cp \"{0}\" \"{1}\"", sourceArgument, targetArgument);
                 WriteCommand(command);
@@ -1075,227 +1075,28 @@ namespace WinSCP
             }
         }
 
-        // This is not static method only to make it visible to COM
+        [Obsolete("Use RemotePath.EscapeFileMask")]
         public string EscapeFileMask(string fileMask)
         {
-            if (fileMask == null)
-            {
-                throw Logger.WriteException(new ArgumentNullException("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("?", "[?]");
-            return path + mask;
+            return RemotePath.EscapeFileMask(fileMask);
         }
 
+        [Obsolete("Use RemotePath.TranslateRemotePathToLocal")]
         public string TranslateRemotePathToLocal(string remotePath, string remoteRoot, string localRoot)
         {
-            if (remotePath == null)
-            {
-                throw Logger.WriteException(new ArgumentNullException("remotePath"));
-            }
-
-            if (remoteRoot == null)
-            {
-                throw Logger.WriteException(new ArgumentNullException("remoteRoot"));
-            }
-
-            if (localRoot == null)
-            {
-                throw Logger.WriteException(new ArgumentNullException("localRoot"));
-            }
-
-            if ((localRoot.Length > 0) && !localRoot.EndsWith("\\", StringComparison.Ordinal))
-            {
-                localRoot += "\\";
-            }
-
-            // not adding to empty root paths, because the path may not even start with slash
-            if ((remoteRoot.Length > 0) && !remoteRoot.EndsWith("/", StringComparison.Ordinal))
-            {
-                remoteRoot += "/";
-            }
-
-            string localPath;
-            // special case
-            if (remotePath == remoteRoot)
-            {
-                localPath = localRoot;
-            }
-            else
-            {
-                if (!remotePath.StartsWith(remoteRoot, StringComparison.Ordinal))
-                {
-                    throw Logger.WriteException(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;
+            return RemotePath.TranslateRemotePathToLocal(remotePath, remoteRoot, localRoot);
         }
 
+        [Obsolete("Use RemotePath.TranslateLocalPathToRemote")]
         public string TranslateLocalPathToRemote(string localPath, string localRoot, string remoteRoot)
         {
-            if (localPath == null)
-            {
-                throw Logger.WriteException(new ArgumentNullException("localPath"));
-            }
-
-            if (localRoot == null)
-            {
-                throw Logger.WriteException(new ArgumentNullException("localRoot"));
-            }
-
-            if (remoteRoot == null)
-            {
-                throw Logger.WriteException(new ArgumentNullException("remoteRoot"));
-            }
-
-            if ((localRoot.Length > 0) && !localRoot.EndsWith("\\", StringComparison.Ordinal))
-            {
-                localRoot += "\\";
-            }
-
-            // not adding to empty root paths, because the path may not even start with slash
-            if ((remoteRoot.Length > 0) && !remoteRoot.EndsWith("/", StringComparison.Ordinal))
-            {
-                remoteRoot += "/";
-            }
-
-            string remotePath;
-            // special case
-            if (localPath == localRoot)
-            {
-                remotePath = remoteRoot;
-            }
-            else
-            {
-                if (!localPath.StartsWith(localRoot, StringComparison.Ordinal))
-                {
-                    throw Logger.WriteException(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;
+            return RemotePath.TranslateLocalPathToRemote(localPath, localRoot, remoteRoot);
         }
 
+        [Obsolete("Use RemotePath.CombinePaths")]
         public string CombinePaths(string path1, string path2)
         {
-            if (path1 == null)
-            {
-                throw Logger.WriteException(new ArgumentNullException("path1"));
-            }
-
-            if (path2 == null)
-            {
-                throw Logger.WriteException(new ArgumentNullException("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 string GetDirectoryName(string path)
-        {
-            string result;
-            if (path == null)
-            {
-                result = null;
-            }
-            else if (path.Length == 0)
-            {
-                throw Logger.WriteException(new ArgumentException("Path cannot be empty", "path"));
-            }
-            else
-            {
-                int i = path.LastIndexOf('/');
-                if (i < 0)
-                {
-                    result = null;
-                }
-                else if (i == 0)
-                {
-                    if (path.Length == 1)
-                    {
-                        result = null;
-                    }
-                    else
-                    {
-                        result = "/";
-                    }
-                }
-                else
-                {
-                    result = path.Substring(0, i);
-                }
-            }
-            return result;
-        }
-
-        public string AddDirectorySeparator(string path)
-        {
-            if (string.IsNullOrEmpty(path))
-            {
-                throw Logger.WriteException(new ArgumentException("Path cannot be empty", "path"));
-            }
-
-            if (!path.EndsWith("/", StringComparison.Ordinal))
-            {
-                path += "/";
-            }
-
-            return path;
-        }
-
-        public 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 = string.Empty;
-                }
-            }
-            return result;
+            return RemotePath.CombinePaths(path1, path2);
         }
 
         public void AddRawConfiguration(string setting, string value)

+ 1 - 0
dotnet/WinSCPnet.csproj

@@ -83,6 +83,7 @@
     <Compile Include="InteropCollections\SessionRemoteExceptionCollection.cs" />
     <Compile Include="InteropCollections\StringCollection.cs" />
     <Compile Include="InteropCollections\TransferEventArgsCollection.cs" />
+    <Compile Include="RemotePath.cs" />
     <Compile Include="RemovalEventArgs.cs" />
     <Compile Include="RemovalOperationResult.cs" />
     <Compile Include="SessionEvents.cs" />