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

Util.cs 5.8 kB

10 years ago
10 years ago
10 years ago
10 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. using System;
  2. using System.Diagnostics;
  3. using System.IO;
  4. using System.IO.Compression;
  5. using System.Runtime.InteropServices;
  6. using System.Windows.Forms;
  7. using Shadowsocks.Controller;
  8. namespace Shadowsocks.Util
  9. {
  10. public class Utils
  11. {
  12. private static string TempPath = null;
  13. // return path to store temporary files
  14. public static string GetTempPath()
  15. {
  16. if (TempPath == null)
  17. {
  18. if (File.Exists(Path.Combine(Application.StartupPath, "shadowsocks_portable_mode.txt")))
  19. try
  20. {
  21. Directory.CreateDirectory(Path.Combine(Application.StartupPath, "temp"));
  22. }
  23. catch (Exception e)
  24. {
  25. TempPath = Path.GetTempPath();
  26. Logging.LogUsefulException(e);
  27. }
  28. finally
  29. {
  30. // don't use "/", it will fail when we call explorer /select xxx/temp\xxx.log
  31. TempPath = Path.Combine(Application.StartupPath, "temp");
  32. }
  33. else
  34. TempPath = Path.GetTempPath();
  35. }
  36. return TempPath;
  37. }
  38. // return a full path with filename combined which pointed to the temporary directory
  39. public static string GetTempPath(string filename)
  40. {
  41. return Path.Combine(GetTempPath(), filename);
  42. }
  43. public static void ReleaseMemory(bool removePages)
  44. {
  45. // release any unused pages
  46. // making the numbers look good in task manager
  47. // this is totally nonsense in programming
  48. // but good for those users who care
  49. // making them happier with their everyday life
  50. // which is part of user experience
  51. GC.Collect(GC.MaxGeneration);
  52. GC.WaitForPendingFinalizers();
  53. if (removePages)
  54. {
  55. // as some users have pointed out
  56. // removing pages from working set will cause some IO
  57. // which lowered user experience for another group of users
  58. //
  59. // so we do 2 more things here to satisfy them:
  60. // 1. only remove pages once when configuration is changed
  61. // 2. add more comments here to tell users that calling
  62. // this function will not be more frequent than
  63. // IM apps writing chat logs, or web browsers writing cache files
  64. // if they're so concerned about their disk, they should
  65. // uninstall all IM apps and web browsers
  66. //
  67. // please open an issue if you're worried about anything else in your computer
  68. // no matter it's GPU performance, monitor contrast, audio fidelity
  69. // or anything else in the task manager
  70. // we'll do as much as we can to help you
  71. //
  72. // just kidding
  73. SetProcessWorkingSetSize(Process.GetCurrentProcess().Handle,
  74. (UIntPtr)0xFFFFFFFF,
  75. (UIntPtr)0xFFFFFFFF);
  76. }
  77. }
  78. public static string UnGzip(byte[] buf)
  79. {
  80. byte[] buffer = new byte[1024];
  81. int n;
  82. using (MemoryStream sb = new MemoryStream())
  83. {
  84. using (GZipStream input = new GZipStream(new MemoryStream(buf),
  85. CompressionMode.Decompress,
  86. false))
  87. {
  88. while ((n = input.Read(buffer, 0, buffer.Length)) > 0)
  89. {
  90. sb.Write(buffer, 0, n);
  91. }
  92. }
  93. return System.Text.Encoding.UTF8.GetString(sb.ToArray());
  94. }
  95. }
  96. public static string FormatBandwidth(long n)
  97. {
  98. var result = GetBandwidthScale(n);
  99. return $"{result.Item1:0.##}{result.Item2}";
  100. }
  101. /// <summary>
  102. /// Return scaled bandwidth
  103. /// </summary>
  104. /// <param name="n">Raw bandwidth</param>
  105. /// <returns>
  106. /// Item1: float, bandwidth with suitable scale (eg. 56)
  107. /// Item2: string, scale unit name (eg. KiB)
  108. /// Item3: long, scale unit (eg. 1024)
  109. /// </returns>
  110. public static Tuple<float, string, long> GetBandwidthScale(long n)
  111. {
  112. long scale = 1;
  113. float f = n;
  114. string unit = "B";
  115. if (f > 1024)
  116. {
  117. f = f / 1024;
  118. scale <<= 10;
  119. unit = "KiB";
  120. }
  121. if (f > 1024)
  122. {
  123. f = f / 1024;
  124. scale <<= 10;
  125. unit = "MiB";
  126. }
  127. if (f > 1024)
  128. {
  129. f = f / 1024;
  130. scale <<= 10;
  131. unit = "GiB";
  132. }
  133. if (f > 1024)
  134. {
  135. f = f / 1024;
  136. scale <<= 10;
  137. unit = "TiB";
  138. }
  139. return new Tuple<float, string, long>(f, unit, scale);
  140. }
  141. [DllImport("kernel32.dll")]
  142. [return: MarshalAs(UnmanagedType.Bool)]
  143. private static extern bool SetProcessWorkingSetSize(IntPtr process,
  144. UIntPtr minimumWorkingSetSize, UIntPtr maximumWorkingSetSize);
  145. }
  146. }