You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

172 lines
5.9 KiB

  1. //----------------------------------------------------------------------------
  2. // Copyright (C) 2004-2021 by EMGU Corporation. All rights reserved.
  3. //----------------------------------------------------------------------------
  4. using System;
  5. using System.Collections.Generic;
  6. using System.Text;
  7. using System.IO;
  8. using System.Diagnostics;
  9. using System.Runtime.InteropServices;
  10. using System.Security.Cryptography;
  11. namespace Emgu.Util
  12. {
  13. /// <summary>
  14. /// This represent a file that can be downloaded from the internet
  15. /// </summary>
  16. public class DownloadableFile
  17. {
  18. private String _url;
  19. private String _localSubfolder;
  20. private String _sha256Hash;
  21. private String _localFile = null;
  22. /// <summary>
  23. /// Create a downloadable file from the url
  24. /// </summary>
  25. /// <param name="url">The url where the file can be downloaded from</param>
  26. /// <param name="localSubfolder">The sub-folder to store the model</param>
  27. /// <param name="sha256Hash">The SHA256 has for the file.</param>
  28. public DownloadableFile(String url, String localSubfolder, String sha256Hash = null)
  29. {
  30. _url = url;
  31. _localSubfolder = localSubfolder;
  32. if (sha256Hash != null)
  33. _sha256Hash = sha256Hash.ToUpper();
  34. else
  35. {
  36. _sha256Hash = null;
  37. }
  38. }
  39. /// <summary>
  40. /// The url where this file can be downloaded from
  41. /// </summary>
  42. public String Url
  43. {
  44. get { return _url; }
  45. }
  46. private static String ByteArrayToString(byte[] array)
  47. {
  48. StringBuilder sb = new StringBuilder();
  49. for (int i = 0; i < array.Length; i++)
  50. {
  51. sb.Append($"{array[i]:X2}");
  52. }
  53. return sb.ToString();
  54. }
  55. /// <summary>
  56. /// Return true if the local file exist and match the sha256hash (if specified in the constructor).
  57. /// </summary>
  58. public bool IsLocalFileValid
  59. {
  60. get
  61. {
  62. String localFile = LocalFile;
  63. if (!File.Exists(localFile))
  64. return false;
  65. FileInfo fi = new FileInfo(localFile);
  66. if (fi.Length == 0)
  67. return false;
  68. if (_sha256Hash != null)
  69. {
  70. using (SHA256 sha256 = SHA256.Create())
  71. {
  72. try
  73. {
  74. // Create a fileStream for the file.
  75. using (FileStream fileStream = fi.Open(FileMode.Open))
  76. {
  77. // Be sure it's positioned to the beginning of the stream.
  78. fileStream.Position = 0;
  79. // Compute the hash of the fileStream.
  80. byte[] hashValue = sha256.ComputeHash(fileStream);
  81. String hashStr = ByteArrayToString(hashValue);
  82. if (hashStr != _sha256Hash)
  83. {
  84. Trace.WriteLine(String.Format("{0}: expecting SHA256 of \"{1}\", got \"{2}\"", localFile, _sha256Hash, hashStr));
  85. return false;
  86. }
  87. }
  88. }
  89. catch (IOException e)
  90. {
  91. Trace.WriteLine($"I/O Exception: {e.Message}");
  92. return false;
  93. }
  94. catch (UnauthorizedAccessException e)
  95. {
  96. Trace.WriteLine($"Access Exception: {e.Message}");
  97. return false;
  98. }
  99. }
  100. }
  101. return true;
  102. }
  103. }
  104. /// <summary>
  105. /// The local file name
  106. /// </summary>
  107. public String LocalFile
  108. {
  109. get
  110. {
  111. if (_localFile != null)
  112. return _localFile;
  113. else if (Url == null)
  114. return null;
  115. else
  116. {
  117. Uri uri = new Uri(Url);
  118. string fileName = System.IO.Path.GetFileName(uri.LocalPath);
  119. return GetLocalFileName(fileName);
  120. }
  121. }
  122. set
  123. {
  124. _localFile = value;
  125. }
  126. }
  127. /// <summary>
  128. /// Return the directory where the local file is
  129. /// </summary>
  130. public String LocalFolder
  131. {
  132. get
  133. {
  134. String localFile = LocalFile;
  135. System.IO.FileInfo fi = new FileInfo(localFile);
  136. return fi.DirectoryName;
  137. }
  138. }
  139. /// <summary>
  140. /// The local path to the local file given the file name
  141. /// </summary>
  142. /// <param name="fileName">The name of the file</param>
  143. /// <returns>The local path of the file</returns>
  144. public String GetLocalFileName(String fileName)
  145. {
  146. #if UNITY_EDITOR || UNITY_IOS || UNITY_ANDROID || UNITY_STANDALONE || UNITY_WEBGL
  147. return System.IO.Path.Combine(UnityEngine.Application.persistentDataPath, _localSubfolder, fileName);
  148. #else
  149. //String personalFolder = Environment.GetFolderPath(Environment.SpecialFolder.Personal);
  150. //String appDataFolder = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
  151. String appDataFolder = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);
  152. return Path.Combine(appDataFolder, _localSubfolder, fileName);
  153. #endif
  154. }
  155. }
  156. }