GetChecksum.cs 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Text;
  4. namespace System.Net.FtpClient.Extensions {
  5. /// <summary>
  6. /// Retrieve checksum of file on the server
  7. /// </summary>
  8. public static class ChecksumExtension {
  9. delegate FtpHash AsyncGetChecksum(string path);
  10. static Dictionary<IAsyncResult, AsyncGetChecksum> m_asyncmethods = new Dictionary<IAsyncResult, AsyncGetChecksum>();
  11. /// <summary>
  12. /// Retrieves a checksum of the given file using a checksumming method
  13. /// that the server supports, if any. The algorithm used goes in this order:
  14. /// 1. HASH command; server preferred algorithm. See FtpClient.SetHashAlgorithm()
  15. /// 2. MD5 / XMD5 commands
  16. /// 3. XSHA1 command
  17. /// 4. XSHA256 command
  18. /// 5. XSHA512 command
  19. /// 6. XCRC command
  20. /// </summary>
  21. /// <param name="client">FtpClient Object</param>
  22. /// <param name="path">Full or relative path of the file to checksum</param>
  23. /// <returns>FtpHash object containing the value and algorithm. Use the IsValid property to
  24. /// determine if this command was successfull. FtpCommandException's can be thrown from
  25. /// the underlying calls.</returns>
  26. /// <example><code source="..\Examples\GetChecksum.cs" lang="cs" /></example>
  27. public static FtpHash GetChecksum(this FtpClient client, string path) {
  28. if (client.HasFeature(FtpCapability.HASH)) {
  29. return client.GetHash(path);
  30. }
  31. else {
  32. FtpHash res = new FtpHash();
  33. if (client.HasFeature(FtpCapability.MD5)) {
  34. res.Value = client.GetMD5(path);
  35. res.Algorithm = FtpHashAlgorithm.MD5;
  36. }
  37. else if (client.HasFeature(FtpCapability.XMD5)) {
  38. res.Value = client.GetXMD5(path);
  39. res.Algorithm = FtpHashAlgorithm.MD5;
  40. }
  41. else if (client.HasFeature(FtpCapability.XSHA1)) {
  42. res.Value = client.GetXSHA1(path);
  43. res.Algorithm = FtpHashAlgorithm.SHA1;
  44. }
  45. else if (client.HasFeature(FtpCapability.XSHA256)) {
  46. res.Value = client.GetXSHA256(path);
  47. res.Algorithm = FtpHashAlgorithm.SHA256;
  48. }
  49. else if (client.HasFeature(FtpCapability.XSHA512)) {
  50. res.Value = client.GetXSHA512(path);
  51. res.Algorithm = FtpHashAlgorithm.SHA512;
  52. }
  53. else if (client.HasFeature(FtpCapability.XCRC)) {
  54. res.Value = client.GetXCRC(path);
  55. res.Algorithm = FtpHashAlgorithm.CRC;
  56. }
  57. return res;
  58. }
  59. }
  60. /// <summary>
  61. /// Asynchronusly retrieve a checksum of the specified file. This feature
  62. /// is non-standard.
  63. /// </summary>
  64. /// <param name="client">FtpClient Object</param>
  65. /// <param name="path">Full or relative path to remote file</param>
  66. /// <param name="callback">AsyncCallback</param>
  67. /// <param name="state">State Object</param>
  68. /// <returns>IAsyncResult</returns>
  69. public static IAsyncResult BeginGetChecksum(this FtpClient client, string path, AsyncCallback callback, object state) {
  70. AsyncGetChecksum func = new AsyncGetChecksum(client.GetChecksum);
  71. IAsyncResult ar = func.BeginInvoke(path, callback, state); ;
  72. lock (m_asyncmethods) {
  73. m_asyncmethods.Add(ar, func);
  74. }
  75. return ar;
  76. }
  77. /// <summary>
  78. /// Ends an asynchronous call to BeginGetChecksum()
  79. /// </summary>
  80. /// <param name="ar">IAsyncResult returned from BeginGetChecksum()</param>
  81. /// <returns>FtpHash object containing the value and algorithm. Use the IsValid property to
  82. /// determine if this command was successfull. FtpCommandException's can be thrown from
  83. /// the underlying calls.</returns>
  84. public static FtpHash EndGetChecksum(IAsyncResult ar) {
  85. AsyncGetChecksum func = null;
  86. lock (m_asyncmethods) {
  87. if (!m_asyncmethods.ContainsKey(ar))
  88. throw new InvalidOperationException("The specified IAsyncResult was not found in the collection.");
  89. func = m_asyncmethods[ar];
  90. m_asyncmethods.Remove(ar);
  91. }
  92. return func.EndInvoke(ar);
  93. }
  94. }
  95. }