HttpUtility.cs 37 KB

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