mirror of
https://github.com/winscp/winscp.git
synced 2026-10-24 02:28:55 +03:00
(cherry picked from commit 5adbaa9381)
Source commit: 77080c12e6408ba75067272b538d01fc08990ce4
207 lines
7.0 KiB
C#
207 lines
7.0 KiB
C#
using System;
|
||
using System.IO;
|
||
using System.Runtime.InteropServices;
|
||
|
||
namespace WinSCP
|
||
{
|
||
[Guid("B1DAE3A0-5E56-4001-88D8-786F68557E28")]
|
||
[ComVisible(true)]
|
||
public enum SynchronizationAction
|
||
{
|
||
UploadNew = 1,
|
||
DownloadNew = 2,
|
||
UploadUpdate = 3,
|
||
DownloadUpdate = 4,
|
||
DeleteRemote = 5,
|
||
DeleteLocal = 6,
|
||
};
|
||
|
||
[Guid("2D6EFFB5-69BA-47AA-90E8-A92953E8B58A")]
|
||
[ComVisible(true)]
|
||
public sealed class ComparisonFileInfo
|
||
{
|
||
public string FileName { get; internal set; }
|
||
public DateTime LastWriteTime { get; internal set; }
|
||
public long Length { get; internal set; }
|
||
public int Length32 { get { return GetLength32(); } }
|
||
|
||
internal ComparisonFileInfo()
|
||
{
|
||
}
|
||
|
||
private int GetLength32()
|
||
{
|
||
return Tools.LengthTo32Bit(Length);
|
||
}
|
||
}
|
||
|
||
[Guid("97F5222E-9379-4C24-9E50-E93C7334BBD5")]
|
||
[ClassInterface(Constants.ClassInterface)]
|
||
[ComVisible(true)]
|
||
public sealed class ComparisonDifference
|
||
{
|
||
public SynchronizationAction Action { get; internal set; }
|
||
public bool IsDirectory { get; internal set; }
|
||
public ComparisonFileInfo Local { get; internal set; }
|
||
public ComparisonFileInfo Remote { get; internal set; }
|
||
|
||
internal ComparisonDifference(string localPath, string remotePath)
|
||
{
|
||
_localPath = localPath;
|
||
_remotePath = remotePath;
|
||
}
|
||
|
||
public override string ToString()
|
||
{
|
||
string buf;
|
||
switch (Action)
|
||
{
|
||
case SynchronizationAction.UploadNew:
|
||
buf = RemotePath.Combine(TranslateLocalPathToRemote(), "*");
|
||
return $"{GetLocalPathString()} ==> {buf}";
|
||
|
||
case SynchronizationAction.DownloadNew:
|
||
buf = Path.Combine(TranslateRemotePathToLocal(), "*");
|
||
return $"{buf} <== {GetRemotePathString()}";
|
||
|
||
case SynchronizationAction.UploadUpdate:
|
||
return $"{GetLocalPathString()} ==> {GetRemotePathString()}";
|
||
|
||
case SynchronizationAction.DownloadUpdate:
|
||
return $"{GetLocalPathString()} <== {GetRemotePathString()}";
|
||
|
||
case SynchronizationAction.DeleteRemote:
|
||
return $"× {GetRemotePathString()}";
|
||
|
||
case SynchronizationAction.DeleteLocal:
|
||
return $"× {GetLocalPathString()}";
|
||
|
||
default:
|
||
throw new InvalidOperationException();
|
||
}
|
||
}
|
||
|
||
private string TranslateRemotePathToLocal()
|
||
{
|
||
return RemotePath.TranslateRemotePathToLocal(RemotePath.GetDirectoryName(Remote.FileName), _remotePath, _localPath);
|
||
}
|
||
|
||
private string TranslateLocalPathToRemote()
|
||
{
|
||
return RemotePath.TranslateLocalPathToRemote(Path.GetDirectoryName(Local.FileName), _localPath, _remotePath);
|
||
}
|
||
|
||
private string GetRemotePathString()
|
||
{
|
||
return Remote.FileName + (IsDirectory ? "/" : string.Empty);
|
||
}
|
||
|
||
private string GetLocalPathString()
|
||
{
|
||
return Local.FileName + (IsDirectory ? "\\" : string.Empty);
|
||
}
|
||
|
||
public FileOperationEventArgs Resolve(Session session, TransferOptions options = null)
|
||
{
|
||
if (session == null)
|
||
{
|
||
throw new ArgumentNullException(nameof(session));
|
||
}
|
||
|
||
switch (Action)
|
||
{
|
||
case SynchronizationAction.UploadNew:
|
||
case SynchronizationAction.UploadUpdate:
|
||
{
|
||
string remoteDirectory = TranslateLocalPathToRemote();
|
||
if (!IsDirectory)
|
||
{
|
||
return session.PutFileToDirectory(Local.FileName, remoteDirectory, options: options);
|
||
}
|
||
else
|
||
{
|
||
session.PutEntryToDirectory(Local.FileName, remoteDirectory, options: options);
|
||
return null;
|
||
}
|
||
}
|
||
|
||
case SynchronizationAction.DownloadNew:
|
||
case SynchronizationAction.DownloadUpdate:
|
||
{
|
||
string localDirectory = TranslateRemotePathToLocal();
|
||
if (!IsDirectory)
|
||
{
|
||
return session.GetFileToDirectory(Remote.FileName, localDirectory, options: options);
|
||
}
|
||
else
|
||
{
|
||
session.GetEntryToDirectory(Remote.FileName, localDirectory, options: options);
|
||
return null;
|
||
}
|
||
}
|
||
|
||
case SynchronizationAction.DeleteRemote:
|
||
if (!IsDirectory)
|
||
{
|
||
return session.RemoveFile(Remote.FileName);
|
||
}
|
||
else
|
||
{
|
||
session.RemoveEntry(Remote.FileName);
|
||
return null;
|
||
}
|
||
|
||
case SynchronizationAction.DeleteLocal:
|
||
if (!IsDirectory)
|
||
{
|
||
File.Delete(Local.FileName);
|
||
}
|
||
else
|
||
{
|
||
Directory.Delete(Local.FileName, true);
|
||
}
|
||
return null;
|
||
|
||
default:
|
||
throw session.Logger.WriteException(new InvalidOperationException());
|
||
}
|
||
}
|
||
|
||
public void Reverse()
|
||
{
|
||
switch (Action)
|
||
{
|
||
case SynchronizationAction.UploadNew:
|
||
Action = SynchronizationAction.DeleteLocal;
|
||
break;
|
||
|
||
case SynchronizationAction.DownloadNew:
|
||
Action = SynchronizationAction.DeleteRemote;
|
||
break;
|
||
|
||
case SynchronizationAction.UploadUpdate:
|
||
Action = SynchronizationAction.DownloadUpdate;
|
||
break;
|
||
|
||
case SynchronizationAction.DownloadUpdate:
|
||
Action = SynchronizationAction.UploadUpdate;
|
||
break;
|
||
|
||
case SynchronizationAction.DeleteRemote:
|
||
Action = SynchronizationAction.DownloadNew;
|
||
break;
|
||
|
||
case SynchronizationAction.DeleteLocal:
|
||
Action = SynchronizationAction.UploadNew;
|
||
break;
|
||
|
||
default:
|
||
throw new InvalidOperationException();
|
||
}
|
||
}
|
||
|
||
private readonly string _localPath;
|
||
private readonly string _remotePath;
|
||
}
|
||
}
|