HttpUtility.cs 37 KB

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