URLUtils.cs 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280
  1. using System;
  2. using System.Text;
  3. namespace prBrowser
  4. {
  5. internal static class URLUtils
  6. {
  7. private class UrlDecoder
  8. {
  9. private int _bufferSize;
  10. private byte[] _byteBuffer;
  11. private char[] _charBuffer;
  12. private Encoding _encoding;
  13. private int _numBytes;
  14. private int _numChars;
  15. public bool forFilePaths = false;
  16. internal UrlDecoder(int bufferSize, Encoding encoding)
  17. {
  18. _bufferSize = bufferSize;
  19. _encoding = encoding;
  20. _charBuffer = new char[bufferSize];
  21. }
  22. internal void AddByte(byte b)
  23. {
  24. if (_byteBuffer == null)
  25. {
  26. _byteBuffer = new byte[_bufferSize];
  27. }
  28. _byteBuffer[_numBytes++] = b;
  29. }
  30. internal void AddChar(char ch, bool checkChar = false)
  31. {
  32. if (_numBytes > 0)
  33. {
  34. FlushBytes();
  35. }
  36. if (checkChar && forFilePaths && !ch.SupportedInFilePath())
  37. {
  38. AddChar('_');
  39. int num = ch;
  40. AddString("0x" + num.ToString("X"));
  41. AddChar('_');
  42. }
  43. else
  44. {
  45. _charBuffer[_numChars++] = ch;
  46. }
  47. }
  48. internal void AddString(string str)
  49. {
  50. if (_numBytes > 0)
  51. {
  52. FlushBytes();
  53. }
  54. foreach (char ch in str)
  55. {
  56. _charBuffer[_numChars++] = ch;
  57. }
  58. }
  59. public void FlushBytes(bool checkChar = false)
  60. {
  61. if (_numBytes <= 0)
  62. {
  63. return;
  64. }
  65. if (checkChar && forFilePaths)
  66. {
  67. char[] newChars = _encoding.GetChars(_byteBuffer, 0, _numBytes);
  68. _numBytes = 0;
  69. char[] array = newChars;
  70. foreach (char ch in array)
  71. {
  72. AddChar(ch);
  73. }
  74. }
  75. else
  76. {
  77. _numChars += _encoding.GetChars(_byteBuffer, 0, _numBytes, _charBuffer, _numChars);
  78. _numBytes = 0;
  79. }
  80. }
  81. internal string GetString()
  82. {
  83. if (_numBytes > 0)
  84. {
  85. FlushBytes();
  86. }
  87. if (_numChars > 0)
  88. {
  89. return new string(_charBuffer, 0, _numChars);
  90. }
  91. return string.Empty;
  92. }
  93. }
  94. public static string PathToURL(this string filePath, string removeBaseDir = null)
  95. {
  96. if (!filePath.CheckIfValid())
  97. {
  98. return "";
  99. }
  100. return "file:///" + filePath.Replace("\\", "/");
  101. }
  102. public static bool IsURLOfflineFile(this string url)
  103. {
  104. return url.StartsWith("file://", StringComparison.Ordinal);
  105. }
  106. public static bool IsURLLocalhost(this string url)
  107. {
  108. return url.BeginsWith("http://localhost") || url.BeginsWith("localhost");
  109. }
  110. public static string DecodeURL(this string url)
  111. {
  112. if (url == null)
  113. {
  114. return null;
  115. }
  116. int length = url.Length;
  117. UrlDecoder decoder = new UrlDecoder(length, Encoding.UTF8);
  118. for (int i = 0; i < length; i++)
  119. {
  120. char ch = url[i];
  121. if (ch == '+')
  122. {
  123. ch = ' ';
  124. }
  125. else if (ch == '%' && i < length - 2)
  126. {
  127. if (url[i + 1] == 'u' && i < length - 5)
  128. {
  129. int num3 = url[i + 2].HexToInt();
  130. int num4 = url[i + 3].HexToInt();
  131. int num5 = url[i + 4].HexToInt();
  132. int num6 = url[i + 5].HexToInt();
  133. if (num3 >= 0 && num4 >= 0 && num5 >= 0 && num6 >= 0)
  134. {
  135. ch = (char)((num3 << 12) | (num4 << 8) | (num5 << 4) | num6);
  136. i += 5;
  137. decoder.AddChar(ch);
  138. continue;
  139. }
  140. }
  141. else
  142. {
  143. int num7 = url[i + 1].HexToInt();
  144. int num8 = url[i + 2].HexToInt();
  145. if (num7 >= 0 && num8 >= 0)
  146. {
  147. byte b = (byte)((num7 << 4) | num8);
  148. i += 2;
  149. decoder.AddByte(b);
  150. continue;
  151. }
  152. }
  153. }
  154. if ((ch & 0xFF80) == 0)
  155. {
  156. decoder.AddByte((byte)ch);
  157. }
  158. else
  159. {
  160. decoder.AddChar(ch);
  161. }
  162. }
  163. return decoder.GetString();
  164. }
  165. public static int HexToInt(this char hex)
  166. {
  167. if (hex >= '0' && hex <= '9')
  168. {
  169. return hex - 48;
  170. }
  171. if (hex >= 'a' && hex <= 'f')
  172. {
  173. return hex - 97 + 10;
  174. }
  175. if (hex >= 'A' && hex <= 'F')
  176. {
  177. return hex - 65 + 10;
  178. }
  179. return -1;
  180. }
  181. public static string DecodeURLForFilepath(this string url)
  182. {
  183. if (url == null)
  184. {
  185. return null;
  186. }
  187. int length = url.Length;
  188. UrlDecoder decoder = new UrlDecoder(length * 10, Encoding.UTF8);
  189. decoder.forFilePaths = true;
  190. for (int i = 0; i < length; i++)
  191. {
  192. char ch = url[i];
  193. if (ch == '+')
  194. {
  195. ch = ' ';
  196. }
  197. else if (ch == '%' && i < length - 2)
  198. {
  199. if (url[i + 1] == 'u' && i < length - 5)
  200. {
  201. int num3 = url[i + 2].HexToInt();
  202. int num4 = url[i + 3].HexToInt();
  203. int num5 = url[i + 4].HexToInt();
  204. int num6 = url[i + 5].HexToInt();
  205. if (num3 >= 0 && num4 >= 0 && num5 >= 0 && num6 >= 0)
  206. {
  207. ch = (char)((num3 << 12) | (num4 << 8) | (num5 << 4) | num6);
  208. i += 5;
  209. decoder.FlushBytes();
  210. decoder.AddChar(ch, checkChar: true);
  211. continue;
  212. }
  213. }
  214. else
  215. {
  216. int num7 = url[i + 1].HexToInt();
  217. int num8 = url[i + 2].HexToInt();
  218. if (num7 >= 0 && num8 >= 0)
  219. {
  220. byte b = (byte)((num7 << 4) | num8);
  221. i += 2;
  222. decoder.FlushBytes();
  223. decoder.AddByte(b);
  224. if (i + 1 < length - 2 && url[i + 1] == '%')
  225. {
  226. num7 = url[i + 1].HexToInt();
  227. num8 = url[i + 2].HexToInt();
  228. if (num7 >= 0 && num8 >= 0)
  229. {
  230. b = (byte)((num7 << 4) | num8);
  231. i += 2;
  232. decoder.AddByte(b);
  233. decoder.FlushBytes(checkChar: true);
  234. }
  235. }
  236. else
  237. {
  238. decoder.FlushBytes(checkChar: true);
  239. }
  240. continue;
  241. }
  242. }
  243. }
  244. if ((ch & 0xFF80) == 0)
  245. {
  246. decoder.AddByte((byte)ch);
  247. }
  248. else
  249. {
  250. decoder.AddChar(ch);
  251. }
  252. }
  253. return decoder.GetString();
  254. }
  255. public static string EncodeURL(this string text)
  256. {
  257. return Uri.EscapeDataString(text);
  258. }
  259. }
  260. }