HttpUtility.cs 38 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942
  1. using System;
  2. using System.Collections;
  3. using System.Collections.Generic;
  4. using System.Collections.Specialized;
  5. using System.Text;
  6. using MediaBrowser.Model.Services;
  7. namespace MediaBrowser.Server.Implementations.HttpServer.SocketSharp
  8. {
  9. public static class MyHttpUtility
  10. {
  11. sealed class HttpQSCollection : NameValueCollection
  12. {
  13. public override string ToString()
  14. {
  15. int count = Count;
  16. if (count == 0)
  17. return "";
  18. StringBuilder sb = new StringBuilder();
  19. string[] keys = AllKeys;
  20. for (int i = 0; i < count; i++)
  21. {
  22. sb.AppendFormat("{0}={1}&", keys[i], this[keys[i]]);
  23. }
  24. if (sb.Length > 0)
  25. sb.Length--;
  26. return sb.ToString();
  27. }
  28. }
  29. // Must be sorted
  30. static readonly long[] entities = new long[] {
  31. (long)'A' << 56 | (long)'E' << 48 | (long)'l' << 40 | (long)'i' << 32 | (long)'g' << 24,
  32. (long)'A' << 56 | (long)'a' << 48 | (long)'c' << 40 | (long)'u' << 32 | (long)'t' << 24 | (long)'e' << 16,
  33. (long)'A' << 56 | (long)'c' << 48 | (long)'i' << 40 | (long)'r' << 32 | (long)'c' << 24,
  34. (long)'A' << 56 | (long)'g' << 48 | (long)'r' << 40 | (long)'a' << 32 | (long)'v' << 24 | (long)'e' << 16,
  35. (long)'A' << 56 | (long)'l' << 48 | (long)'p' << 40 | (long)'h' << 32 | (long)'a' << 24,
  36. (long)'A' << 56 | (long)'r' << 48 | (long)'i' << 40 | (long)'n' << 32 | (long)'g' << 24,
  37. (long)'A' << 56 | (long)'t' << 48 | (long)'i' << 40 | (long)'l' << 32 | (long)'d' << 24 | (long)'e' << 16,
  38. (long)'A' << 56 | (long)'u' << 48 | (long)'m' << 40 | (long)'l' << 32,
  39. (long)'B' << 56 | (long)'e' << 48 | (long)'t' << 40 | (long)'a' << 32,
  40. (long)'C' << 56 | (long)'c' << 48 | (long)'e' << 40 | (long)'d' << 32 | (long)'i' << 24 | (long)'l' << 16,
  41. (long)'C' << 56 | (long)'h' << 48 | (long)'i' << 40,
  42. (long)'D' << 56 | (long)'a' << 48 | (long)'g' << 40 | (long)'g' << 32 | (long)'e' << 24 | (long)'r' << 16,
  43. (long)'D' << 56 | (long)'e' << 48 | (long)'l' << 40 | (long)'t' << 32 | (long)'a' << 24,
  44. (long)'E' << 56 | (long)'T' << 48 | (long)'H' << 40,
  45. (long)'E' << 56 | (long)'a' << 48 | (long)'c' << 40 | (long)'u' << 32 | (long)'t' << 24 | (long)'e' << 16,
  46. (long)'E' << 56 | (long)'c' << 48 | (long)'i' << 40 | (long)'r' << 32 | (long)'c' << 24,
  47. (long)'E' << 56 | (long)'g' << 48 | (long)'r' << 40 | (long)'a' << 32 | (long)'v' << 24 | (long)'e' << 16,
  48. (long)'E' << 56 | (long)'p' << 48 | (long)'s' << 40 | (long)'i' << 32 | (long)'l' << 24 | (long)'o' << 16 | (long)'n' << 8,
  49. (long)'E' << 56 | (long)'t' << 48 | (long)'a' << 40,
  50. (long)'E' << 56 | (long)'u' << 48 | (long)'m' << 40 | (long)'l' << 32,
  51. (long)'G' << 56 | (long)'a' << 48 | (long)'m' << 40 | (long)'m' << 32 | (long)'a' << 24,
  52. (long)'I' << 56 | (long)'a' << 48 | (long)'c' << 40 | (long)'u' << 32 | (long)'t' << 24 | (long)'e' << 16,
  53. (long)'I' << 56 | (long)'c' << 48 | (long)'i' << 40 | (long)'r' << 32 | (long)'c' << 24,
  54. (long)'I' << 56 | (long)'g' << 48 | (long)'r' << 40 | (long)'a' << 32 | (long)'v' << 24 | (long)'e' << 16,
  55. (long)'I' << 56 | (long)'o' << 48 | (long)'t' << 40 | (long)'a' << 32,
  56. (long)'I' << 56 | (long)'u' << 48 | (long)'m' << 40 | (long)'l' << 32,
  57. (long)'K' << 56 | (long)'a' << 48 | (long)'p' << 40 | (long)'p' << 32 | (long)'a' << 24,
  58. (long)'L' << 56 | (long)'a' << 48 | (long)'m' << 40 | (long)'b' << 32 | (long)'d' << 24 | (long)'a' << 16,
  59. (long)'M' << 56 | (long)'u' << 48,
  60. (long)'N' << 56 | (long)'t' << 48 | (long)'i' << 40 | (long)'l' << 32 | (long)'d' << 24 | (long)'e' << 16,
  61. (long)'N' << 56 | (long)'u' << 48,
  62. (long)'O' << 56 | (long)'E' << 48 | (long)'l' << 40 | (long)'i' << 32 | (long)'g' << 24,
  63. (long)'O' << 56 | (long)'a' << 48 | (long)'c' << 40 | (long)'u' << 32 | (long)'t' << 24 | (long)'e' << 16,
  64. (long)'O' << 56 | (long)'c' << 48 | (long)'i' << 40 | (long)'r' << 32 | (long)'c' << 24,
  65. (long)'O' << 56 | (long)'g' << 48 | (long)'r' << 40 | (long)'a' << 32 | (long)'v' << 24 | (long)'e' << 16,
  66. (long)'O' << 56 | (long)'m' << 48 | (long)'e' << 40 | (long)'g' << 32 | (long)'a' << 24,
  67. (long)'O' << 56 | (long)'m' << 48 | (long)'i' << 40 | (long)'c' << 32 | (long)'r' << 24 | (long)'o' << 16 | (long)'n' << 8,
  68. (long)'O' << 56 | (long)'s' << 48 | (long)'l' << 40 | (long)'a' << 32 | (long)'s' << 24 | (long)'h' << 16,
  69. (long)'O' << 56 | (long)'t' << 48 | (long)'i' << 40 | (long)'l' << 32 | (long)'d' << 24 | (long)'e' << 16,
  70. (long)'O' << 56 | (long)'u' << 48 | (long)'m' << 40 | (long)'l' << 32,
  71. (long)'P' << 56 | (long)'h' << 48 | (long)'i' << 40,
  72. (long)'P' << 56 | (long)'i' << 48,
  73. (long)'P' << 56 | (long)'r' << 48 | (long)'i' << 40 | (long)'m' << 32 | (long)'e' << 24,
  74. (long)'P' << 56 | (long)'s' << 48 | (long)'i' << 40,
  75. (long)'R' << 56 | (long)'h' << 48 | (long)'o' << 40,
  76. (long)'S' << 56 | (long)'c' << 48 | (long)'a' << 40 | (long)'r' << 32 | (long)'o' << 24 | (long)'n' << 16,
  77. (long)'S' << 56 | (long)'i' << 48 | (long)'g' << 40 | (long)'m' << 32 | (long)'a' << 24,
  78. (long)'T' << 56 | (long)'H' << 48 | (long)'O' << 40 | (long)'R' << 32 | (long)'N' << 24,
  79. (long)'T' << 56 | (long)'a' << 48 | (long)'u' << 40,
  80. (long)'T' << 56 | (long)'h' << 48 | (long)'e' << 40 | (long)'t' << 32 | (long)'a' << 24,
  81. (long)'U' << 56 | (long)'a' << 48 | (long)'c' << 40 | (long)'u' << 32 | (long)'t' << 24 | (long)'e' << 16,
  82. (long)'U' << 56 | (long)'c' << 48 | (long)'i' << 40 | (long)'r' << 32 | (long)'c' << 24,
  83. (long)'U' << 56 | (long)'g' << 48 | (long)'r' << 40 | (long)'a' << 32 | (long)'v' << 24 | (long)'e' << 16,
  84. (long)'U' << 56 | (long)'p' << 48 | (long)'s' << 40 | (long)'i' << 32 | (long)'l' << 24 | (long)'o' << 16 | (long)'n' << 8,
  85. (long)'U' << 56 | (long)'u' << 48 | (long)'m' << 40 | (long)'l' << 32,
  86. (long)'X' << 56 | (long)'i' << 48,
  87. (long)'Y' << 56 | (long)'a' << 48 | (long)'c' << 40 | (long)'u' << 32 | (long)'t' << 24 | (long)'e' << 16,
  88. (long)'Y' << 56 | (long)'u' << 48 | (long)'m' << 40 | (long)'l' << 32,
  89. (long)'Z' << 56 | (long)'e' << 48 | (long)'t' << 40 | (long)'a' << 32,
  90. (long)'a' << 56 | (long)'a' << 48 | (long)'c' << 40 | (long)'u' << 32 | (long)'t' << 24 | (long)'e' << 16,
  91. (long)'a' << 56 | (long)'c' << 48 | (long)'i' << 40 | (long)'r' << 32 | (long)'c' << 24,
  92. (long)'a' << 56 | (long)'c' << 48 | (long)'u' << 40 | (long)'t' << 32 | (long)'e' << 24,
  93. (long)'a' << 56 | (long)'e' << 48 | (long)'l' << 40 | (long)'i' << 32 | (long)'g' << 24,
  94. (long)'a' << 56 | (long)'g' << 48 | (long)'r' << 40 | (long)'a' << 32 | (long)'v' << 24 | (long)'e' << 16,
  95. (long)'a' << 56 | (long)'l' << 48 | (long)'e' << 40 | (long)'f' << 32 | (long)'s' << 24 | (long)'y' << 16 | (long)'m' << 8,
  96. (long)'a' << 56 | (long)'l' << 48 | (long)'p' << 40 | (long)'h' << 32 | (long)'a' << 24,
  97. (long)'a' << 56 | (long)'m' << 48 | (long)'p' << 40,
  98. (long)'a' << 56 | (long)'n' << 48 | (long)'d' << 40,
  99. (long)'a' << 56 | (long)'n' << 48 | (long)'g' << 40,
  100. (long)'a' << 56 | (long)'p' << 48 | (long)'o' << 40 | (long)'s' << 32,
  101. (long)'a' << 56 | (long)'r' << 48 | (long)'i' << 40 | (long)'n' << 32 | (long)'g' << 24,
  102. (long)'a' << 56 | (long)'s' << 48 | (long)'y' << 40 | (long)'m' << 32 | (long)'p' << 24,
  103. (long)'a' << 56 | (long)'t' << 48 | (long)'i' << 40 | (long)'l' << 32 | (long)'d' << 24 | (long)'e' << 16,
  104. (long)'a' << 56 | (long)'u' << 48 | (long)'m' << 40 | (long)'l' << 32,
  105. (long)'b' << 56 | (long)'d' << 48 | (long)'q' << 40 | (long)'u' << 32 | (long)'o' << 24,
  106. (long)'b' << 56 | (long)'e' << 48 | (long)'t' << 40 | (long)'a' << 32,
  107. (long)'b' << 56 | (long)'r' << 48 | (long)'v' << 40 | (long)'b' << 32 | (long)'a' << 24 | (long)'r' << 16,
  108. (long)'b' << 56 | (long)'u' << 48 | (long)'l' << 40 | (long)'l' << 32,
  109. (long)'c' << 56 | (long)'a' << 48 | (long)'p' << 40,
  110. (long)'c' << 56 | (long)'c' << 48 | (long)'e' << 40 | (long)'d' << 32 | (long)'i' << 24 | (long)'l' << 16,
  111. (long)'c' << 56 | (long)'e' << 48 | (long)'d' << 40 | (long)'i' << 32 | (long)'l' << 24,
  112. (long)'c' << 56 | (long)'e' << 48 | (long)'n' << 40 | (long)'t' << 32,
  113. (long)'c' << 56 | (long)'h' << 48 | (long)'i' << 40,
  114. (long)'c' << 56 | (long)'i' << 48 | (long)'r' << 40 | (long)'c' << 32,
  115. (long)'c' << 56 | (long)'l' << 48 | (long)'u' << 40 | (long)'b' << 32 | (long)'s' << 24,
  116. (long)'c' << 56 | (long)'o' << 48 | (long)'n' << 40 | (long)'g' << 32,
  117. (long)'c' << 56 | (long)'o' << 48 | (long)'p' << 40 | (long)'y' << 32,
  118. (long)'c' << 56 | (long)'r' << 48 | (long)'a' << 40 | (long)'r' << 32 | (long)'r' << 24,
  119. (long)'c' << 56 | (long)'u' << 48 | (long)'p' << 40,
  120. (long)'c' << 56 | (long)'u' << 48 | (long)'r' << 40 | (long)'r' << 32 | (long)'e' << 24 | (long)'n' << 16,
  121. (long)'d' << 56 | (long)'A' << 48 | (long)'r' << 40 | (long)'r' << 32,
  122. (long)'d' << 56 | (long)'a' << 48 | (long)'g' << 40 | (long)'g' << 32 | (long)'e' << 24 | (long)'r' << 16,
  123. (long)'d' << 56 | (long)'a' << 48 | (long)'r' << 40 | (long)'r' << 32,
  124. (long)'d' << 56 | (long)'e' << 48 | (long)'g' << 40,
  125. (long)'d' << 56 | (long)'e' << 48 | (long)'l' << 40 | (long)'t' << 32 | (long)'a' << 24,
  126. (long)'d' << 56 | (long)'i' << 48 | (long)'a' << 40 | (long)'m' << 32 | (long)'s' << 24,
  127. (long)'d' << 56 | (long)'i' << 48 | (long)'v' << 40 | (long)'i' << 32 | (long)'d' << 24 | (long)'e' << 16,
  128. (long)'e' << 56 | (long)'a' << 48 | (long)'c' << 40 | (long)'u' << 32 | (long)'t' << 24 | (long)'e' << 16,
  129. (long)'e' << 56 | (long)'c' << 48 | (long)'i' << 40 | (long)'r' << 32 | (long)'c' << 24,
  130. (long)'e' << 56 | (long)'g' << 48 | (long)'r' << 40 | (long)'a' << 32 | (long)'v' << 24 | (long)'e' << 16,
  131. (long)'e' << 56 | (long)'m' << 48 | (long)'p' << 40 | (long)'t' << 32 | (long)'y' << 24,
  132. (long)'e' << 56 | (long)'m' << 48 | (long)'s' << 40 | (long)'p' << 32,
  133. (long)'e' << 56 | (long)'n' << 48 | (long)'s' << 40 | (long)'p' << 32,
  134. (long)'e' << 56 | (long)'p' << 48 | (long)'s' << 40 | (long)'i' << 32 | (long)'l' << 24 | (long)'o' << 16 | (long)'n' << 8,
  135. (long)'e' << 56 | (long)'q' << 48 | (long)'u' << 40 | (long)'i' << 32 | (long)'v' << 24,
  136. (long)'e' << 56 | (long)'t' << 48 | (long)'a' << 40,
  137. (long)'e' << 56 | (long)'t' << 48 | (long)'h' << 40,
  138. (long)'e' << 56 | (long)'u' << 48 | (long)'m' << 40 | (long)'l' << 32,
  139. (long)'e' << 56 | (long)'u' << 48 | (long)'r' << 40 | (long)'o' << 32,
  140. (long)'e' << 56 | (long)'x' << 48 | (long)'i' << 40 | (long)'s' << 32 | (long)'t' << 24,
  141. (long)'f' << 56 | (long)'n' << 48 | (long)'o' << 40 | (long)'f' << 32,
  142. (long)'f' << 56 | (long)'o' << 48 | (long)'r' << 40 | (long)'a' << 32 | (long)'l' << 24 | (long)'l' << 16,
  143. (long)'f' << 56 | (long)'r' << 48 | (long)'a' << 40 | (long)'c' << 32 | (long)'1' << 24 | (long)'2' << 16,
  144. (long)'f' << 56 | (long)'r' << 48 | (long)'a' << 40 | (long)'c' << 32 | (long)'1' << 24 | (long)'4' << 16,
  145. (long)'f' << 56 | (long)'r' << 48 | (long)'a' << 40 | (long)'c' << 32 | (long)'3' << 24 | (long)'4' << 16,
  146. (long)'f' << 56 | (long)'r' << 48 | (long)'a' << 40 | (long)'s' << 32 | (long)'l' << 24,
  147. (long)'g' << 56 | (long)'a' << 48 | (long)'m' << 40 | (long)'m' << 32 | (long)'a' << 24,
  148. (long)'g' << 56 | (long)'e' << 48,
  149. (long)'g' << 56 | (long)'t' << 48,
  150. (long)'h' << 56 | (long)'A' << 48 | (long)'r' << 40 | (long)'r' << 32,
  151. (long)'h' << 56 | (long)'a' << 48 | (long)'r' << 40 | (long)'r' << 32,
  152. (long)'h' << 56 | (long)'e' << 48 | (long)'a' << 40 | (long)'r' << 32 | (long)'t' << 24 | (long)'s' << 16,
  153. (long)'h' << 56 | (long)'e' << 48 | (long)'l' << 40 | (long)'l' << 32 | (long)'i' << 24 | (long)'p' << 16,
  154. (long)'i' << 56 | (long)'a' << 48 | (long)'c' << 40 | (long)'u' << 32 | (long)'t' << 24 | (long)'e' << 16,
  155. (long)'i' << 56 | (long)'c' << 48 | (long)'i' << 40 | (long)'r' << 32 | (long)'c' << 24,
  156. (long)'i' << 56 | (long)'e' << 48 | (long)'x' << 40 | (long)'c' << 32 | (long)'l' << 24,
  157. (long)'i' << 56 | (long)'g' << 48 | (long)'r' << 40 | (long)'a' << 32 | (long)'v' << 24 | (long)'e' << 16,
  158. (long)'i' << 56 | (long)'m' << 48 | (long)'a' << 40 | (long)'g' << 32 | (long)'e' << 24,
  159. (long)'i' << 56 | (long)'n' << 48 | (long)'f' << 40 | (long)'i' << 32 | (long)'n' << 24,
  160. (long)'i' << 56 | (long)'n' << 48 | (long)'t' << 40,
  161. (long)'i' << 56 | (long)'o' << 48 | (long)'t' << 40 | (long)'a' << 32,
  162. (long)'i' << 56 | (long)'q' << 48 | (long)'u' << 40 | (long)'e' << 32 | (long)'s' << 24 | (long)'t' << 16,
  163. (long)'i' << 56 | (long)'s' << 48 | (long)'i' << 40 | (long)'n' << 32,
  164. (long)'i' << 56 | (long)'u' << 48 | (long)'m' << 40 | (long)'l' << 32,
  165. (long)'k' << 56 | (long)'a' << 48 | (long)'p' << 40 | (long)'p' << 32 | (long)'a' << 24,
  166. (long)'l' << 56 | (long)'A' << 48 | (long)'r' << 40 | (long)'r' << 32,
  167. (long)'l' << 56 | (long)'a' << 48 | (long)'m' << 40 | (long)'b' << 32 | (long)'d' << 24 | (long)'a' << 16,
  168. (long)'l' << 56 | (long)'a' << 48 | (long)'n' << 40 | (long)'g' << 32,
  169. (long)'l' << 56 | (long)'a' << 48 | (long)'q' << 40 | (long)'u' << 32 | (long)'o' << 24,
  170. (long)'l' << 56 | (long)'a' << 48 | (long)'r' << 40 | (long)'r' << 32,
  171. (long)'l' << 56 | (long)'c' << 48 | (long)'e' << 40 | (long)'i' << 32 | (long)'l' << 24,
  172. (long)'l' << 56 | (long)'d' << 48 | (long)'q' << 40 | (long)'u' << 32 | (long)'o' << 24,
  173. (long)'l' << 56 | (long)'e' << 48,
  174. (long)'l' << 56 | (long)'f' << 48 | (long)'l' << 40 | (long)'o' << 32 | (long)'o' << 24 | (long)'r' << 16,
  175. (long)'l' << 56 | (long)'o' << 48 | (long)'w' << 40 | (long)'a' << 32 | (long)'s' << 24 | (long)'t' << 16,
  176. (long)'l' << 56 | (long)'o' << 48 | (long)'z' << 40,
  177. (long)'l' << 56 | (long)'r' << 48 | (long)'m' << 40,
  178. (long)'l' << 56 | (long)'s' << 48 | (long)'a' << 40 | (long)'q' << 32 | (long)'u' << 24 | (long)'o' << 16,
  179. (long)'l' << 56 | (long)'s' << 48 | (long)'q' << 40 | (long)'u' << 32 | (long)'o' << 24,
  180. (long)'l' << 56 | (long)'t' << 48,
  181. (long)'m' << 56 | (long)'a' << 48 | (long)'c' << 40 | (long)'r' << 32,
  182. (long)'m' << 56 | (long)'d' << 48 | (long)'a' << 40 | (long)'s' << 32 | (long)'h' << 24,
  183. (long)'m' << 56 | (long)'i' << 48 | (long)'c' << 40 | (long)'r' << 32 | (long)'o' << 24,
  184. (long)'m' << 56 | (long)'i' << 48 | (long)'d' << 40 | (long)'d' << 32 | (long)'o' << 24 | (long)'t' << 16,
  185. (long)'m' << 56 | (long)'i' << 48 | (long)'n' << 40 | (long)'u' << 32 | (long)'s' << 24,
  186. (long)'m' << 56 | (long)'u' << 48,
  187. (long)'n' << 56 | (long)'a' << 48 | (long)'b' << 40 | (long)'l' << 32 | (long)'a' << 24,
  188. (long)'n' << 56 | (long)'b' << 48 | (long)'s' << 40 | (long)'p' << 32,
  189. (long)'n' << 56 | (long)'d' << 48 | (long)'a' << 40 | (long)'s' << 32 | (long)'h' << 24,
  190. (long)'n' << 56 | (long)'e' << 48,
  191. (long)'n' << 56 | (long)'i' << 48,
  192. (long)'n' << 56 | (long)'o' << 48 | (long)'t' << 40,
  193. (long)'n' << 56 | (long)'o' << 48 | (long)'t' << 40 | (long)'i' << 32 | (long)'n' << 24,
  194. (long)'n' << 56 | (long)'s' << 48 | (long)'u' << 40 | (long)'b' << 32,
  195. (long)'n' << 56 | (long)'t' << 48 | (long)'i' << 40 | (long)'l' << 32 | (long)'d' << 24 | (long)'e' << 16,
  196. (long)'n' << 56 | (long)'u' << 48,
  197. (long)'o' << 56 | (long)'a' << 48 | (long)'c' << 40 | (long)'u' << 32 | (long)'t' << 24 | (long)'e' << 16,
  198. (long)'o' << 56 | (long)'c' << 48 | (long)'i' << 40 | (long)'r' << 32 | (long)'c' << 24,
  199. (long)'o' << 56 | (long)'e' << 48 | (long)'l' << 40 | (long)'i' << 32 | (long)'g' << 24,
  200. (long)'o' << 56 | (long)'g' << 48 | (long)'r' << 40 | (long)'a' << 32 | (long)'v' << 24 | (long)'e' << 16,
  201. (long)'o' << 56 | (long)'l' << 48 | (long)'i' << 40 | (long)'n' << 32 | (long)'e' << 24,
  202. (long)'o' << 56 | (long)'m' << 48 | (long)'e' << 40 | (long)'g' << 32 | (long)'a' << 24,
  203. (long)'o' << 56 | (long)'m' << 48 | (long)'i' << 40 | (long)'c' << 32 | (long)'r' << 24 | (long)'o' << 16 | (long)'n' << 8,
  204. (long)'o' << 56 | (long)'p' << 48 | (long)'l' << 40 | (long)'u' << 32 | (long)'s' << 24,
  205. (long)'o' << 56 | (long)'r' << 48,
  206. (long)'o' << 56 | (long)'r' << 48 | (long)'d' << 40 | (long)'f' << 32,
  207. (long)'o' << 56 | (long)'r' << 48 | (long)'d' << 40 | (long)'m' << 32,
  208. (long)'o' << 56 | (long)'s' << 48 | (long)'l' << 40 | (long)'a' << 32 | (long)'s' << 24 | (long)'h' << 16,
  209. (long)'o' << 56 | (long)'t' << 48 | (long)'i' << 40 | (long)'l' << 32 | (long)'d' << 24 | (long)'e' << 16,
  210. (long)'o' << 56 | (long)'t' << 48 | (long)'i' << 40 | (long)'m' << 32 | (long)'e' << 24 | (long)'s' << 16,
  211. (long)'o' << 56 | (long)'u' << 48 | (long)'m' << 40 | (long)'l' << 32,
  212. (long)'p' << 56 | (long)'a' << 48 | (long)'r' << 40 | (long)'a' << 32,
  213. (long)'p' << 56 | (long)'a' << 48 | (long)'r' << 40 | (long)'t' << 32,
  214. (long)'p' << 56 | (long)'e' << 48 | (long)'r' << 40 | (long)'m' << 32 | (long)'i' << 24 | (long)'l' << 16,
  215. (long)'p' << 56 | (long)'e' << 48 | (long)'r' << 40 | (long)'p' << 32,
  216. (long)'p' << 56 | (long)'h' << 48 | (long)'i' << 40,
  217. (long)'p' << 56 | (long)'i' << 48,
  218. (long)'p' << 56 | (long)'i' << 48 | (long)'v' << 40,
  219. (long)'p' << 56 | (long)'l' << 48 | (long)'u' << 40 | (long)'s' << 32 | (long)'m' << 24 | (long)'n' << 16,
  220. (long)'p' << 56 | (long)'o' << 48 | (long)'u' << 40 | (long)'n' << 32 | (long)'d' << 24,
  221. (long)'p' << 56 | (long)'r' << 48 | (long)'i' << 40 | (long)'m' << 32 | (long)'e' << 24,
  222. (long)'p' << 56 | (long)'r' << 48 | (long)'o' << 40 | (long)'d' << 32,
  223. (long)'p' << 56 | (long)'r' << 48 | (long)'o' << 40 | (long)'p' << 32,
  224. (long)'p' << 56 | (long)'s' << 48 | (long)'i' << 40,
  225. (long)'q' << 56 | (long)'u' << 48 | (long)'o' << 40 | (long)'t' << 32,
  226. (long)'r' << 56 | (long)'A' << 48 | (long)'r' << 40 | (long)'r' << 32,
  227. (long)'r' << 56 | (long)'a' << 48 | (long)'d' << 40 | (long)'i' << 32 | (long)'c' << 24,
  228. (long)'r' << 56 | (long)'a' << 48 | (long)'n' << 40 | (long)'g' << 32,
  229. (long)'r' << 56 | (long)'a' << 48 | (long)'q' << 40 | (long)'u' << 32 | (long)'o' << 24,
  230. (long)'r' << 56 | (long)'a' << 48 | (long)'r' << 40 | (long)'r' << 32,
  231. (long)'r' << 56 | (long)'c' << 48 | (long)'e' << 40 | (long)'i' << 32 | (long)'l' << 24,
  232. (long)'r' << 56 | (long)'d' << 48 | (long)'q' << 40 | (long)'u' << 32 | (long)'o' << 24,
  233. (long)'r' << 56 | (long)'e' << 48 | (long)'a' << 40 | (long)'l' << 32,
  234. (long)'r' << 56 | (long)'e' << 48 | (long)'g' << 40,
  235. (long)'r' << 56 | (long)'f' << 48 | (long)'l' << 40 | (long)'o' << 32 | (long)'o' << 24 | (long)'r' << 16,
  236. (long)'r' << 56 | (long)'h' << 48 | (long)'o' << 40,
  237. (long)'r' << 56 | (long)'l' << 48 | (long)'m' << 40,
  238. (long)'r' << 56 | (long)'s' << 48 | (long)'a' << 40 | (long)'q' << 32 | (long)'u' << 24 | (long)'o' << 16,
  239. (long)'r' << 56 | (long)'s' << 48 | (long)'q' << 40 | (long)'u' << 32 | (long)'o' << 24,
  240. (long)'s' << 56 | (long)'b' << 48 | (long)'q' << 40 | (long)'u' << 32 | (long)'o' << 24,
  241. (long)'s' << 56 | (long)'c' << 48 | (long)'a' << 40 | (long)'r' << 32 | (long)'o' << 24 | (long)'n' << 16,
  242. (long)'s' << 56 | (long)'d' << 48 | (long)'o' << 40 | (long)'t' << 32,
  243. (long)'s' << 56 | (long)'e' << 48 | (long)'c' << 40 | (long)'t' << 32,
  244. (long)'s' << 56 | (long)'h' << 48 | (long)'y' << 40,
  245. (long)'s' << 56 | (long)'i' << 48 | (long)'g' << 40 | (long)'m' << 32 | (long)'a' << 24,
  246. (long)'s' << 56 | (long)'i' << 48 | (long)'g' << 40 | (long)'m' << 32 | (long)'a' << 24 | (long)'f' << 16,
  247. (long)'s' << 56 | (long)'i' << 48 | (long)'m' << 40,
  248. (long)'s' << 56 | (long)'p' << 48 | (long)'a' << 40 | (long)'d' << 32 | (long)'e' << 24 | (long)'s' << 16,
  249. (long)'s' << 56 | (long)'u' << 48 | (long)'b' << 40,
  250. (long)'s' << 56 | (long)'u' << 48 | (long)'b' << 40 | (long)'e' << 32,
  251. (long)'s' << 56 | (long)'u' << 48 | (long)'m' << 40,
  252. (long)'s' << 56 | (long)'u' << 48 | (long)'p' << 40,
  253. (long)'s' << 56 | (long)'u' << 48 | (long)'p' << 40 | (long)'1' << 32,
  254. (long)'s' << 56 | (long)'u' << 48 | (long)'p' << 40 | (long)'2' << 32,
  255. (long)'s' << 56 | (long)'u' << 48 | (long)'p' << 40 | (long)'3' << 32,
  256. (long)'s' << 56 | (long)'u' << 48 | (long)'p' << 40 | (long)'e' << 32,
  257. (long)'s' << 56 | (long)'z' << 48 | (long)'l' << 40 | (long)'i' << 32 | (long)'g' << 24,
  258. (long)'t' << 56 | (long)'a' << 48 | (long)'u' << 40,
  259. (long)'t' << 56 | (long)'h' << 48 | (long)'e' << 40 | (long)'r' << 32 | (long)'e' << 24 | (long)'4' << 16,
  260. (long)'t' << 56 | (long)'h' << 48 | (long)'e' << 40 | (long)'t' << 32 | (long)'a' << 24,
  261. (long)'t' << 56 | (long)'h' << 48 | (long)'e' << 40 | (long)'t' << 32 | (long)'a' << 24 | (long)'s' << 16 | (long)'y' << 8 | (long)'m' << 0,
  262. (long)'t' << 56 | (long)'h' << 48 | (long)'i' << 40 | (long)'n' << 32 | (long)'s' << 24 | (long)'p' << 16,
  263. (long)'t' << 56 | (long)'h' << 48 | (long)'o' << 40 | (long)'r' << 32 | (long)'n' << 24,
  264. (long)'t' << 56 | (long)'i' << 48 | (long)'l' << 40 | (long)'d' << 32 | (long)'e' << 24,
  265. (long)'t' << 56 | (long)'i' << 48 | (long)'m' << 40 | (long)'e' << 32 | (long)'s' << 24,
  266. (long)'t' << 56 | (long)'r' << 48 | (long)'a' << 40 | (long)'d' << 32 | (long)'e' << 24,
  267. (long)'u' << 56 | (long)'A' << 48 | (long)'r' << 40 | (long)'r' << 32,
  268. (long)'u' << 56 | (long)'a' << 48 | (long)'c' << 40 | (long)'u' << 32 | (long)'t' << 24 | (long)'e' << 16,
  269. (long)'u' << 56 | (long)'a' << 48 | (long)'r' << 40 | (long)'r' << 32,
  270. (long)'u' << 56 | (long)'c' << 48 | (long)'i' << 40 | (long)'r' << 32 | (long)'c' << 24,
  271. (long)'u' << 56 | (long)'g' << 48 | (long)'r' << 40 | (long)'a' << 32 | (long)'v' << 24 | (long)'e' << 16,
  272. (long)'u' << 56 | (long)'m' << 48 | (long)'l' << 40,
  273. (long)'u' << 56 | (long)'p' << 48 | (long)'s' << 40 | (long)'i' << 32 | (long)'h' << 24,
  274. (long)'u' << 56 | (long)'p' << 48 | (long)'s' << 40 | (long)'i' << 32 | (long)'l' << 24 | (long)'o' << 16 | (long)'n' << 8,
  275. (long)'u' << 56 | (long)'u' << 48 | (long)'m' << 40 | (long)'l' << 32,
  276. (long)'w' << 56 | (long)'e' << 48 | (long)'i' << 40 | (long)'e' << 32 | (long)'r' << 24 | (long)'p' << 16,
  277. (long)'x' << 56 | (long)'i' << 48,
  278. (long)'y' << 56 | (long)'a' << 48 | (long)'c' << 40 | (long)'u' << 32 | (long)'t' << 24 | (long)'e' << 16,
  279. (long)'y' << 56 | (long)'e' << 48 | (long)'n' << 40,
  280. (long)'y' << 56 | (long)'u' << 48 | (long)'m' << 40 | (long)'l' << 32,
  281. (long)'z' << 56 | (long)'e' << 48 | (long)'t' << 40 | (long)'a' << 32,
  282. (long)'z' << 56 | (long)'w' << 48 | (long)'j' << 40,
  283. (long)'z' << 56 | (long)'w' << 48 | (long)'n' << 40 | (long)'j' << 32
  284. };
  285. static readonly char[] entities_values = new char[] {
  286. '\u00C6',
  287. '\u00C1',
  288. '\u00C2',
  289. '\u00C0',
  290. '\u0391',
  291. '\u00C5',
  292. '\u00C3',
  293. '\u00C4',
  294. '\u0392',
  295. '\u00C7',
  296. '\u03A7',
  297. '\u2021',
  298. '\u0394',
  299. '\u00D0',
  300. '\u00C9',
  301. '\u00CA',
  302. '\u00C8',
  303. '\u0395',
  304. '\u0397',
  305. '\u00CB',
  306. '\u0393',
  307. '\u00CD',
  308. '\u00CE',
  309. '\u00CC',
  310. '\u0399',
  311. '\u00CF',
  312. '\u039A',
  313. '\u039B',
  314. '\u039C',
  315. '\u00D1',
  316. '\u039D',
  317. '\u0152',
  318. '\u00D3',
  319. '\u00D4',
  320. '\u00D2',
  321. '\u03A9',
  322. '\u039F',
  323. '\u00D8',
  324. '\u00D5',
  325. '\u00D6',
  326. '\u03A6',
  327. '\u03A0',
  328. '\u2033',
  329. '\u03A8',
  330. '\u03A1',
  331. '\u0160',
  332. '\u03A3',
  333. '\u00DE',
  334. '\u03A4',
  335. '\u0398',
  336. '\u00DA',
  337. '\u00DB',
  338. '\u00D9',
  339. '\u03A5',
  340. '\u00DC',
  341. '\u039E',
  342. '\u00DD',
  343. '\u0178',
  344. '\u0396',
  345. '\u00E1',
  346. '\u00E2',
  347. '\u00B4',
  348. '\u00E6',
  349. '\u00E0',
  350. '\u2135',
  351. '\u03B1',
  352. '\u0026',
  353. '\u2227',
  354. '\u2220',
  355. '\u0027',
  356. '\u00E5',
  357. '\u2248',
  358. '\u00E3',
  359. '\u00E4',
  360. '\u201E',
  361. '\u03B2',
  362. '\u00A6',
  363. '\u2022',
  364. '\u2229',
  365. '\u00E7',
  366. '\u00B8',
  367. '\u00A2',
  368. '\u03C7',
  369. '\u02C6',
  370. '\u2663',
  371. '\u2245',
  372. '\u00A9',
  373. '\u21B5',
  374. '\u222A',
  375. '\u00A4',
  376. '\u21D3',
  377. '\u2020',
  378. '\u2193',
  379. '\u00B0',
  380. '\u03B4',
  381. '\u2666',
  382. '\u00F7',
  383. '\u00E9',
  384. '\u00EA',
  385. '\u00E8',
  386. '\u2205',
  387. '\u2003',
  388. '\u2002',
  389. '\u03B5',
  390. '\u2261',
  391. '\u03B7',
  392. '\u00F0',
  393. '\u00EB',
  394. '\u20AC',
  395. '\u2203',
  396. '\u0192',
  397. '\u2200',
  398. '\u00BD',
  399. '\u00BC',
  400. '\u00BE',
  401. '\u2044',
  402. '\u03B3',
  403. '\u2265',
  404. '\u003E',
  405. '\u21D4',
  406. '\u2194',
  407. '\u2665',
  408. '\u2026',
  409. '\u00ED',
  410. '\u00EE',
  411. '\u00A1',
  412. '\u00EC',
  413. '\u2111',
  414. '\u221E',
  415. '\u222B',
  416. '\u03B9',
  417. '\u00BF',
  418. '\u2208',
  419. '\u00EF',
  420. '\u03BA',
  421. '\u21D0',
  422. '\u03BB',
  423. '\u2329',
  424. '\u00AB',
  425. '\u2190',
  426. '\u2308',
  427. '\u201C',
  428. '\u2264',
  429. '\u230A',
  430. '\u2217',
  431. '\u25CA',
  432. '\u200E',
  433. '\u2039',
  434. '\u2018',
  435. '\u003C',
  436. '\u00AF',
  437. '\u2014',
  438. '\u00B5',
  439. '\u00B7',
  440. '\u2212',
  441. '\u03BC',
  442. '\u2207',
  443. '\u00A0',
  444. '\u2013',
  445. '\u2260',
  446. '\u220B',
  447. '\u00AC',
  448. '\u2209',
  449. '\u2284',
  450. '\u00F1',
  451. '\u03BD',
  452. '\u00F3',
  453. '\u00F4',
  454. '\u0153',
  455. '\u00F2',
  456. '\u203E',
  457. '\u03C9',
  458. '\u03BF',
  459. '\u2295',
  460. '\u2228',
  461. '\u00AA',
  462. '\u00BA',
  463. '\u00F8',
  464. '\u00F5',
  465. '\u2297',
  466. '\u00F6',
  467. '\u00B6',
  468. '\u2202',
  469. '\u2030',
  470. '\u22A5',
  471. '\u03C6',
  472. '\u03C0',
  473. '\u03D6',
  474. '\u00B1',
  475. '\u00A3',
  476. '\u2032',
  477. '\u220F',
  478. '\u221D',
  479. '\u03C8',
  480. '\u0022',
  481. '\u21D2',
  482. '\u221A',
  483. '\u232A',
  484. '\u00BB',
  485. '\u2192',
  486. '\u2309',
  487. '\u201D',
  488. '\u211C',
  489. '\u00AE',
  490. '\u230B',
  491. '\u03C1',
  492. '\u200F',
  493. '\u203A',
  494. '\u2019',
  495. '\u201A',
  496. '\u0161',
  497. '\u22C5',
  498. '\u00A7',
  499. '\u00AD',
  500. '\u03C3',
  501. '\u03C2',
  502. '\u223C',
  503. '\u2660',
  504. '\u2282',
  505. '\u2286',
  506. '\u2211',
  507. '\u2283',
  508. '\u00B9',
  509. '\u00B2',
  510. '\u00B3',
  511. '\u2287',
  512. '\u00DF',
  513. '\u03C4',
  514. '\u2234',
  515. '\u03B8',
  516. '\u03D1',
  517. '\u2009',
  518. '\u00FE',
  519. '\u02DC',
  520. '\u00D7',
  521. '\u2122',
  522. '\u21D1',
  523. '\u00FA',
  524. '\u2191',
  525. '\u00FB',
  526. '\u00F9',
  527. '\u00A8',
  528. '\u03D2',
  529. '\u03C5',
  530. '\u00FC',
  531. '\u2118',
  532. '\u03BE',
  533. '\u00FD',
  534. '\u00A5',
  535. '\u00FF',
  536. '\u03B6',
  537. '\u200D',
  538. '\u200C'
  539. };
  540. #region Methods
  541. static void WriteCharBytes(IList buf, char ch, Encoding e)
  542. {
  543. if (ch > 255)
  544. {
  545. foreach (byte b in e.GetBytes(new char[] { ch }))
  546. buf.Add(b);
  547. }
  548. else
  549. buf.Add((byte)ch);
  550. }
  551. public static string UrlDecode(string s, Encoding e)
  552. {
  553. if (null == s)
  554. return null;
  555. if (s.IndexOf('%') == -1 && s.IndexOf('+') == -1)
  556. return s;
  557. if (e == null)
  558. e = Encoding.UTF8;
  559. long len = s.Length;
  560. var bytes = new List<byte>();
  561. int xchar;
  562. char ch;
  563. for (int i = 0; i < len; i++)
  564. {
  565. ch = s[i];
  566. if (ch == '%' && i + 2 < len && s[i + 1] != '%')
  567. {
  568. if (s[i + 1] == 'u' && i + 5 < len)
  569. {
  570. // unicode hex sequence
  571. xchar = GetChar(s, i + 2, 4);
  572. if (xchar != -1)
  573. {
  574. WriteCharBytes(bytes, (char)xchar, e);
  575. i += 5;
  576. }
  577. else
  578. WriteCharBytes(bytes, '%', e);
  579. }
  580. else if ((xchar = GetChar(s, i + 1, 2)) != -1)
  581. {
  582. WriteCharBytes(bytes, (char)xchar, e);
  583. i += 2;
  584. }
  585. else
  586. {
  587. WriteCharBytes(bytes, '%', e);
  588. }
  589. continue;
  590. }
  591. if (ch == '+')
  592. WriteCharBytes(bytes, ' ', e);
  593. else
  594. WriteCharBytes(bytes, ch, e);
  595. }
  596. byte[] buf = bytes.ToArray();
  597. bytes = null;
  598. return e.GetString(buf);
  599. }
  600. static int GetInt(byte b)
  601. {
  602. char c = (char)b;
  603. if (c >= '0' && c <= '9')
  604. return c - '0';
  605. if (c >= 'a' && c <= 'f')
  606. return c - 'a' + 10;
  607. if (c >= 'A' && c <= 'F')
  608. return c - 'A' + 10;
  609. return -1;
  610. }
  611. static int GetChar(string str, int offset, int length)
  612. {
  613. int val = 0;
  614. int end = length + offset;
  615. for (int i = offset; i < end; i++)
  616. {
  617. char c = str[i];
  618. if (c > 127)
  619. return -1;
  620. int current = GetInt((byte)c);
  621. if (current == -1)
  622. return -1;
  623. val = (val << 4) + current;
  624. }
  625. return val;
  626. }
  627. static bool TryConvertKeyToEntity(string key, out char value)
  628. {
  629. var token = CalculateKeyValue(key);
  630. if (token == 0)
  631. {
  632. value = '\0';
  633. return false;
  634. }
  635. var idx = Array.BinarySearch(entities, token);
  636. if (idx < 0)
  637. {
  638. value = '\0';
  639. return false;
  640. }
  641. value = entities_values[idx];
  642. return true;
  643. }
  644. static long CalculateKeyValue(string s)
  645. {
  646. if (s.Length > 8)
  647. return 0;
  648. long key = 0;
  649. for (int i = 0; i < s.Length; ++i)
  650. {
  651. long ch = s[i];
  652. if (ch > 'z' || ch < '0')
  653. return 0;
  654. key |= ch << ((7 - i) * 8);
  655. }
  656. return key;
  657. }
  658. /// <summary>
  659. /// Decodes an HTML-encoded string and returns the decoded string.
  660. /// </summary>
  661. /// <param name="s">The HTML string to decode. </param>
  662. /// <returns>The decoded text.</returns>
  663. public static string HtmlDecode(string s)
  664. {
  665. if (s == null)
  666. throw new ArgumentNullException("s");
  667. if (s.IndexOf('&') == -1)
  668. return s;
  669. StringBuilder entity = new StringBuilder();
  670. StringBuilder output = new StringBuilder();
  671. int len = s.Length;
  672. // 0 -> nothing,
  673. // 1 -> right after '&'
  674. // 2 -> between '&' and ';' but no '#'
  675. // 3 -> '#' found after '&' and getting numbers
  676. int state = 0;
  677. int number = 0;
  678. int digit_start = 0;
  679. bool hex_number = false;
  680. for (int i = 0; i < len; i++)
  681. {
  682. char c = s[i];
  683. if (state == 0)
  684. {
  685. if (c == '&')
  686. {
  687. entity.Append(c);
  688. state = 1;
  689. }
  690. else
  691. {
  692. output.Append(c);
  693. }
  694. continue;
  695. }
  696. if (c == '&')
  697. {
  698. state = 1;
  699. if (digit_start > 0)
  700. {
  701. entity.Append(s, digit_start, i - digit_start);
  702. digit_start = 0;
  703. }
  704. output.Append(entity.ToString());
  705. entity.Length = 0;
  706. entity.Append('&');
  707. continue;
  708. }
  709. switch (state)
  710. {
  711. case 1:
  712. if (c == ';')
  713. {
  714. state = 0;
  715. output.Append(entity.ToString());
  716. output.Append(c);
  717. entity.Length = 0;
  718. break;
  719. }
  720. number = 0;
  721. hex_number = false;
  722. if (c != '#')
  723. {
  724. state = 2;
  725. }
  726. else
  727. {
  728. state = 3;
  729. }
  730. entity.Append(c);
  731. break;
  732. case 2:
  733. entity.Append(c);
  734. if (c == ';')
  735. {
  736. string key = entity.ToString();
  737. state = 0;
  738. entity.Length = 0;
  739. if (key.Length > 1)
  740. {
  741. var skey = key.Substring(1, key.Length - 2);
  742. if (TryConvertKeyToEntity(skey, out c))
  743. {
  744. output.Append(c);
  745. break;
  746. }
  747. }
  748. output.Append(key);
  749. }
  750. break;
  751. case 3:
  752. if (c == ';')
  753. {
  754. if (number < 0x10000)
  755. {
  756. output.Append((char)number);
  757. }
  758. else
  759. {
  760. output.Append((char)(0xd800 + ((number - 0x10000) >> 10)));
  761. output.Append((char)(0xdc00 + ((number - 0x10000) & 0x3ff)));
  762. }
  763. state = 0;
  764. entity.Length = 0;
  765. digit_start = 0;
  766. break;
  767. }
  768. if (c == 'x' || c == 'X' && !hex_number)
  769. {
  770. digit_start = i;
  771. hex_number = true;
  772. break;
  773. }
  774. if (Char.IsDigit(c))
  775. {
  776. if (digit_start == 0)
  777. digit_start = i;
  778. number = number * (hex_number ? 16 : 10) + ((int)c - '0');
  779. break;
  780. }
  781. if (hex_number)
  782. {
  783. if (c >= 'a' && c <= 'f')
  784. {
  785. number = number * 16 + 10 + ((int)c - 'a');
  786. break;
  787. }
  788. if (c >= 'A' && c <= 'F')
  789. {
  790. number = number * 16 + 10 + ((int)c - 'A');
  791. break;
  792. }
  793. }
  794. state = 2;
  795. if (digit_start > 0)
  796. {
  797. entity.Append(s, digit_start, i - digit_start);
  798. digit_start = 0;
  799. }
  800. entity.Append(c);
  801. break;
  802. }
  803. }
  804. if (entity.Length > 0)
  805. {
  806. output.Append(entity);
  807. }
  808. else if (digit_start > 0)
  809. {
  810. output.Append(s, digit_start, s.Length - digit_start);
  811. }
  812. return output.ToString();
  813. }
  814. public static QueryParamCollection ParseQueryString(string query)
  815. {
  816. return ParseQueryString(query, Encoding.UTF8);
  817. }
  818. public static QueryParamCollection ParseQueryString(string query, Encoding encoding)
  819. {
  820. if (query == null)
  821. throw new ArgumentNullException("query");
  822. if (encoding == null)
  823. throw new ArgumentNullException("encoding");
  824. if (query.Length == 0 || (query.Length == 1 && query[0] == '?'))
  825. return new QueryParamCollection();
  826. if (query[0] == '?')
  827. query = query.Substring(1);
  828. QueryParamCollection result = new QueryParamCollection();
  829. ParseQueryString(query, encoding, result);
  830. return result;
  831. }
  832. internal static void ParseQueryString(string query, Encoding encoding, QueryParamCollection result)
  833. {
  834. if (query.Length == 0)
  835. return;
  836. string decoded = HtmlDecode(query);
  837. int decodedLength = decoded.Length;
  838. int namePos = 0;
  839. bool first = true;
  840. while (namePos <= decodedLength)
  841. {
  842. int valuePos = -1, valueEnd = -1;
  843. for (int q = namePos; q < decodedLength; q++)
  844. {
  845. if (valuePos == -1 && decoded[q] == '=')
  846. {
  847. valuePos = q + 1;
  848. }
  849. else if (decoded[q] == '&')
  850. {
  851. valueEnd = q;
  852. break;
  853. }
  854. }
  855. if (first)
  856. {
  857. first = false;
  858. if (decoded[namePos] == '?')
  859. namePos++;
  860. }
  861. string name, value;
  862. if (valuePos == -1)
  863. {
  864. name = null;
  865. valuePos = namePos;
  866. }
  867. else
  868. {
  869. name = UrlDecode(decoded.Substring(namePos, valuePos - namePos - 1), encoding);
  870. }
  871. if (valueEnd < 0)
  872. {
  873. namePos = -1;
  874. valueEnd = decoded.Length;
  875. }
  876. else
  877. {
  878. namePos = valueEnd + 1;
  879. }
  880. value = UrlDecode(decoded.Substring(valuePos, valueEnd - valuePos), encoding);
  881. result.Add(name, value);
  882. if (namePos == -1)
  883. break;
  884. }
  885. }
  886. #endregion // Methods
  887. }
  888. }