1
0

ComparisonDifference.cs 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206
  1. using System;
  2. using System.IO;
  3. using System.Runtime.InteropServices;
  4. namespace WinSCP
  5. {
  6. [Guid("B1DAE3A0-5E56-4001-88D8-786F68557E28")]
  7. [ComVisible(true)]
  8. public enum SynchronizationAction
  9. {
  10. UploadNew = 1,
  11. DownloadNew = 2,
  12. UploadUpdate = 3,
  13. DownloadUpdate = 4,
  14. DeleteRemote = 5,
  15. DeleteLocal = 6,
  16. };
  17. [Guid("2D6EFFB5-69BA-47AA-90E8-A92953E8B58A")]
  18. [ComVisible(true)]
  19. public sealed class ComparisonFileInfo
  20. {
  21. public string FileName { get; internal set; }
  22. public DateTime LastWriteTime { get; internal set; }
  23. public long Length { get; internal set; }
  24. public int Length32 { get { return GetLength32(); } }
  25. internal ComparisonFileInfo()
  26. {
  27. }
  28. private int GetLength32()
  29. {
  30. return Tools.LengthTo32Bit(Length);
  31. }
  32. }
  33. [Guid("97F5222E-9379-4C24-9E50-E93C7334BBD5")]
  34. [ClassInterface(Constants.ClassInterface)]
  35. [ComVisible(true)]
  36. public sealed class ComparisonDifference
  37. {
  38. public SynchronizationAction Action { get; internal set; }
  39. public bool IsDirectory { get; internal set; }
  40. public ComparisonFileInfo Local { get; internal set; }
  41. public ComparisonFileInfo Remote { get; internal set; }
  42. internal ComparisonDifference(string localPath, string remotePath)
  43. {
  44. _localPath = localPath;
  45. _remotePath = remotePath;
  46. }
  47. public override string ToString()
  48. {
  49. string buf;
  50. switch (Action)
  51. {
  52. case SynchronizationAction.UploadNew:
  53. buf = RemotePath.Combine(TranslateLocalPathToRemote(), "*");
  54. return $"{GetLocalPathString()} ==> {buf}";
  55. case SynchronizationAction.DownloadNew:
  56. buf = Path.Combine(TranslateRemotePathToLocal(), "*");
  57. return $"{buf} <== {GetRemotePathString()}";
  58. case SynchronizationAction.UploadUpdate:
  59. return $"{GetLocalPathString()} ==> {GetRemotePathString()}";
  60. case SynchronizationAction.DownloadUpdate:
  61. return $"{GetLocalPathString()} <== {GetRemotePathString()}";
  62. case SynchronizationAction.DeleteRemote:
  63. return $"× {GetRemotePathString()}";
  64. case SynchronizationAction.DeleteLocal:
  65. return $"× {GetLocalPathString()}";
  66. default:
  67. throw new InvalidOperationException();
  68. }
  69. }
  70. private string TranslateRemotePathToLocal()
  71. {
  72. return RemotePath.TranslateRemotePathToLocal(RemotePath.GetDirectoryName(Remote.FileName), _remotePath, _localPath);
  73. }
  74. private string TranslateLocalPathToRemote()
  75. {
  76. return RemotePath.TranslateLocalPathToRemote(Path.GetDirectoryName(Local.FileName), _localPath, _remotePath);
  77. }
  78. private string GetRemotePathString()
  79. {
  80. return Remote.FileName + (IsDirectory ? "/" : string.Empty);
  81. }
  82. private string GetLocalPathString()
  83. {
  84. return Local.FileName + (IsDirectory ? "\\" : string.Empty);
  85. }
  86. public FileOperationEventArgs Resolve(Session session, TransferOptions options = null)
  87. {
  88. if (session == null)
  89. {
  90. throw new ArgumentNullException(nameof(session));
  91. }
  92. switch (Action)
  93. {
  94. case SynchronizationAction.UploadNew:
  95. case SynchronizationAction.UploadUpdate:
  96. {
  97. string remoteDirectory = TranslateLocalPathToRemote();
  98. if (!IsDirectory)
  99. {
  100. return session.PutFileToDirectory(Local.FileName, remoteDirectory, options: options);
  101. }
  102. else
  103. {
  104. session.PutEntryToDirectory(Local.FileName, remoteDirectory, options: options);
  105. return null;
  106. }
  107. }
  108. case SynchronizationAction.DownloadNew:
  109. case SynchronizationAction.DownloadUpdate:
  110. {
  111. string localDirectory = TranslateRemotePathToLocal();
  112. if (!IsDirectory)
  113. {
  114. return session.GetFileToDirectory(Remote.FileName, localDirectory, options: options);
  115. }
  116. else
  117. {
  118. session.GetEntryToDirectory(Remote.FileName, localDirectory, options: options);
  119. return null;
  120. }
  121. }
  122. case SynchronizationAction.DeleteRemote:
  123. if (!IsDirectory)
  124. {
  125. return session.RemoveFile(Remote.FileName);
  126. }
  127. else
  128. {
  129. session.RemoveEntry(Remote.FileName);
  130. return null;
  131. }
  132. case SynchronizationAction.DeleteLocal:
  133. if (!IsDirectory)
  134. {
  135. File.Delete(Local.FileName);
  136. }
  137. else
  138. {
  139. Directory.Delete(Local.FileName, true);
  140. }
  141. return null;
  142. default:
  143. throw session.Logger.WriteException(new InvalidOperationException());
  144. }
  145. }
  146. public void Reverse()
  147. {
  148. switch (Action)
  149. {
  150. case SynchronizationAction.UploadNew:
  151. Action = SynchronizationAction.DeleteLocal;
  152. break;
  153. case SynchronizationAction.DownloadNew:
  154. Action = SynchronizationAction.DeleteRemote;
  155. break;
  156. case SynchronizationAction.UploadUpdate:
  157. Action = SynchronizationAction.DownloadUpdate;
  158. break;
  159. case SynchronizationAction.DownloadUpdate:
  160. Action = SynchronizationAction.UploadUpdate;
  161. break;
  162. case SynchronizationAction.DeleteRemote:
  163. Action = SynchronizationAction.DownloadNew;
  164. break;
  165. case SynchronizationAction.DeleteLocal:
  166. Action = SynchronizationAction.UploadNew;
  167. break;
  168. default:
  169. throw new InvalidOperationException();
  170. }
  171. }
  172. private readonly string _localPath;
  173. private readonly string _remotePath;
  174. }
  175. }