andrew4582

HttpUtility - Without Syste.Web

Aug 27th, 2010
268
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 34.90 KB | None | 0 0
  1. //#if WindowsCE || PocketPC
  2.  
  3. //  
  4. // System.Web.HttpUtility
  5. //
  6. // Authors:
  7. //   Patrik Torstensson ([email protected])
  8. //   Wictor Wil\uinput1\u195 Ã\uinput1\u169 ©n (decode/encode functions) ([email protected])
  9. //   Tim Coleman ([email protected])
  10. //   Gonzalo Paniagua Javier ([email protected])
  11. //
  12. // Copyright (C) 2005 Novell, Inc (http://www.novell.com)
  13. //
  14. // Permission is hereby granted, free of charge, to any person obtaining
  15. // a copy of this software and associated documentation files (the
  16. // "Software"), to deal in the Software without restriction, including
  17. // without limitation the rights to use, copy, modify, merge, publish,
  18. // distribute, sublicense, and/or sell copies of the Software, and to
  19. // permit persons to whom the Software is furnished to do so, subject to
  20. // the following conditions:
  21. //  
  22. // The above copyright notice and this permission notice shall be
  23. // included in all copies or substantial portions of the Software.
  24. //  
  25. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  26. // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  27. // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  28. // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
  29. // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
  30. // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
  31. // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  32. //
  33.  
  34. using System.Collections;
  35. using System.Collections.Specialized;
  36. using System.Globalization;
  37. using System.IO;
  38. using System.Security.Permissions;
  39. using System.Text;
  40. using System;
  41.  
  42. namespace Core.Web {
  43.  
  44.     public sealed class HttpUtility {
  45.  
  46.         #region  Fields
  47.  
  48.         static Hashtable entities;
  49.         static object lock_ = new object();
  50.  
  51.         #endregion  // Fields
  52.  
  53.         static Hashtable Entities {
  54.             get {
  55.                 lock(lock_) {
  56.                     if(entities == null)
  57.                         InitEntities();
  58.  
  59.                     return entities;
  60.                 }
  61.             }
  62.         }
  63.  
  64.         #region  Constructors
  65.  
  66.         static void InitEntities() {
  67.             // Build the hash table of HTML entity references.  This list comes
  68.             // from the HTML 4.01 W3C recommendation.
  69.             entities = new Hashtable();
  70.             entities.Add("nbsp",'\u00A0');
  71.             entities.Add("iexcl",'\u00A1');
  72.             entities.Add("cent",'\u00A2');
  73.             entities.Add("pound",'\u00A3');
  74.             entities.Add("curren",'\u00A4');
  75.             entities.Add("yen",'\u00A5');
  76.             entities.Add("brvbar",'\u00A6');
  77.             entities.Add("sect",'\u00A7');
  78.             entities.Add("uml",'\u00A8');
  79.             entities.Add("copy",'\u00A9');
  80.             entities.Add("ordf",'\u00AA');
  81.             entities.Add("laquo",'\u00AB');
  82.             entities.Add("not",'\u00AC');
  83.             entities.Add("shy",'\u00AD');
  84.             entities.Add("reg",'\u00AE');
  85.             entities.Add("macr",'\u00AF');
  86.             entities.Add("deg",'\u00B0');
  87.             entities.Add("plusmn",'\u00B1');
  88.             entities.Add("sup2",'\u00B2');
  89.             entities.Add("sup3",'\u00B3');
  90.             entities.Add("acute",'\u00B4');
  91.             entities.Add("micro",'\u00B5');
  92.             entities.Add("para",'\u00B6');
  93.             entities.Add("middot",'\u00B7');
  94.             entities.Add("cedil",'\u00B8');
  95.             entities.Add("sup1",'\u00B9');
  96.             entities.Add("ordm",'\u00BA');
  97.             entities.Add("raquo",'\u00BB');
  98.             entities.Add("frac14",'\u00BC');
  99.             entities.Add("frac12",'\u00BD');
  100.             entities.Add("frac34",'\u00BE');
  101.             entities.Add("iquest",'\u00BF');
  102.             entities.Add("Agrave",'\u00C0');
  103.             entities.Add("Aacute",'\u00C1');
  104.             entities.Add("Acirc",'\u00C2');
  105.             entities.Add("Atilde",'\u00C3');
  106.             entities.Add("Auml",'\u00C4');
  107.             entities.Add("Aring",'\u00C5');
  108.             entities.Add("AElig",'\u00C6');
  109.             entities.Add("Ccedil",'\u00C7');
  110.             entities.Add("Egrave",'\u00C8');
  111.             entities.Add("Eacute",'\u00C9');
  112.             entities.Add("Ecirc",'\u00CA');
  113.             entities.Add("Euml",'\u00CB');
  114.             entities.Add("Igrave",'\u00CC');
  115.             entities.Add("Iacute",'\u00CD');
  116.             entities.Add("Icirc",'\u00CE');
  117.             entities.Add("Iuml",'\u00CF');
  118.             entities.Add("ETH",'\u00D0');
  119.             entities.Add("Ntilde",'\u00D1');
  120.             entities.Add("Ograve",'\u00D2');
  121.             entities.Add("Oacute",'\u00D3');
  122.             entities.Add("Ocirc",'\u00D4');
  123.             entities.Add("Otilde",'\u00D5');
  124.             entities.Add("Ouml",'\u00D6');
  125.             entities.Add("times",'\u00D7');
  126.             entities.Add("Oslash",'\u00D8');
  127.             entities.Add("Ugrave",'\u00D9');
  128.             entities.Add("Uacute",'\u00DA');
  129.             entities.Add("Ucirc",'\u00DB');
  130.             entities.Add("Uuml",'\u00DC');
  131.             entities.Add("Yacute",'\u00DD');
  132.             entities.Add("THORN",'\u00DE');
  133.             entities.Add("szlig",'\u00DF');
  134.             entities.Add("agrave",'\u00E0');
  135.             entities.Add("aacute",'\u00E1');
  136.             entities.Add("acirc",'\u00E2');
  137.             entities.Add("atilde",'\u00E3');
  138.             entities.Add("auml",'\u00E4');
  139.             entities.Add("aring",'\u00E5');
  140.             entities.Add("aelig",'\u00E6');
  141.             entities.Add("ccedil",'\u00E7');
  142.             entities.Add("egrave",'\u00E8');
  143.             entities.Add("eacute",'\u00E9');
  144.             entities.Add("ecirc",'\u00EA');
  145.             entities.Add("euml",'\u00EB');
  146.             entities.Add("igrave",'\u00EC');
  147.             entities.Add("iacute",'\u00ED');
  148.             entities.Add("icirc",'\u00EE');
  149.             entities.Add("iuml",'\u00EF');
  150.             entities.Add("eth",'\u00F0');
  151.             entities.Add("ntilde",'\u00F1');
  152.             entities.Add("ograve",'\u00F2');
  153.             entities.Add("oacute",'\u00F3');
  154.             entities.Add("ocirc",'\u00F4');
  155.             entities.Add("otilde",'\u00F5');
  156.             entities.Add("ouml",'\u00F6');
  157.             entities.Add("divide",'\u00F7');
  158.             entities.Add("oslash",'\u00F8');
  159.             entities.Add("ugrave",'\u00F9');
  160.             entities.Add("uacute",'\u00FA');
  161.             entities.Add("ucirc",'\u00FB');
  162.             entities.Add("uuml",'\u00FC');
  163.             entities.Add("yacute",'\u00FD');
  164.             entities.Add("thorn",'\u00FE');
  165.             entities.Add("yuml",'\u00FF');
  166.             entities.Add("fnof",'\u0192');
  167.             entities.Add("Alpha",'\u0391');
  168.             entities.Add("Beta",'\u0392');
  169.             entities.Add("Gamma",'\u0393');
  170.             entities.Add("Delta",'\u0394');
  171.             entities.Add("Epsilon",'\u0395');
  172.             entities.Add("Zeta",'\u0396');
  173.             entities.Add("Eta",'\u0397');
  174.             entities.Add("Theta",'\u0398');
  175.             entities.Add("Iota",'\u0399');
  176.             entities.Add("Kappa",'\u039A');
  177.             entities.Add("Lambda",'\u039B');
  178.             entities.Add("Mu",'\u039C');
  179.             entities.Add("Nu",'\u039D');
  180.             entities.Add("Xi",'\u039E');
  181.             entities.Add("Omicron",'\u039F');
  182.             entities.Add("Pi",'\u03A0');
  183.             entities.Add("Rho",'\u03A1');
  184.             entities.Add("Sigma",'\u03A3');
  185.             entities.Add("Tau",'\u03A4');
  186.             entities.Add("Upsilon",'\u03A5');
  187.             entities.Add("Phi",'\u03A6');
  188.             entities.Add("Chi",'\u03A7');
  189.             entities.Add("Psi",'\u03A8');
  190.             entities.Add("Omega",'\u03A9');
  191.             entities.Add("alpha",'\u03B1');
  192.             entities.Add("beta",'\u03B2');
  193.             entities.Add("gamma",'\u03B3');
  194.             entities.Add("delta",'\u03B4');
  195.             entities.Add("epsilon",'\u03B5');
  196.             entities.Add("zeta",'\u03B6');
  197.             entities.Add("eta",'\u03B7');
  198.             entities.Add("theta",'\u03B8');
  199.             entities.Add("iota",'\u03B9');
  200.             entities.Add("kappa",'\u03BA');
  201.             entities.Add("lambda",'\u03BB');
  202.             entities.Add("mu",'\u03BC');
  203.             entities.Add("nu",'\u03BD');
  204.             entities.Add("xi",'\u03BE');
  205.             entities.Add("omicron",'\u03BF');
  206.             entities.Add("pi",'\u03C0');
  207.             entities.Add("rho",'\u03C1');
  208.             entities.Add("sigmaf",'\u03C2');
  209.             entities.Add("sigma",'\u03C3');
  210.             entities.Add("tau",'\u03C4');
  211.             entities.Add("upsilon",'\u03C5');
  212.             entities.Add("phi",'\u03C6');
  213.             entities.Add("chi",'\u03C7');
  214.             entities.Add("psi",'\u03C8');
  215.             entities.Add("omega",'\u03C9');
  216.             entities.Add("thetasym",'\u03D1');
  217.             entities.Add("upsih",'\u03D2');
  218.             entities.Add("piv",'\u03D6');
  219.             entities.Add("bull",'\u2022');
  220.             entities.Add("hellip",'\u2026');
  221.             entities.Add("prime",'\u2032');
  222.             entities.Add("Prime",'\u2033');
  223.             entities.Add("oline",'\u203E');
  224.             entities.Add("frasl",'\u2044');
  225.             entities.Add("weierp",'\u2118');
  226.             entities.Add("image",'\u2111');
  227.             entities.Add("real",'\u211C');
  228.             entities.Add("trade",'\u2122');
  229.             entities.Add("alefsym",'\u2135');
  230.             entities.Add("larr",'\u2190');
  231.             entities.Add("uarr",'\u2191');
  232.             entities.Add("rarr",'\u2192');
  233.             entities.Add("darr",'\u2193');
  234.             entities.Add("harr",'\u2194');
  235.             entities.Add("crarr",'\u21B5');
  236.             entities.Add("lArr",'\u21D0');
  237.             entities.Add("uArr",'\u21D1');
  238.             entities.Add("rArr",'\u21D2');
  239.             entities.Add("dArr",'\u21D3');
  240.             entities.Add("hArr",'\u21D4');
  241.             entities.Add("forall",'\u2200');
  242.             entities.Add("part",'\u2202');
  243.             entities.Add("exist",'\u2203');
  244.             entities.Add("empty",'\u2205');
  245.             entities.Add("nabla",'\u2207');
  246.             entities.Add("isin",'\u2208');
  247.             entities.Add("notin",'\u2209');
  248.             entities.Add("ni",'\u220B');
  249.             entities.Add("prod",'\u220F');
  250.             entities.Add("sum",'\u2211');
  251.             entities.Add("minus",'\u2212');
  252.             entities.Add("lowast",'\u2217');
  253.             entities.Add("radic",'\u221A');
  254.             entities.Add("prop",'\u221D');
  255.             entities.Add("infin",'\u221E');
  256.             entities.Add("ang",'\u2220');
  257.             entities.Add("and",'\u2227');
  258.             entities.Add("or",'\u2228');
  259.             entities.Add("cap",'\u2229');
  260.             entities.Add("cup",'\u222A');
  261.             entities.Add("int",'\u222B');
  262.             entities.Add("there4",'\u2234');
  263.             entities.Add("sim",'\u223C');
  264.             entities.Add("cong",'\u2245');
  265.             entities.Add("asymp",'\u2248');
  266.             entities.Add("ne",'\u2260');
  267.             entities.Add("equiv",'\u2261');
  268.             entities.Add("le",'\u2264');
  269.             entities.Add("ge",'\u2265');
  270.             entities.Add("sub",'\u2282');
  271.             entities.Add("sup",'\u2283');
  272.             entities.Add("nsub",'\u2284');
  273.             entities.Add("sube",'\u2286');
  274.             entities.Add("supe",'\u2287');
  275.             entities.Add("oplus",'\u2295');
  276.             entities.Add("otimes",'\u2297');
  277.             entities.Add("perp",'\u22A5');
  278.             entities.Add("sdot",'\u22C5');
  279.             entities.Add("lceil",'\u2308');
  280.             entities.Add("rceil",'\u2309');
  281.             entities.Add("lfloor",'\u230A');
  282.             entities.Add("rfloor",'\u230B');
  283.             entities.Add("lang",'\u2329');
  284.             entities.Add("rang",'\u232A');
  285.             entities.Add("loz",'\u25CA');
  286.             entities.Add("spades",'\u2660');
  287.             entities.Add("clubs",'\u2663');
  288.             entities.Add("hearts",'\u2665');
  289.             entities.Add("diams",'\u2666');
  290.             entities.Add("quot",'\u0022');
  291.             entities.Add("amp",'\u0026');
  292.             entities.Add("lt",'\u003C');
  293.             entities.Add("gt",'\u003E');
  294.             entities.Add("OElig",'\u0152');
  295.             entities.Add("oelig",'\u0153');
  296.             entities.Add("Scaron",'\u0160');
  297.             entities.Add("scaron",'\u0161');
  298.             entities.Add("Yuml",'\u0178');
  299.             entities.Add("circ",'\u02C6');
  300.             entities.Add("tilde",'\u02DC');
  301.             entities.Add("ensp",'\u2002');
  302.             entities.Add("emsp",'\u2003');
  303.             entities.Add("thinsp",'\u2009');
  304.             entities.Add("zwnj",'\u200C');
  305.             entities.Add("zwj",'\u200D');
  306.             entities.Add("lrm",'\u200E');
  307.             entities.Add("rlm",'\u200F');
  308.             entities.Add("ndash",'\u2013');
  309.             entities.Add("mdash",'\u2014');
  310.             entities.Add("lsquo",'\u2018');
  311.             entities.Add("rsquo",'\u2019');
  312.             entities.Add("sbquo",'\u201A');
  313.             entities.Add("ldquo",'\u201C');
  314.             entities.Add("rdquo",'\u201D');
  315.             entities.Add("bdquo",'\u201E');
  316.             entities.Add("dagger",'\u2020');
  317.             entities.Add("Dagger",'\u2021');
  318.             entities.Add("permil",'\u2030');
  319.             entities.Add("lsaquo",'\u2039');
  320.             entities.Add("rsaquo",'\u203A');
  321.             entities.Add("euro",'\u20AC');
  322.         }
  323.  
  324.         public HttpUtility() {
  325.         }
  326.  
  327.         #endregion  // Constructors
  328.  
  329.         #region  Methods
  330.  
  331.         public static void HtmlAttributeEncode(string s,TextWriter output) {
  332.             output.Write(HtmlAttributeEncode(s));
  333.         }
  334.  
  335.         public static string HtmlAttributeEncode(string s) {
  336.             if(null == s)
  337.                 return null;
  338.  
  339.             if(s.IndexOf('&') == -1 && s.IndexOf('"') == -1)
  340.                 return s;
  341.  
  342.             StringBuilder output = new StringBuilder();
  343.             foreach(char c in s)
  344.                 switch(c) {
  345.                     case '&':
  346.                         output.Append("&");
  347.                         break;
  348.                     case '"':
  349.                         output.Append(""");
  350.                         break;
  351.                     default:
  352.                         output.Append(c);
  353.                         break;
  354.                 }
  355.  
  356.             return output.ToString();
  357.         }
  358.  
  359.         public static string UrlDecode(string str) {
  360.             return UrlDecode(str,Encoding.UTF8);
  361.         }
  362.  
  363.         private static char[] GetChars(MemoryStream b,Encoding e) {
  364.             return e.GetChars(b.GetBuffer(),0,(int)b.Length);
  365.         }
  366.  
  367.         public static string UrlDecode(string s,Encoding e) {
  368.             if(null == s)
  369.                 return null;
  370.  
  371.             if(s.IndexOf('%') == -1 && s.IndexOf('+') == -1)
  372.                 return s;
  373.  
  374.             if(e == null)
  375.                 e = Encoding.UTF8;
  376.  
  377.             StringBuilder output = new StringBuilder();
  378.             long len = s.Length;
  379.             MemoryStream bytes = new MemoryStream();
  380.             int xchar;
  381.  
  382.             for(int i = 0;i < len;i++) {
  383.                 if(s[i] == '%' && i + 2 < len && s[i + 1] != '%') {
  384.                     if(s[i + 1] == 'u' && i + 5 < len) {
  385.                         if(bytes.Length > 0) {
  386.                             output.Append(GetChars(bytes,e));
  387.                             bytes.SetLength(0);
  388.                         }
  389.  
  390.                         xchar = GetChar(s,i + 2,4);
  391.                         if(xchar != -1) {
  392.                             output.Append((char)xchar);
  393.                             i += 5;
  394.                         }
  395.                         else {
  396.                             output.Append('%');
  397.                         }
  398.                     }
  399.                     else if((xchar = GetChar(s,i + 1,2)) != -1) {
  400.                         bytes.WriteByte((byte)xchar);
  401.                         i += 2;
  402.                     }
  403.                     else {
  404.                         output.Append('%');
  405.                     }
  406.                     continue;
  407.                 }
  408.  
  409.                 if(bytes.Length > 0) {
  410.                     output.Append(GetChars(bytes,e));
  411.                     bytes.SetLength(0);
  412.                 }
  413.  
  414.                 if(s[i] == '+') {
  415.                     output.Append(' ');
  416.                 }
  417.                 else {
  418.                     output.Append(s[i]);
  419.                 }
  420.             }
  421.  
  422.             if(bytes.Length > 0) {
  423.                 output.Append(GetChars(bytes,e));
  424.             }
  425.  
  426.             bytes = null;
  427.             return output.ToString();
  428.         }
  429.  
  430.         public static string UrlDecode(byte[] bytes,Encoding e) {
  431.             if(bytes == null)
  432.                 return null;
  433.  
  434.             return UrlDecode(bytes,0,bytes.Length,e);
  435.         }
  436.  
  437.         private static int GetInt(byte b) {
  438.             char c = (char)b;
  439.             if(c >= '0' && c <= '9')
  440.                 return c - '0';
  441.  
  442.             if(c >= 'a' && c <= 'f')
  443.                 return c - 'a' + 10;
  444.  
  445.             if(c >= 'A' && c <= 'F')
  446.                 return c - 'A' + 10;
  447.  
  448.             return -1;
  449.         }
  450.  
  451.         private static int GetChar(byte[] bytes,int offset,int length) {
  452.             int value = 0;
  453.             int end = length + offset;
  454.             for(int i = offset;i < end;i++) {
  455.                 int current = GetInt(bytes[i]);
  456.                 if(current == -1)
  457.                     return -1;
  458.                 value = (value << 4) + current;
  459.             }
  460.  
  461.             return value;
  462.         }
  463.  
  464.         private static int GetChar(string str,int offset,int length) {
  465.             int val = 0;
  466.             int end = length + offset;
  467.             for(int i = offset;i < end;i++) {
  468.                 char c = str[i];
  469.                 if(c > 127)
  470.                     return -1;
  471.  
  472.                 int current = GetInt((byte)c);
  473.                 if(current == -1)
  474.                     return -1;
  475.                 val = (val << 4) + current;
  476.             }
  477.  
  478.             return val;
  479.         }
  480.  
  481.         public static string UrlDecode(byte[] bytes,int offset,int count,Encoding e) {
  482.             if(bytes == null)
  483.                 return null;
  484.             if(count == 0)
  485.                 return String.Empty;
  486.  
  487.             if(bytes == null)
  488.                 throw new ArgumentNullException("bytes");
  489.  
  490.             if(offset < 0 || offset > bytes.Length)
  491.                 throw new ArgumentOutOfRangeException("offset");
  492.  
  493.             if(count < 0 || offset + count > bytes.Length)
  494.                 throw new ArgumentOutOfRangeException("count");
  495.  
  496.             StringBuilder output = new StringBuilder();
  497.             MemoryStream acc = new MemoryStream();
  498.  
  499.             int end = count + offset;
  500.             int xchar;
  501.             for(int i = offset;i < end;i++) {
  502.                 if(bytes[i] == '%' && i + 2 < count && bytes[i + 1] != '%') {
  503.                     if(bytes[i + 1] == (byte)'u' && i + 5 < end) {
  504.                         if(acc.Length > 0) {
  505.                             output.Append(GetChars(acc,e));
  506.                             acc.SetLength(0);
  507.                         }
  508.                         xchar = GetChar(bytes,i + 2,4);
  509.                         if(xchar != -1) {
  510.                             output.Append((char)xchar);
  511.                             i += 5;
  512.                             continue;
  513.                         }
  514.                     }
  515.                     else if((xchar = GetChar(bytes,i + 1,2)) != -1) {
  516.                         acc.WriteByte((byte)xchar);
  517.                         i += 2;
  518.                         continue;
  519.                     }
  520.                 }
  521.  
  522.                 if(acc.Length > 0) {
  523.                     output.Append(GetChars(acc,e));
  524.                     acc.SetLength(0);
  525.                 }
  526.  
  527.                 if(bytes[i] == '+') {
  528.                     output.Append(' ');
  529.                 }
  530.                 else {
  531.                     output.Append((char)bytes[i]);
  532.                 }
  533.             }
  534.  
  535.             if(acc.Length > 0) {
  536.                 output.Append(GetChars(acc,e));
  537.             }
  538.  
  539.             acc = null;
  540.             return output.ToString();
  541.         }
  542.  
  543.         public static byte[] UrlDecodeToBytes(byte[] bytes) {
  544.             if(bytes == null)
  545.                 return null;
  546.  
  547.             return UrlDecodeToBytes(bytes,0,bytes.Length);
  548.         }
  549.  
  550.         public static byte[] UrlDecodeToBytes(string str) {
  551.             return UrlDecodeToBytes(str,Encoding.UTF8);
  552.         }
  553.  
  554.         public static byte[] UrlDecodeToBytes(string str,Encoding e) {
  555.             if(str == null)
  556.                 return null;
  557.  
  558.             if(e == null)
  559.                 throw new ArgumentNullException("e");
  560.  
  561.             return UrlDecodeToBytes(e.GetBytes(str));
  562.         }
  563.  
  564.         public static byte[] UrlDecodeToBytes(byte[] bytes,int offset,int count) {
  565.             if(bytes == null)
  566.                 return null;
  567.             if(count == 0)
  568.                 return new byte[0];
  569.  
  570.             int len = bytes.Length;
  571.             if(offset < 0 || offset >= len)
  572.                 throw new ArgumentOutOfRangeException("offset");
  573.  
  574.             if(count < 0 || offset > len - count)
  575.                 throw new ArgumentOutOfRangeException("count");
  576.  
  577.             MemoryStream result = new MemoryStream();
  578.             int end = offset + count;
  579.             for(int i = offset;i < end;i++) {
  580.                 char c = (char)bytes[i];
  581.                 if(c == '+') {
  582.                     c = ' ';
  583.                 }
  584.                 else if(c == '%' && i < end - 2) {
  585.                     int xchar = GetChar(bytes,i + 1,2);
  586.                     if(xchar != -1) {
  587.                         c = (char)xchar;
  588.                         i += 2;
  589.                     }
  590.                 }
  591.                 result.WriteByte((byte)c);
  592.             }
  593.  
  594.             return result.ToArray();
  595.         }
  596.  
  597.         static char[] hexChars = "0123456789abcdef".ToCharArray();
  598.         const string notEncoded = "!'()*-._";
  599.  
  600.         static void UrlEncodeChar(char c,Stream result,bool isUnicode) {
  601.             if(c > 255) {
  602.                 //FIXME: what happens when there is an internal error?
  603.                 //if (!isUnicode)
  604.                 //  throw new ArgumentOutOfRangeException ("c", c, "c must be less than 256");
  605.                 int idx;
  606.                 int i = (int)c;
  607.  
  608.                 result.WriteByte((byte)'%');
  609.                 result.WriteByte((byte)'u');
  610.                 idx = i >> 12;
  611.                 result.WriteByte((byte)hexChars[idx]);
  612.                 idx = (i >> 8) & 0x0F;
  613.                 result.WriteByte((byte)hexChars[idx]);
  614.                 idx = (i >> 4) & 0x0F;
  615.                 result.WriteByte((byte)hexChars[idx]);
  616.                 idx = i & 0x0F;
  617.                 result.WriteByte((byte)hexChars[idx]);
  618.                 return;
  619.             }
  620.  
  621.             if(c > ' ' && notEncoded.IndexOf(c) != -1) {
  622.                 result.WriteByte((byte)c);
  623.                 return;
  624.             }
  625.             if(c == ' ') {
  626.                 result.WriteByte((byte)'+');
  627.                 return;
  628.             }
  629.             if((c < '0') ||
  630.                 (c < 'A' && c > '9') ||
  631.                 (c > 'Z' && c < 'a') ||
  632.                 (c > 'z')) {
  633.                 if(isUnicode && c > 127) {
  634.                     result.WriteByte((byte)'%');
  635.                     result.WriteByte((byte)'u');
  636.                     result.WriteByte((byte)'0');
  637.                     result.WriteByte((byte)'0');
  638.                 }
  639.                 else
  640.                     result.WriteByte((byte)'%');
  641.  
  642.                 int idx = ((int)c) >> 4;
  643.                 result.WriteByte((byte)hexChars[idx]);
  644.                 idx = ((int)c) & 0x0F;
  645.                 result.WriteByte((byte)hexChars[idx]);
  646.             }
  647.             else
  648.                 result.WriteByte((byte)c);
  649.         }
  650.  
  651.         public static byte[] UrlEncodeToBytes(byte[] bytes,int offset,int count) {
  652.             if(bytes == null)
  653.                 return null;
  654.  
  655.             int len = bytes.Length;
  656.             if(len == 0)
  657.                 return new byte[0];
  658.  
  659.             if(offset < 0 || offset >= len)
  660.                 throw new ArgumentOutOfRangeException("offset");
  661.  
  662.             if(count < 0 || count > len - offset)
  663.                 throw new ArgumentOutOfRangeException("count");
  664.  
  665.             MemoryStream result = new MemoryStream(count);
  666.             int end = offset + count;
  667.             for(int i = offset;i < end;i++)
  668.                 UrlEncodeChar((char)bytes[i],result,false);
  669.  
  670.             return result.ToArray();
  671.         }
  672.  
  673.  
  674.         public static byte[] UrlEncodeUnicodeToBytes(string str) {
  675.             if(str == null)
  676.                 return null;
  677.  
  678.             if(str == "")
  679.                 return new byte[0];
  680.  
  681.             MemoryStream result = new MemoryStream(str.Length);
  682.             foreach(char c in str) {
  683.                 UrlEncodeChar(c,result,true);
  684.             }
  685.             return result.ToArray();
  686.         }
  687.  
  688.         /// <summary>
  689.         /// Decodes an HTML-encoded string and returns the decoded string.
  690.         /// </summary>
  691.         /// <param name="s">The HTML string to decode. </param>
  692.         /// <returns>The decoded text.</returns>
  693.         public static string HtmlDecode(string s) {
  694.             if(s == null)
  695.                 throw new ArgumentNullException("s");
  696.  
  697.             if(s.IndexOf('&') == -1)
  698.                 return s;
  699.  
  700.             StringBuilder entity = new StringBuilder();
  701.             StringBuilder output = new StringBuilder();
  702.             int len = s.Length;
  703.             // 0 -> nothing,
  704.             // 1 -> right after '&'
  705.             // 2 -> between '&' and ';' but no '#'
  706.             // 3 -> '#' found after '&' and getting numbers
  707.             int state = 0;
  708.             int number = 0;
  709.             bool have_trailing_digits = false;
  710.  
  711.             for(int i = 0;i < len;i++) {
  712.                 char c = s[i];
  713.                 if(state == 0) {
  714.                     if(c == '&') {
  715.                         entity.Append(c);
  716.                         state = 1;
  717.                     }
  718.                     else {
  719.                         output.Append(c);
  720.                     }
  721.                     continue;
  722.                 }
  723.  
  724.                 if(c == '&') {
  725.                     state = 1;
  726.                     if(have_trailing_digits) {
  727.                         entity.Append(number.ToString(CultureInfo.InvariantCulture));
  728.                         have_trailing_digits = false;
  729.                     }
  730.  
  731.                     output.Append(entity.ToString());
  732.                     entity.Length = 0;
  733.                     entity.Append('&');
  734.                     continue;
  735.                 }
  736.  
  737.                 if(state == 1) {
  738.                     if(c == ';') {
  739.                         state = 0;
  740.                         output.Append(entity.ToString());
  741.                         output.Append(c);
  742.                         entity.Length = 0;
  743.                     }
  744.                     else {
  745.                         number = 0;
  746.                         if(c != '#') {
  747.                             state = 2;
  748.                         }
  749.                         else {
  750.                             state = 3;
  751.                         }
  752.                         entity.Append(c);
  753.                     }
  754.                 }
  755.                 else if(state == 2) {
  756.                     entity.Append(c);
  757.                     if(c == ';') {
  758.                         string key = entity.ToString();
  759.                         if(key.Length > 1 && Entities.ContainsKey(key.Substring(1,key.Length - 2)))
  760.                             key = Entities[key.Substring(1,key.Length - 2)].ToString();
  761.  
  762.                         output.Append(key);
  763.                         state = 0;
  764.                         entity.Length = 0;
  765.                     }
  766.                 }
  767.                 else if(state == 3) {
  768.                     if(c == ';') {
  769.                         if(number > 65535) {
  770.                             output.Append("&#");
  771.                             output.Append(number.ToString(CultureInfo.InvariantCulture));
  772.                             output.Append(";");
  773.                         }
  774.                         else {
  775.                             output.Append((char)number);
  776.                         }
  777.                         state = 0;
  778.                         entity.Length = 0;
  779.                         have_trailing_digits = false;
  780.                     }
  781.                     else if(Char.IsDigit(c)) {
  782.                         number = number * 10 + ((int)c - '0');
  783.                         have_trailing_digits = true;
  784.                     }
  785.                     else {
  786.                         state = 2;
  787.                         if(have_trailing_digits) {
  788.                             entity.Append(number.ToString(CultureInfo.InvariantCulture));
  789.                             have_trailing_digits = false;
  790.                         }
  791.                         entity.Append(c);
  792.                     }
  793.                 }
  794.             }
  795.  
  796.             if(entity.Length > 0) {
  797.                 output.Append(entity.ToString());
  798.             }
  799.             else if(have_trailing_digits) {
  800.                 output.Append(number.ToString(CultureInfo.InvariantCulture));
  801.             }
  802.             return output.ToString();
  803.         }
  804.  
  805.         /// <summary>
  806.         /// Decodes an HTML-encoded string and sends the resulting output to a TextWriter output stream.
  807.         /// </summary>
  808.         /// <param name="s">The HTML string to decode</param>
  809.         /// <param name="output">The TextWriter output stream containing the decoded string. </param>
  810.         public static void HtmlDecode(string s,TextWriter output) {
  811.             if(s != null)
  812.                 output.Write(HtmlDecode(s));
  813.         }
  814.  
  815.         /// <summary>
  816.         /// HTML-encodes a string and returns the encoded string.
  817.         /// </summary>
  818.         /// <param name="s">The text string to encode. </param>
  819.         /// <returns>The HTML-encoded text.</returns>
  820.         public static string HtmlEncode(string s) {
  821.             if(s == null)
  822.                 return null;
  823.  
  824.             StringBuilder output = new StringBuilder();
  825.  
  826.             foreach(char c in s)
  827.                 switch(c) {
  828.                     case '&':
  829.                         output.Append("&amp;");
  830.                         break;
  831.                     case '>':
  832.                         output.Append("&gt;");
  833.                         break;
  834.                     case '<':
  835.                         output.Append("&lt;");
  836.                         break;
  837.                     case '"':
  838.                         output.Append("&quot;");
  839.                         break;
  840.                     default:
  841.                         // MS starts encoding with &# from 160 and stops at 255.
  842.                         // We don't do that. One reason is the 65308/65310 unicode
  843.                         // characters that look like '<' and '>'.
  844.                         if(c > 159) {
  845.                             output.Append("&#");
  846.                             output.Append(((int)c).ToString(CultureInfo.InvariantCulture));
  847.                             output.Append(";");
  848.                         }
  849.                         else {
  850.                             output.Append(c);
  851.                         }
  852.                         break;
  853.                 }
  854.             return output.ToString();
  855.         }
  856.  
  857.         /// <summary>
  858.         /// HTML-encodes a string and sends the resulting output to a TextWriter output stream.
  859.         /// </summary>
  860.         /// <param name="s">The string to encode. </param>
  861.         /// <param name="output">The TextWriter output stream containing the encoded string. </param>
  862.         public static void HtmlEncode(string s,TextWriter output) {
  863.             if(s != null)
  864.                 output.Write(HtmlEncode(s));
  865.         }
  866.  
  867. #if  NET_1_1
  868.         public static string UrlPathEncode (string s)
  869.         {
  870.             if (s == null || s.Length == 0)
  871.                 return s;
  872.  
  873.             MemoryStream result = new MemoryStream ();
  874.             int length = s.Length;
  875.              for (int i = 0; i < length; i++) {
  876.                 UrlPathEncodeChar (s [i], result);
  877.             }
  878.             return Encoding.ASCII.GetString (result.ToArray ());
  879.         }
  880.          
  881.         static void UrlPathEncodeChar (char c, Stream result) {
  882.             if (c > 127) {
  883.                 byte [] bIn = Encoding.UTF8.GetBytes (c.ToString ());
  884.                 for (int i = 0; i < bIn.Length; i++) {
  885.                     result.WriteByte ((byte) '%');
  886.                     int idx = ((int) bIn [i]) >> 4;
  887.                     result.WriteByte ((byte) hexChars [idx]);
  888.                     idx = ((int) bIn [i]) & 0x0F;
  889.                     result.WriteByte ((byte) hexChars [idx]);
  890.                 }
  891.             }
  892.             else if (c == ' ') {
  893.                 result.WriteByte ((byte) '%');
  894.                 result.WriteByte ((byte) '2');
  895.                 result.WriteByte ((byte) '0');
  896.             }
  897.             else
  898.                 result.WriteByte ((byte) c);
  899.         }
  900. #endif
  901.  
  902. #if  !NET_2_0
  903.         public static NameValueCollection ParseQueryString(string query) {
  904.             return ParseQueryString(query,Encoding.UTF8);
  905.         }
  906.  
  907.         public static NameValueCollection ParseQueryString(string query,Encoding encoding) {
  908.             if(query == null)
  909.                 throw new ArgumentNullException("query");
  910.             if(encoding == null)
  911.                 throw new ArgumentNullException("encoding");
  912.             if(query.Length == 0 || (query.Length == 1 && query[0] == '?'))
  913.                 return new NameValueCollection();
  914.             if(query[0] == '?')
  915.                 query = query.Substring(1);
  916.  
  917.             NameValueCollection result = new NameValueCollection();
  918.             ParseQueryString(query,encoding,result);
  919.             return result;
  920.         }
  921. #endif
  922.  
  923.         internal static void ParseQueryString(string query,Encoding encoding,NameValueCollection result) {
  924.             if(query.Length == 0)
  925.                 return;
  926.  
  927.             int namePos = 0;
  928.             while(namePos <= query.Length) {
  929.                 int valuePos = -1,valueEnd = -1;
  930.                 for(int q = namePos;q < query.Length;q++) {
  931.                     if(valuePos == -1 && query[q] == '=') {
  932.                         valuePos = q + 1;
  933.                     }
  934.                     else if(query[q] == '&') {
  935.                         valueEnd = q;
  936.                         break;
  937.                     }
  938.                 }
  939.  
  940.                 string name,value;
  941.                 if(valuePos == -1) {
  942.                     name = null;
  943.                     valuePos = namePos;
  944.                 }
  945.                 else {
  946.                     name = UrlDecode(query.Substring(namePos,valuePos - namePos - 1),encoding);
  947.                 }
  948.                 if(valueEnd < 0) {
  949.                     namePos = -1;
  950.                     valueEnd = query.Length;
  951.                 }
  952.                 else {
  953.                     namePos = valueEnd + 1;
  954.                 }
  955.                 value = UrlDecode(query.Substring(valuePos,valueEnd - valuePos),encoding);
  956.  
  957.                 result.Add(name,value);
  958.                 if(namePos == -1)
  959.                     break;
  960.             }
  961.         }
  962.         #endregion  // Methods
  963.     }
  964. }
  965.  
  966. //#endif
Advertisement
Add Comment
Please, Sign In to add comment