diff --git a/websocket-sharp/Net/HttpUtility.cs b/websocket-sharp/Net/HttpUtility.cs index 64f10bac..871d32f7 100644 --- a/websocket-sharp/Net/HttpUtility.cs +++ b/websocket-sharp/Net/HttpUtility.cs @@ -1,3 +1,4 @@ +#region License // // HttpUtility.cs // Copied from System.Net.HttpUtility.cs @@ -9,6 +10,7 @@ // Gonzalo Paniagua Javier (gonzalo@ximian.com) // // Copyright (C) 2005-2009 Novell, Inc (http://www.novell.com) +// Copyright (c) 2012-2013 sta.blockhead (sta.blockhead@gmail.com) // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the @@ -29,6 +31,7 @@ // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // +#endregion using System; using System.Collections; @@ -36,8 +39,6 @@ using System.Collections.Generic; using System.Collections.Specialized; using System.Globalization; using System.IO; -using System.Net; -using System.Security.Permissions; using System.Text; namespace WebSocketSharp.Net { @@ -48,62 +49,54 @@ namespace WebSocketSharp.Net { { public override string ToString () { - int count = Count; + var count = Count; if (count == 0) - return ""; + return String.Empty; - StringBuilder sb = new StringBuilder (); - string [] keys = AllKeys; - for (int i = 0; i < count; i++) { - sb.AppendFormat ("{0}={1}&", keys [i], this [keys [i]]); - } + var output = new StringBuilder (); + var keys = AllKeys; + foreach (var key in keys) + output.AppendFormat ("{0}={1}&", key, this [key]); - if (sb.Length > 0) - sb.Length--; + if (output.Length > 0) + output.Length--; - return sb.ToString (); + return output.ToString (); } } - #region Fields - - static Hashtable entities; - static char [] hexChars = "0123456789abcdef".ToCharArray (); - static object lock_ = new object (); - - #endregion // Fields + #region Private Static Fields - #region Constructor + private static Dictionary _entities; + private static char [] _hexChars = "0123456789abcdef".ToCharArray (); + private static object _sync = new object (); - public HttpUtility () - { - } + #endregion - #endregion // Constructor + #region Private Static Properties - #region Property - - static Hashtable Entities { + private static Dictionary Entities { get { - lock (lock_) { - if (entities == null) + lock (_sync) { + if (_entities == null) InitEntities (); - return entities; + return _entities; } } } - #endregion // Property + #endregion #region Private Methods - static int GetChar (byte [] bytes, int offset, int length) + private static int GetChar (byte [] bytes, int offset, int length) { - int value = 0; - int end = length + offset; + var value = 0; + var end = length + offset; + int current; for (int i = offset; i < end; i++) { - int current = GetInt (bytes [i]); + current = GetInt (bytes [i]); if (current == -1) return -1; @@ -113,338 +106,343 @@ namespace WebSocketSharp.Net { return value; } - static int GetChar (string str, int offset, int length) + private static int GetChar (string s, int offset, int length) { - int val = 0; - int end = length + offset; + var value = 0; + var end = length + offset; + char c; + int current; for (int i = offset; i < end; i++) { - char c = str [i]; + c = s [i]; if (c > 127) return -1; - int current = GetInt ((byte) c); + current = GetInt ((byte) c); if (current == -1) return -1; - val = (val << 4) + current; + value = (value << 4) + current; } - return val; + return value; } - static char [] GetChars (MemoryStream b, Encoding e) + private static char [] GetChars (MemoryStream buffer, Encoding encoding) { - return e.GetChars (b.GetBuffer (), 0, (int) b.Length); + return encoding.GetChars (buffer.GetBuffer (), 0, (int) buffer.Length); } - static int GetInt (byte b) + private static int GetInt (byte b) { - char c = (char) b; - if (c >= '0' && c <= '9') - return c - '0'; - - if (c >= 'a' && c <= 'f') - return c - 'a' + 10; - - if (c >= 'A' && c <= 'F') - return c - 'A' + 10; - - return -1; + var c = (char) b; + return c >= '0' && c <= '9' + ? c - '0' + : c >= 'a' && c <= 'f' + ? c - 'a' + 10 + : c >= 'A' && c <= 'F' + ? c - 'A' + 10 + : -1; } - static void InitEntities () + private static void InitEntities () { - // Build the hash table of HTML entity references. This list comes - // from the HTML 4.01 W3C recommendation. - entities = new Hashtable (); - entities.Add ("nbsp", '\u00A0'); - entities.Add ("iexcl", '\u00A1'); - entities.Add ("cent", '\u00A2'); - entities.Add ("pound", '\u00A3'); - entities.Add ("curren", '\u00A4'); - entities.Add ("yen", '\u00A5'); - entities.Add ("brvbar", '\u00A6'); - entities.Add ("sect", '\u00A7'); - entities.Add ("uml", '\u00A8'); - entities.Add ("copy", '\u00A9'); - entities.Add ("ordf", '\u00AA'); - entities.Add ("laquo", '\u00AB'); - entities.Add ("not", '\u00AC'); - entities.Add ("shy", '\u00AD'); - entities.Add ("reg", '\u00AE'); - entities.Add ("macr", '\u00AF'); - entities.Add ("deg", '\u00B0'); - entities.Add ("plusmn", '\u00B1'); - entities.Add ("sup2", '\u00B2'); - entities.Add ("sup3", '\u00B3'); - entities.Add ("acute", '\u00B4'); - entities.Add ("micro", '\u00B5'); - entities.Add ("para", '\u00B6'); - entities.Add ("middot", '\u00B7'); - entities.Add ("cedil", '\u00B8'); - entities.Add ("sup1", '\u00B9'); - entities.Add ("ordm", '\u00BA'); - entities.Add ("raquo", '\u00BB'); - entities.Add ("frac14", '\u00BC'); - entities.Add ("frac12", '\u00BD'); - entities.Add ("frac34", '\u00BE'); - entities.Add ("iquest", '\u00BF'); - entities.Add ("Agrave", '\u00C0'); - entities.Add ("Aacute", '\u00C1'); - entities.Add ("Acirc", '\u00C2'); - entities.Add ("Atilde", '\u00C3'); - entities.Add ("Auml", '\u00C4'); - entities.Add ("Aring", '\u00C5'); - entities.Add ("AElig", '\u00C6'); - entities.Add ("Ccedil", '\u00C7'); - entities.Add ("Egrave", '\u00C8'); - entities.Add ("Eacute", '\u00C9'); - entities.Add ("Ecirc", '\u00CA'); - entities.Add ("Euml", '\u00CB'); - entities.Add ("Igrave", '\u00CC'); - entities.Add ("Iacute", '\u00CD'); - entities.Add ("Icirc", '\u00CE'); - entities.Add ("Iuml", '\u00CF'); - entities.Add ("ETH", '\u00D0'); - entities.Add ("Ntilde", '\u00D1'); - entities.Add ("Ograve", '\u00D2'); - entities.Add ("Oacute", '\u00D3'); - entities.Add ("Ocirc", '\u00D4'); - entities.Add ("Otilde", '\u00D5'); - entities.Add ("Ouml", '\u00D6'); - entities.Add ("times", '\u00D7'); - entities.Add ("Oslash", '\u00D8'); - entities.Add ("Ugrave", '\u00D9'); - entities.Add ("Uacute", '\u00DA'); - entities.Add ("Ucirc", '\u00DB'); - entities.Add ("Uuml", '\u00DC'); - entities.Add ("Yacute", '\u00DD'); - entities.Add ("THORN", '\u00DE'); - entities.Add ("szlig", '\u00DF'); - entities.Add ("agrave", '\u00E0'); - entities.Add ("aacute", '\u00E1'); - entities.Add ("acirc", '\u00E2'); - entities.Add ("atilde", '\u00E3'); - entities.Add ("auml", '\u00E4'); - entities.Add ("aring", '\u00E5'); - entities.Add ("aelig", '\u00E6'); - entities.Add ("ccedil", '\u00E7'); - entities.Add ("egrave", '\u00E8'); - entities.Add ("eacute", '\u00E9'); - entities.Add ("ecirc", '\u00EA'); - entities.Add ("euml", '\u00EB'); - entities.Add ("igrave", '\u00EC'); - entities.Add ("iacute", '\u00ED'); - entities.Add ("icirc", '\u00EE'); - entities.Add ("iuml", '\u00EF'); - entities.Add ("eth", '\u00F0'); - entities.Add ("ntilde", '\u00F1'); - entities.Add ("ograve", '\u00F2'); - entities.Add ("oacute", '\u00F3'); - entities.Add ("ocirc", '\u00F4'); - entities.Add ("otilde", '\u00F5'); - entities.Add ("ouml", '\u00F6'); - entities.Add ("divide", '\u00F7'); - entities.Add ("oslash", '\u00F8'); - entities.Add ("ugrave", '\u00F9'); - entities.Add ("uacute", '\u00FA'); - entities.Add ("ucirc", '\u00FB'); - entities.Add ("uuml", '\u00FC'); - entities.Add ("yacute", '\u00FD'); - entities.Add ("thorn", '\u00FE'); - entities.Add ("yuml", '\u00FF'); - entities.Add ("fnof", '\u0192'); - entities.Add ("Alpha", '\u0391'); - entities.Add ("Beta", '\u0392'); - entities.Add ("Gamma", '\u0393'); - entities.Add ("Delta", '\u0394'); - entities.Add ("Epsilon", '\u0395'); - entities.Add ("Zeta", '\u0396'); - entities.Add ("Eta", '\u0397'); - entities.Add ("Theta", '\u0398'); - entities.Add ("Iota", '\u0399'); - entities.Add ("Kappa", '\u039A'); - entities.Add ("Lambda", '\u039B'); - entities.Add ("Mu", '\u039C'); - entities.Add ("Nu", '\u039D'); - entities.Add ("Xi", '\u039E'); - entities.Add ("Omicron", '\u039F'); - entities.Add ("Pi", '\u03A0'); - entities.Add ("Rho", '\u03A1'); - entities.Add ("Sigma", '\u03A3'); - entities.Add ("Tau", '\u03A4'); - entities.Add ("Upsilon", '\u03A5'); - entities.Add ("Phi", '\u03A6'); - entities.Add ("Chi", '\u03A7'); - entities.Add ("Psi", '\u03A8'); - entities.Add ("Omega", '\u03A9'); - entities.Add ("alpha", '\u03B1'); - entities.Add ("beta", '\u03B2'); - entities.Add ("gamma", '\u03B3'); - entities.Add ("delta", '\u03B4'); - entities.Add ("epsilon", '\u03B5'); - entities.Add ("zeta", '\u03B6'); - entities.Add ("eta", '\u03B7'); - entities.Add ("theta", '\u03B8'); - entities.Add ("iota", '\u03B9'); - entities.Add ("kappa", '\u03BA'); - entities.Add ("lambda", '\u03BB'); - entities.Add ("mu", '\u03BC'); - entities.Add ("nu", '\u03BD'); - entities.Add ("xi", '\u03BE'); - entities.Add ("omicron", '\u03BF'); - entities.Add ("pi", '\u03C0'); - entities.Add ("rho", '\u03C1'); - entities.Add ("sigmaf", '\u03C2'); - entities.Add ("sigma", '\u03C3'); - entities.Add ("tau", '\u03C4'); - entities.Add ("upsilon", '\u03C5'); - entities.Add ("phi", '\u03C6'); - entities.Add ("chi", '\u03C7'); - entities.Add ("psi", '\u03C8'); - entities.Add ("omega", '\u03C9'); - entities.Add ("thetasym", '\u03D1'); - entities.Add ("upsih", '\u03D2'); - entities.Add ("piv", '\u03D6'); - entities.Add ("bull", '\u2022'); - entities.Add ("hellip", '\u2026'); - entities.Add ("prime", '\u2032'); - entities.Add ("Prime", '\u2033'); - entities.Add ("oline", '\u203E'); - entities.Add ("frasl", '\u2044'); - entities.Add ("weierp", '\u2118'); - entities.Add ("image", '\u2111'); - entities.Add ("real", '\u211C'); - entities.Add ("trade", '\u2122'); - entities.Add ("alefsym", '\u2135'); - entities.Add ("larr", '\u2190'); - entities.Add ("uarr", '\u2191'); - entities.Add ("rarr", '\u2192'); - entities.Add ("darr", '\u2193'); - entities.Add ("harr", '\u2194'); - entities.Add ("crarr", '\u21B5'); - entities.Add ("lArr", '\u21D0'); - entities.Add ("uArr", '\u21D1'); - entities.Add ("rArr", '\u21D2'); - entities.Add ("dArr", '\u21D3'); - entities.Add ("hArr", '\u21D4'); - entities.Add ("forall", '\u2200'); - entities.Add ("part", '\u2202'); - entities.Add ("exist", '\u2203'); - entities.Add ("empty", '\u2205'); - entities.Add ("nabla", '\u2207'); - entities.Add ("isin", '\u2208'); - entities.Add ("notin", '\u2209'); - entities.Add ("ni", '\u220B'); - entities.Add ("prod", '\u220F'); - entities.Add ("sum", '\u2211'); - entities.Add ("minus", '\u2212'); - entities.Add ("lowast", '\u2217'); - entities.Add ("radic", '\u221A'); - entities.Add ("prop", '\u221D'); - entities.Add ("infin", '\u221E'); - entities.Add ("ang", '\u2220'); - entities.Add ("and", '\u2227'); - entities.Add ("or", '\u2228'); - entities.Add ("cap", '\u2229'); - entities.Add ("cup", '\u222A'); - entities.Add ("int", '\u222B'); - entities.Add ("there4", '\u2234'); - entities.Add ("sim", '\u223C'); - entities.Add ("cong", '\u2245'); - entities.Add ("asymp", '\u2248'); - entities.Add ("ne", '\u2260'); - entities.Add ("equiv", '\u2261'); - entities.Add ("le", '\u2264'); - entities.Add ("ge", '\u2265'); - entities.Add ("sub", '\u2282'); - entities.Add ("sup", '\u2283'); - entities.Add ("nsub", '\u2284'); - entities.Add ("sube", '\u2286'); - entities.Add ("supe", '\u2287'); - entities.Add ("oplus", '\u2295'); - entities.Add ("otimes", '\u2297'); - entities.Add ("perp", '\u22A5'); - entities.Add ("sdot", '\u22C5'); - entities.Add ("lceil", '\u2308'); - entities.Add ("rceil", '\u2309'); - entities.Add ("lfloor", '\u230A'); - entities.Add ("rfloor", '\u230B'); - entities.Add ("lang", '\u2329'); - entities.Add ("rang", '\u232A'); - entities.Add ("loz", '\u25CA'); - entities.Add ("spades", '\u2660'); - entities.Add ("clubs", '\u2663'); - entities.Add ("hearts", '\u2665'); - entities.Add ("diams", '\u2666'); - entities.Add ("quot", '\u0022'); - entities.Add ("amp", '\u0026'); - entities.Add ("lt", '\u003C'); - entities.Add ("gt", '\u003E'); - entities.Add ("OElig", '\u0152'); - entities.Add ("oelig", '\u0153'); - entities.Add ("Scaron", '\u0160'); - entities.Add ("scaron", '\u0161'); - entities.Add ("Yuml", '\u0178'); - entities.Add ("circ", '\u02C6'); - entities.Add ("tilde", '\u02DC'); - entities.Add ("ensp", '\u2002'); - entities.Add ("emsp", '\u2003'); - entities.Add ("thinsp", '\u2009'); - entities.Add ("zwnj", '\u200C'); - entities.Add ("zwj", '\u200D'); - entities.Add ("lrm", '\u200E'); - entities.Add ("rlm", '\u200F'); - entities.Add ("ndash", '\u2013'); - entities.Add ("mdash", '\u2014'); - entities.Add ("lsquo", '\u2018'); - entities.Add ("rsquo", '\u2019'); - entities.Add ("sbquo", '\u201A'); - entities.Add ("ldquo", '\u201C'); - entities.Add ("rdquo", '\u201D'); - entities.Add ("bdquo", '\u201E'); - entities.Add ("dagger", '\u2020'); - entities.Add ("Dagger", '\u2021'); - entities.Add ("permil", '\u2030'); - entities.Add ("lsaquo", '\u2039'); - entities.Add ("rsaquo", '\u203A'); - entities.Add ("euro", '\u20AC'); + // Build the dictionary of HTML entity references. + // This list comes from the HTML 4.01 W3C recommendation. + _entities = new Dictionary (); + _entities.Add ("nbsp", '\u00A0'); + _entities.Add ("iexcl", '\u00A1'); + _entities.Add ("cent", '\u00A2'); + _entities.Add ("pound", '\u00A3'); + _entities.Add ("curren", '\u00A4'); + _entities.Add ("yen", '\u00A5'); + _entities.Add ("brvbar", '\u00A6'); + _entities.Add ("sect", '\u00A7'); + _entities.Add ("uml", '\u00A8'); + _entities.Add ("copy", '\u00A9'); + _entities.Add ("ordf", '\u00AA'); + _entities.Add ("laquo", '\u00AB'); + _entities.Add ("not", '\u00AC'); + _entities.Add ("shy", '\u00AD'); + _entities.Add ("reg", '\u00AE'); + _entities.Add ("macr", '\u00AF'); + _entities.Add ("deg", '\u00B0'); + _entities.Add ("plusmn", '\u00B1'); + _entities.Add ("sup2", '\u00B2'); + _entities.Add ("sup3", '\u00B3'); + _entities.Add ("acute", '\u00B4'); + _entities.Add ("micro", '\u00B5'); + _entities.Add ("para", '\u00B6'); + _entities.Add ("middot", '\u00B7'); + _entities.Add ("cedil", '\u00B8'); + _entities.Add ("sup1", '\u00B9'); + _entities.Add ("ordm", '\u00BA'); + _entities.Add ("raquo", '\u00BB'); + _entities.Add ("frac14", '\u00BC'); + _entities.Add ("frac12", '\u00BD'); + _entities.Add ("frac34", '\u00BE'); + _entities.Add ("iquest", '\u00BF'); + _entities.Add ("Agrave", '\u00C0'); + _entities.Add ("Aacute", '\u00C1'); + _entities.Add ("Acirc", '\u00C2'); + _entities.Add ("Atilde", '\u00C3'); + _entities.Add ("Auml", '\u00C4'); + _entities.Add ("Aring", '\u00C5'); + _entities.Add ("AElig", '\u00C6'); + _entities.Add ("Ccedil", '\u00C7'); + _entities.Add ("Egrave", '\u00C8'); + _entities.Add ("Eacute", '\u00C9'); + _entities.Add ("Ecirc", '\u00CA'); + _entities.Add ("Euml", '\u00CB'); + _entities.Add ("Igrave", '\u00CC'); + _entities.Add ("Iacute", '\u00CD'); + _entities.Add ("Icirc", '\u00CE'); + _entities.Add ("Iuml", '\u00CF'); + _entities.Add ("ETH", '\u00D0'); + _entities.Add ("Ntilde", '\u00D1'); + _entities.Add ("Ograve", '\u00D2'); + _entities.Add ("Oacute", '\u00D3'); + _entities.Add ("Ocirc", '\u00D4'); + _entities.Add ("Otilde", '\u00D5'); + _entities.Add ("Ouml", '\u00D6'); + _entities.Add ("times", '\u00D7'); + _entities.Add ("Oslash", '\u00D8'); + _entities.Add ("Ugrave", '\u00D9'); + _entities.Add ("Uacute", '\u00DA'); + _entities.Add ("Ucirc", '\u00DB'); + _entities.Add ("Uuml", '\u00DC'); + _entities.Add ("Yacute", '\u00DD'); + _entities.Add ("THORN", '\u00DE'); + _entities.Add ("szlig", '\u00DF'); + _entities.Add ("agrave", '\u00E0'); + _entities.Add ("aacute", '\u00E1'); + _entities.Add ("acirc", '\u00E2'); + _entities.Add ("atilde", '\u00E3'); + _entities.Add ("auml", '\u00E4'); + _entities.Add ("aring", '\u00E5'); + _entities.Add ("aelig", '\u00E6'); + _entities.Add ("ccedil", '\u00E7'); + _entities.Add ("egrave", '\u00E8'); + _entities.Add ("eacute", '\u00E9'); + _entities.Add ("ecirc", '\u00EA'); + _entities.Add ("euml", '\u00EB'); + _entities.Add ("igrave", '\u00EC'); + _entities.Add ("iacute", '\u00ED'); + _entities.Add ("icirc", '\u00EE'); + _entities.Add ("iuml", '\u00EF'); + _entities.Add ("eth", '\u00F0'); + _entities.Add ("ntilde", '\u00F1'); + _entities.Add ("ograve", '\u00F2'); + _entities.Add ("oacute", '\u00F3'); + _entities.Add ("ocirc", '\u00F4'); + _entities.Add ("otilde", '\u00F5'); + _entities.Add ("ouml", '\u00F6'); + _entities.Add ("divide", '\u00F7'); + _entities.Add ("oslash", '\u00F8'); + _entities.Add ("ugrave", '\u00F9'); + _entities.Add ("uacute", '\u00FA'); + _entities.Add ("ucirc", '\u00FB'); + _entities.Add ("uuml", '\u00FC'); + _entities.Add ("yacute", '\u00FD'); + _entities.Add ("thorn", '\u00FE'); + _entities.Add ("yuml", '\u00FF'); + _entities.Add ("fnof", '\u0192'); + _entities.Add ("Alpha", '\u0391'); + _entities.Add ("Beta", '\u0392'); + _entities.Add ("Gamma", '\u0393'); + _entities.Add ("Delta", '\u0394'); + _entities.Add ("Epsilon", '\u0395'); + _entities.Add ("Zeta", '\u0396'); + _entities.Add ("Eta", '\u0397'); + _entities.Add ("Theta", '\u0398'); + _entities.Add ("Iota", '\u0399'); + _entities.Add ("Kappa", '\u039A'); + _entities.Add ("Lambda", '\u039B'); + _entities.Add ("Mu", '\u039C'); + _entities.Add ("Nu", '\u039D'); + _entities.Add ("Xi", '\u039E'); + _entities.Add ("Omicron", '\u039F'); + _entities.Add ("Pi", '\u03A0'); + _entities.Add ("Rho", '\u03A1'); + _entities.Add ("Sigma", '\u03A3'); + _entities.Add ("Tau", '\u03A4'); + _entities.Add ("Upsilon", '\u03A5'); + _entities.Add ("Phi", '\u03A6'); + _entities.Add ("Chi", '\u03A7'); + _entities.Add ("Psi", '\u03A8'); + _entities.Add ("Omega", '\u03A9'); + _entities.Add ("alpha", '\u03B1'); + _entities.Add ("beta", '\u03B2'); + _entities.Add ("gamma", '\u03B3'); + _entities.Add ("delta", '\u03B4'); + _entities.Add ("epsilon", '\u03B5'); + _entities.Add ("zeta", '\u03B6'); + _entities.Add ("eta", '\u03B7'); + _entities.Add ("theta", '\u03B8'); + _entities.Add ("iota", '\u03B9'); + _entities.Add ("kappa", '\u03BA'); + _entities.Add ("lambda", '\u03BB'); + _entities.Add ("mu", '\u03BC'); + _entities.Add ("nu", '\u03BD'); + _entities.Add ("xi", '\u03BE'); + _entities.Add ("omicron", '\u03BF'); + _entities.Add ("pi", '\u03C0'); + _entities.Add ("rho", '\u03C1'); + _entities.Add ("sigmaf", '\u03C2'); + _entities.Add ("sigma", '\u03C3'); + _entities.Add ("tau", '\u03C4'); + _entities.Add ("upsilon", '\u03C5'); + _entities.Add ("phi", '\u03C6'); + _entities.Add ("chi", '\u03C7'); + _entities.Add ("psi", '\u03C8'); + _entities.Add ("omega", '\u03C9'); + _entities.Add ("thetasym", '\u03D1'); + _entities.Add ("upsih", '\u03D2'); + _entities.Add ("piv", '\u03D6'); + _entities.Add ("bull", '\u2022'); + _entities.Add ("hellip", '\u2026'); + _entities.Add ("prime", '\u2032'); + _entities.Add ("Prime", '\u2033'); + _entities.Add ("oline", '\u203E'); + _entities.Add ("frasl", '\u2044'); + _entities.Add ("weierp", '\u2118'); + _entities.Add ("image", '\u2111'); + _entities.Add ("real", '\u211C'); + _entities.Add ("trade", '\u2122'); + _entities.Add ("alefsym", '\u2135'); + _entities.Add ("larr", '\u2190'); + _entities.Add ("uarr", '\u2191'); + _entities.Add ("rarr", '\u2192'); + _entities.Add ("darr", '\u2193'); + _entities.Add ("harr", '\u2194'); + _entities.Add ("crarr", '\u21B5'); + _entities.Add ("lArr", '\u21D0'); + _entities.Add ("uArr", '\u21D1'); + _entities.Add ("rArr", '\u21D2'); + _entities.Add ("dArr", '\u21D3'); + _entities.Add ("hArr", '\u21D4'); + _entities.Add ("forall", '\u2200'); + _entities.Add ("part", '\u2202'); + _entities.Add ("exist", '\u2203'); + _entities.Add ("empty", '\u2205'); + _entities.Add ("nabla", '\u2207'); + _entities.Add ("isin", '\u2208'); + _entities.Add ("notin", '\u2209'); + _entities.Add ("ni", '\u220B'); + _entities.Add ("prod", '\u220F'); + _entities.Add ("sum", '\u2211'); + _entities.Add ("minus", '\u2212'); + _entities.Add ("lowast", '\u2217'); + _entities.Add ("radic", '\u221A'); + _entities.Add ("prop", '\u221D'); + _entities.Add ("infin", '\u221E'); + _entities.Add ("ang", '\u2220'); + _entities.Add ("and", '\u2227'); + _entities.Add ("or", '\u2228'); + _entities.Add ("cap", '\u2229'); + _entities.Add ("cup", '\u222A'); + _entities.Add ("int", '\u222B'); + _entities.Add ("there4", '\u2234'); + _entities.Add ("sim", '\u223C'); + _entities.Add ("cong", '\u2245'); + _entities.Add ("asymp", '\u2248'); + _entities.Add ("ne", '\u2260'); + _entities.Add ("equiv", '\u2261'); + _entities.Add ("le", '\u2264'); + _entities.Add ("ge", '\u2265'); + _entities.Add ("sub", '\u2282'); + _entities.Add ("sup", '\u2283'); + _entities.Add ("nsub", '\u2284'); + _entities.Add ("sube", '\u2286'); + _entities.Add ("supe", '\u2287'); + _entities.Add ("oplus", '\u2295'); + _entities.Add ("otimes", '\u2297'); + _entities.Add ("perp", '\u22A5'); + _entities.Add ("sdot", '\u22C5'); + _entities.Add ("lceil", '\u2308'); + _entities.Add ("rceil", '\u2309'); + _entities.Add ("lfloor", '\u230A'); + _entities.Add ("rfloor", '\u230B'); + _entities.Add ("lang", '\u2329'); + _entities.Add ("rang", '\u232A'); + _entities.Add ("loz", '\u25CA'); + _entities.Add ("spades", '\u2660'); + _entities.Add ("clubs", '\u2663'); + _entities.Add ("hearts", '\u2665'); + _entities.Add ("diams", '\u2666'); + _entities.Add ("quot", '\u0022'); + _entities.Add ("amp", '\u0026'); + _entities.Add ("lt", '\u003C'); + _entities.Add ("gt", '\u003E'); + _entities.Add ("OElig", '\u0152'); + _entities.Add ("oelig", '\u0153'); + _entities.Add ("Scaron", '\u0160'); + _entities.Add ("scaron", '\u0161'); + _entities.Add ("Yuml", '\u0178'); + _entities.Add ("circ", '\u02C6'); + _entities.Add ("tilde", '\u02DC'); + _entities.Add ("ensp", '\u2002'); + _entities.Add ("emsp", '\u2003'); + _entities.Add ("thinsp", '\u2009'); + _entities.Add ("zwnj", '\u200C'); + _entities.Add ("zwj", '\u200D'); + _entities.Add ("lrm", '\u200E'); + _entities.Add ("rlm", '\u200F'); + _entities.Add ("ndash", '\u2013'); + _entities.Add ("mdash", '\u2014'); + _entities.Add ("lsquo", '\u2018'); + _entities.Add ("rsquo", '\u2019'); + _entities.Add ("sbquo", '\u201A'); + _entities.Add ("ldquo", '\u201C'); + _entities.Add ("rdquo", '\u201D'); + _entities.Add ("bdquo", '\u201E'); + _entities.Add ("dagger", '\u2020'); + _entities.Add ("Dagger", '\u2021'); + _entities.Add ("permil", '\u2030'); + _entities.Add ("lsaquo", '\u2039'); + _entities.Add ("rsaquo", '\u203A'); + _entities.Add ("euro", '\u20AC'); } - static bool NotEncoded (char c) + private static bool NotEncoded (char c) { - return (c == '!' || c == '\'' || c == '(' || c == ')' || c == '*' || c == '-' || c == '.' || c == '_'); + return c == '!' || + c == '\'' || + c == '(' || + c == ')' || + c == '*' || + c == '-' || + c == '.' || + c == '_'; } - static void UrlEncodeChar (char c, Stream result, bool isUnicode) + private static void UrlEncodeChar (char c, Stream result, bool isUnicode) { if (c > 255) { - // FIXME: what happens when there is an internal error ? + // FIXME: What happens when there is an internal error ? //if (!isUnicode) - // throw new ArgumentOutOfRangeException ("c", c, "c must be less than 256"); - int idx; - int i = (int) c; - - result.WriteByte ((byte)'%'); - result.WriteByte ((byte)'u'); - idx = i >> 12; - result.WriteByte ((byte)hexChars [idx]); + // throw new ArgumentOutOfRangeException ("c", c, "c must be less than 256."); + result.WriteByte ((byte) '%'); + result.WriteByte ((byte) 'u'); + var i = (int) c; + var idx = i >> 12; + result.WriteByte ((byte) _hexChars [idx]); idx = (i >> 8) & 0x0F; - result.WriteByte ((byte)hexChars [idx]); + result.WriteByte ((byte) _hexChars [idx]); idx = (i >> 4) & 0x0F; - result.WriteByte ((byte)hexChars [idx]); + result.WriteByte ((byte) _hexChars [idx]); idx = i & 0x0F; - result.WriteByte ((byte)hexChars [idx]); + result.WriteByte ((byte) _hexChars [idx]); + return; } if (c > ' ' && NotEncoded (c)) { - result.WriteByte ((byte)c); + result.WriteByte ((byte) c); return; } - if (c==' ') { - result.WriteByte ((byte)'+'); + if (c == ' ') { + result.WriteByte ((byte) '+'); return; } @@ -453,33 +451,34 @@ namespace WebSocketSharp.Net { (c > 'Z' && c < 'a') || (c > 'z')) { if (isUnicode && c > 127) { - result.WriteByte ((byte)'%'); - result.WriteByte ((byte)'u'); - result.WriteByte ((byte)'0'); - result.WriteByte ((byte)'0'); + result.WriteByte ((byte) '%'); + result.WriteByte ((byte) 'u'); + result.WriteByte ((byte) '0'); + result.WriteByte ((byte) '0'); } else - result.WriteByte ((byte)'%'); - - int idx = ((int) c) >> 4; - result.WriteByte ((byte)hexChars [idx]); + result.WriteByte ((byte) '%'); + + var idx = ((int) c) >> 4; + result.WriteByte ((byte) _hexChars [idx]); idx = ((int) c) & 0x0F; - result.WriteByte ((byte)hexChars [idx]); + result.WriteByte ((byte) _hexChars [idx]); } else - result.WriteByte ((byte)c); + result.WriteByte ((byte) c); } - static void UrlPathEncodeChar (char c, Stream result) + private static void UrlPathEncodeChar (char c, Stream result) { if (c < 33 || c > 126) { - byte [] bIn = Encoding.UTF8.GetBytes (c.ToString ()); - for (int i = 0; i < bIn.Length; i++) { + var bytes = Encoding.UTF8.GetBytes (c.ToString ()); + int i; + foreach (var b in bytes) { result.WriteByte ((byte) '%'); - int idx = ((int) bIn [i]) >> 4; - result.WriteByte ((byte) hexChars [idx]); - idx = ((int) bIn [i]) & 0x0F; - result.WriteByte ((byte) hexChars [idx]); + i = ((int) b) >> 4; + result.WriteByte ((byte) _hexChars [i]); + i = ((int) b) & 0x0F; + result.WriteByte ((byte) _hexChars [i]); } } else if (c == ' ') { @@ -491,34 +490,35 @@ namespace WebSocketSharp.Net { result.WriteByte ((byte) c); } - static void WriteCharBytes (IList buf, char ch, Encoding e) + private static void WriteCharBytes (IList buffer, char c, Encoding encoding) { - if (ch > 255) { - foreach (byte b in e.GetBytes (new char[] { ch })) - buf.Add (b); - } else - buf.Add ((byte)ch); + if (c > 255) + foreach (var b in encoding.GetBytes (new char[] { c })) + buffer.Add (b); + else + buffer.Add ((byte) c); } - #endregion // Private Methods + #endregion - #region Internal Method + #region Internal Methods internal static void ParseQueryString (string query, Encoding encoding, NameValueCollection result) { if (query.Length == 0) return; - string decoded = HtmlDecode (query); - int decodedLength = decoded.Length; - int namePos = 0; - bool first = true; + var decoded = HtmlDecode (query); + var decodedLength = decoded.Length; + var namePos = 0; + var first = true; while (namePos <= decodedLength) { int valuePos = -1, valueEnd = -1; for (int q = namePos; q < decodedLength; q++) { if (valuePos == -1 && decoded [q] == '=') { valuePos = q + 1; - } else if (decoded [q] == '&') { + } + else if (decoded [q] == '&') { valueEnd = q; break; } @@ -534,14 +534,16 @@ namespace WebSocketSharp.Net { if (valuePos == -1) { name = null; valuePos = namePos; - } else { + } + else { name = UrlDecode (decoded.Substring (namePos, valuePos - namePos - 1), encoding); } if (valueEnd < 0) { namePos = -1; valueEnd = decoded.Length; - } else { + } + else { namePos = valueEnd + 1; } @@ -552,98 +554,182 @@ namespace WebSocketSharp.Net { } } - #endregion // Internal Methods + internal static string UrlDecodeInternal (byte [] bytes, int offset, int count, Encoding encoding) + { + var output = new StringBuilder (); + var acc = new MemoryStream (); + var end = count + offset; + int xchar; + for (int i = offset; i < end; i++) { + if (bytes [i] == '%' && i + 2 < count && bytes [i + 1] != '%') { + if (bytes [i + 1] == (byte) 'u' && i + 5 < end) { + if (acc.Length > 0) { + output.Append (GetChars (acc, encoding)); + acc.SetLength (0); + } - #region Public Methods + xchar = GetChar (bytes, i + 2, 4); + if (xchar != -1) { + output.Append ((char) xchar); + i += 5; - public static string HtmlAttributeEncode (string s) + continue; + } + } + else if ((xchar = GetChar (bytes, i + 1, 2)) != -1) { + acc.WriteByte ((byte) xchar); + i += 2; + + continue; + } + } + + if (acc.Length > 0) { + output.Append (GetChars (acc, encoding)); + acc.SetLength (0); + } + + if (bytes [i] == '+') { + output.Append (' '); + } + else { + output.Append ((char) bytes [i]); + } + } + + if (acc.Length > 0) { + output.Append (GetChars (acc, encoding)); + } + + acc = null; + return output.ToString (); + } + + internal static byte [] UrlDecodeToBytesInternal (byte [] bytes, int offset, int count) { - if (null == s) - return null; - - bool needEncode = false; - for (int i = 0; i < s.Length; i++) { - if (s [i] == '&' || s [i] == '"' || s [i] == '<') { - needEncode = true; - break; + var result = new MemoryStream (); + var end = offset + count; + char c; + int xchar; + for (int i = offset; i < end; i++) { + c = (char) bytes [i]; + if (c == '+') { + c = ' '; } + else if (c == '%' && i < end - 2) { + xchar = GetChar (bytes, i + 1, 2); + if (xchar != -1) { + c = (char) xchar; + i += 2; + } + } + + result.WriteByte ((byte) c); } - if (!needEncode) + return result.ToArray (); + } + + internal static byte [] UrlEncodeToBytesInternal (byte [] bytes, int offset, int count) + { + var result = new MemoryStream (count); + var end = offset + count; + for (int i = offset; i < end; i++) + UrlEncodeChar ((char) bytes [i], result, false); + + return result.ToArray (); + } + + internal static byte [] UrlEncodeUnicodeToBytesInternal (string s) + { + var result = new MemoryStream (s.Length); + foreach (var c in s) + UrlEncodeChar (c, result, true); + + return result.ToArray (); + } + + #endregion + + #region Public Methods + + public static string HtmlAttributeEncode (string s) + { + if (s == null || s.Length == 0 || !s.Contains ('&', '"', '<', '>')) return s; - StringBuilder output = new StringBuilder (); - int len = s.Length; - for (int i = 0; i < len; i++) - switch (s [i]) { - case '&' : - output.Append ("&"); - break; - case '"' : - output.Append ("""); - break; - case '<': - output.Append ("<"); - break; - default: - output.Append (s [i]); - break; - } - - return output.ToString(); + var output = new StringBuilder (); + foreach (var c in s) + output.Append ( + c == '&' + ? "&" + : c == '"' + ? """ + : c == '<' + ? "<" + : c == '>' + ? ">" + : c.ToString () + ); + + return output.ToString (); } - public static void HtmlAttributeEncode (string s, TextWriter output) + public static void HtmlAttributeEncode (string s, TextWriter output) { - output.Write(HtmlAttributeEncode(s)); + if (output == null) + throw new ArgumentNullException ("output"); + + output.Write (HtmlAttributeEncode (s)); } /// - /// Decodes an HTML-encoded string and returns the decoded string. + /// Decodes an HTML-encoded and returns the decoded . /// - /// The HTML string to decode. - /// The decoded text. + /// + /// A that contains the decoded string. + /// + /// + /// A to decode. + /// public static string HtmlDecode (string s) { - if (s == null) - throw new ArgumentNullException ("s"); - - if (s.IndexOf ('&') == -1) + if (s == null || s.Length == 0 || !s.Contains ('&')) return s; - StringBuilder entity = new StringBuilder (); - StringBuilder output = new StringBuilder (); - int len = s.Length; + var entity = new StringBuilder (); + var output = new StringBuilder (); // 0 -> nothing, // 1 -> right after '&' // 2 -> between '&' and ';' but no '#' // 3 -> '#' found after '&' and getting numbers - int state = 0; - int number = 0; - bool have_trailing_digits = false; - - for (int i = 0; i < len; i++) { - char c = s [i]; + var state = 0; + var number = 0; + var haveTrailingDigits = false; + foreach (var c in s) { if (state == 0) { if (c == '&') { entity.Append (c); state = 1; - } else { + } + else { output.Append (c); } + continue; } if (c == '&') { state = 1; - if (have_trailing_digits) { + if (haveTrailingDigits) { entity.Append (number.ToString (CultureInfo.InvariantCulture)); - have_trailing_digits = false; + haveTrailingDigits = false; } output.Append (entity.ToString ()); entity.Length = 0; entity.Append ('&'); + continue; } @@ -653,19 +739,23 @@ namespace WebSocketSharp.Net { output.Append (entity.ToString ()); output.Append (c); entity.Length = 0; - } else { + } + else { number = 0; if (c != '#') { state = 2; - } else { + } + else { state = 3; } + entity.Append (c); } - } else if (state == 2) { + } + else if (state == 2) { entity.Append (c); if (c == ';') { - string key = entity.ToString (); + var key = entity.ToString (); if (key.Length > 1 && Entities.ContainsKey (key.Substring (1, key.Length - 2))) key = Entities [key.Substring (1, key.Length - 2)].ToString (); @@ -673,27 +763,33 @@ namespace WebSocketSharp.Net { state = 0; entity.Length = 0; } - } else if (state == 3) { + } + else if (state == 3) { if (c == ';') { if (number > 65535) { output.Append ("&#"); output.Append (number.ToString (CultureInfo.InvariantCulture)); output.Append (";"); - } else { + } + else { output.Append ((char) number); } + state = 0; entity.Length = 0; - have_trailing_digits = false; - } else if (Char.IsDigit (c)) { + haveTrailingDigits = false; + } + else if (Char.IsDigit (c)) { number = number * 10 + ((int) c - '0'); - have_trailing_digits = true; - } else { + haveTrailingDigits = true; + } + else { state = 2; - if (have_trailing_digits) { + if (haveTrailingDigits) { entity.Append (number.ToString (CultureInfo.InvariantCulture)); - have_trailing_digits = false; + haveTrailingDigits = false; } + entity.Append (c); } } @@ -701,7 +797,8 @@ namespace WebSocketSharp.Net { if (entity.Length > 0) { output.Append (entity.ToString ()); - } else if (have_trailing_digits) { + } + else if (haveTrailingDigits) { output.Append (number.ToString (CultureInfo.InvariantCulture)); } @@ -709,29 +806,39 @@ namespace WebSocketSharp.Net { } /// - /// Decodes an HTML-encoded string and sends the resulting output to a TextWriter output stream. + /// Decodes an HTML-encoded and sends the decoded + /// to a . /// - /// The HTML string to decode. - /// The TextWriter output stream containing the decoded string. - public static void HtmlDecode (string s, TextWriter output) + /// + /// A to decode. + /// + /// + /// A that receives the decoded . + /// + public static void HtmlDecode (string s, TextWriter output) { - if (s != null) - output.Write (HtmlDecode (s)); + if (output == null) + throw new ArgumentNullException ("output"); + + output.Write (HtmlDecode (s)); } /// - /// HTML-encodes a string and returns the encoded string. + /// HTML-encodes a and returns the encoded . /// - /// The text string to encode. - /// The HTML-encoded text. - public static string HtmlEncode (string s) + /// + /// A that contains the encoded string. + /// + /// + /// A to encode. + /// + public static string HtmlEncode (string s) { - if (s == null) - return null; + if (s == null || s.Length == 0) + return s; - bool needEncode = false; - for (int i = 0; i < s.Length; i++) { - char c = s [i]; + var needEncode = false; + foreach (var c in s) { if (c == '&' || c == '"' || c == '<' || c == '>' || c > 159) { needEncode = true; break; @@ -741,49 +848,50 @@ namespace WebSocketSharp.Net { if (!needEncode) return s; - StringBuilder output = new StringBuilder (); - - int len = s.Length; - for (int i = 0; i < len; i++) - switch (s [i]) { - case '&' : + var output = new StringBuilder (); + foreach (var c in s) { + if (c == '&') output.Append ("&"); - break; - case '>' : - output.Append (">"); - break; - case '<' : - output.Append ("<"); - break; - case '"' : + else if (c == '"') output.Append ("""); - break; - default: + else if (c == '<') + output.Append ("<"); + else if (c == '>') + output.Append (">"); + else { // MS starts encoding with &# from 160 and stops at 255. // We don't do that. One reason is the 65308/65310 unicode // characters that look like '<' and '>'. - if (s [i] > 159) { + if (c > 159) { output.Append ("&#"); - output.Append (((int) s [i]).ToString (CultureInfo.InvariantCulture)); + output.Append (((int) c).ToString (CultureInfo.InvariantCulture)); output.Append (";"); - } else { - output.Append (s [i]); } - break; + else { + output.Append (c); + } } + } return output.ToString (); } /// - /// HTML-encodes a string and sends the resulting output to a TextWriter output stream. + /// HTML-encodes a and sends the encoded + /// to a . /// - /// The string to encode. - /// The TextWriter output stream containing the encoded string. - public static void HtmlEncode (string s, TextWriter output) + /// + /// A to encode. + /// + /// + /// A that receives the encoded . + /// + public static void HtmlEncode (string s, TextWriter output) { - if (s != null) - output.Write (HtmlEncode (s)); + if (output == null) + throw new ArgumentNullException ("output"); + + output.Write (HtmlEncode (s)); } public static NameValueCollection ParseQueryString (string query) @@ -796,228 +904,176 @@ namespace WebSocketSharp.Net { if (query == null) throw new ArgumentNullException ("query"); - if (encoding == null) - throw new ArgumentNullException ("encoding"); - - if (query.Length == 0 || (query.Length == 1 && query[0] == '?')) + var length = query.Length; + if (length == 0 || (length == 1 && query [0] == '?')) return new NameValueCollection (); - if (query[0] == '?') + if (query [0] == '?') query = query.Substring (1); - NameValueCollection result = new HttpQSCollection (); + if (encoding == null) + encoding = Encoding.UTF8; + + var result = new HttpQSCollection (); ParseQueryString (query, encoding, result); return result; } - public static string UrlDecode (string str) + public static string UrlDecode (string s) { - return UrlDecode(str, Encoding.UTF8); + return UrlDecode (s, Encoding.UTF8); } - public static string UrlDecode (string s, Encoding e) + public static string UrlDecode (string s, Encoding encoding) { - if (s == null) - return null; - - if (s.IndexOf ('%') == -1 && s.IndexOf ('+') == -1) + if (s == null || s.Length == 0 || !s.Contains ('%', '+')) return s; - if (e == null) - e = Encoding.UTF8; + if (encoding == null) + encoding = Encoding.UTF8; - long len = s.Length; - var bytes = new List (); + var length = s.Length; + var bytes = new List (); + char c; int xchar; - char ch; - - for (int i = 0; i < len; i++) { - ch = s [i]; - if (ch == '%' && i + 2 < len && s [i + 1] != '%') { - if (s [i + 1] == 'u' && i + 5 < len) { - // unicode hex sequence + for (int i = 0; i < length; i++) { + c = s [i]; + if (c == '%' && i + 2 < length && s [i + 1] != '%') { + if (s [i + 1] == 'u' && i + 5 < length) { + // Unicode hex sequence. xchar = GetChar (s, i + 2, 4); if (xchar != -1) { - WriteCharBytes (bytes, (char)xchar, e); + WriteCharBytes (bytes, (char) xchar, encoding); i += 5; - } else - WriteCharBytes (bytes, '%', e); - } else if ((xchar = GetChar (s, i + 1, 2)) != -1) { - WriteCharBytes (bytes, (char)xchar, e); + } + else + WriteCharBytes (bytes, '%', encoding); + } + else if ((xchar = GetChar (s, i + 1, 2)) != -1) { + WriteCharBytes (bytes, (char) xchar, encoding); i += 2; - } else { - WriteCharBytes (bytes, '%', e); } + else { + WriteCharBytes (bytes, '%', encoding); + } + continue; } - if (ch == '+') - WriteCharBytes (bytes, ' ', e); + if (c == '+') + WriteCharBytes (bytes, ' ', encoding); else - WriteCharBytes (bytes, ch, e); + WriteCharBytes (bytes, c, encoding); } - byte[] buf = bytes.ToArray (); - bytes = null; - return e.GetString (buf); + var buffer = bytes.ToArray (); + return encoding.GetString (buffer); } - public static string UrlDecode (byte [] bytes, Encoding e) + public static string UrlDecode (byte [] bytes, Encoding encoding) { - if (bytes == null) - return null; - - return UrlDecode (bytes, 0, bytes.Length, e); + if (encoding == null) + encoding = Encoding.UTF8; + + int length; + return bytes == null + ? null + : (length = bytes.Length) == 0 + ? String.Empty + : UrlDecodeInternal (bytes, 0, length, encoding); } - public static string UrlDecode (byte [] bytes, int offset, int count, Encoding e) + public static string UrlDecode (byte [] bytes, int offset, int count, Encoding encoding) { if (bytes == null) return null; - if (count == 0) - return String.Empty; - if (bytes == null) - throw new ArgumentNullException ("bytes"); + var length = bytes.Length; + if (length == 0 || count == 0) + return String.Empty; - if (offset < 0 || offset > bytes.Length) + if (offset < 0 || offset >= length) throw new ArgumentOutOfRangeException ("offset"); - if (count < 0 || offset + count > bytes.Length) + if (count < 0 || count > length - offset) throw new ArgumentOutOfRangeException ("count"); - StringBuilder output = new StringBuilder (); - MemoryStream acc = new MemoryStream (); - - int end = count + offset; - int xchar; - for (int i = offset; i < end; i++) { - if (bytes [i] == '%' && i + 2 < count && bytes [i + 1] != '%') { - if (bytes [i + 1] == (byte) 'u' && i + 5 < end) { - if (acc.Length > 0) { - output.Append (GetChars (acc, e)); - acc.SetLength (0); - } - xchar = GetChar (bytes, i + 2, 4); - if (xchar != -1) { - output.Append ((char) xchar); - i += 5; - continue; - } - } else if ((xchar = GetChar (bytes, i + 1, 2)) != -1) { - acc.WriteByte ((byte) xchar); - i += 2; - continue; - } - } - - if (acc.Length > 0) { - output.Append (GetChars (acc, e)); - acc.SetLength (0); - } - - if (bytes [i] == '+') { - output.Append (' '); - } else { - output.Append ((char) bytes [i]); - } - } + if (encoding == null) + encoding = Encoding.UTF8; - if (acc.Length > 0) { - output.Append (GetChars (acc, e)); - } - - acc = null; - return output.ToString (); + return UrlDecodeInternal (bytes, offset, count, encoding); } - + public static byte [] UrlDecodeToBytes (byte [] bytes) { - if (bytes == null) - return null; - - return UrlDecodeToBytes (bytes, 0, bytes.Length); + int length; + return bytes == null || (length = bytes.Length) == 0 + ? bytes + : UrlDecodeToBytesInternal (bytes, 0, length); } - public static byte [] UrlDecodeToBytes (string str) + public static byte [] UrlDecodeToBytes (string s) { - return UrlDecodeToBytes (str, Encoding.UTF8); + return UrlDecodeToBytes (s, Encoding.UTF8); } - public static byte [] UrlDecodeToBytes (string str, Encoding e) + public static byte [] UrlDecodeToBytes (string s, Encoding encoding) { - if (str == null) + if (s == null) return null; - if (e == null) - throw new ArgumentNullException ("e"); + if (s.Length == 0) + return new byte [0]; + + if (encoding == null) + encoding = Encoding.UTF8; - return UrlDecodeToBytes (e.GetBytes (str)); + var bytes = encoding.GetBytes (s); + return UrlDecodeToBytesInternal (bytes, 0, bytes.Length); } public static byte [] UrlDecodeToBytes (byte [] bytes, int offset, int count) { - if (bytes == null) - return null; + int length; + if (bytes == null || (length = bytes.Length) == 0) + return bytes; if (count == 0) return new byte [0]; - int len = bytes.Length; - if (offset < 0 || offset >= len) - throw new ArgumentOutOfRangeException("offset"); - - if (count < 0 || offset > len - count) - throw new ArgumentOutOfRangeException("count"); + if (offset < 0 || offset >= length) + throw new ArgumentOutOfRangeException ("offset"); - MemoryStream result = new MemoryStream (); - int end = offset + count; - for (int i = offset; i < end; i++){ - char c = (char) bytes [i]; - if (c == '+') { - c = ' '; - } else if (c == '%' && i < end - 2) { - int xchar = GetChar (bytes, i + 1, 2); - if (xchar != -1) { - c = (char) xchar; - i += 2; - } - } - result.WriteByte ((byte) c); - } + if (count < 0 || count > length - offset ) + throw new ArgumentOutOfRangeException ("count"); - return result.ToArray (); + return UrlDecodeToBytesInternal (bytes, offset, count); } public static string UrlEncode (byte [] bytes) { - if (bytes == null) - return null; - - if (bytes.Length == 0) - return ""; - - return Encoding.ASCII.GetString (UrlEncodeToBytes (bytes, 0, bytes.Length)); + int length; + return bytes == null + ? null + : (length = bytes.Length) == 0 + ? String.Empty + : Encoding.ASCII.GetString (UrlEncodeToBytesInternal (bytes, 0, length)); } - public static string UrlEncode (string str) + public static string UrlEncode (string s) { - return UrlEncode (str, Encoding.UTF8); + return UrlEncode (s, Encoding.UTF8); } - public static string UrlEncode (string s, Encoding Enc) + public static string UrlEncode (string s, Encoding encoding) { - if (s == null) - return null; - - if (s == "") - return ""; + int length; + if (s == null || (length = s.Length) == 0) + return s; - bool needEncode = false; - int len = s.Length; - for (int i = 0; i < len; i++) { - char c = s [i]; + var needEncode = false; + foreach (var c in s) { if ((c < '0') || (c < 'A' && c > '9') || (c > 'Z' && c < 'a') || (c > 'z')) { if (NotEncoded (c)) continue; @@ -1030,98 +1086,88 @@ namespace WebSocketSharp.Net { if (!needEncode) return s; - // avoided GetByteCount call - byte [] bytes = new byte[Enc.GetMaxByteCount(s.Length)]; - int realLen = Enc.GetBytes (s, 0, s.Length, bytes, 0); + if (encoding == null) + encoding = Encoding.UTF8; + + // Avoided GetByteCount call. + var bytes = new byte [encoding.GetMaxByteCount (length)]; + var realLen = encoding.GetBytes (s, 0, length, bytes, 0); - return Encoding.ASCII.GetString (UrlEncodeToBytes (bytes, 0, realLen)); + return Encoding.ASCII.GetString (UrlEncodeToBytesInternal (bytes, 0, realLen)); } public static string UrlEncode (byte [] bytes, int offset, int count) { - if (bytes == null) - return null; - - if (bytes.Length == 0) - return ""; - - return Encoding.ASCII.GetString (UrlEncodeToBytes (bytes, offset, count)); + var encoded = UrlEncodeToBytes (bytes, offset, count); + return encoded == null + ? null + : encoded.Length == 0 + ? String.Empty + : Encoding.ASCII.GetString (encoded); } public static byte [] UrlEncodeToBytes (byte [] bytes) { - if (bytes == null) - return null; - - if (bytes.Length == 0) - return new byte [0]; - - return UrlEncodeToBytes (bytes, 0, bytes.Length); + int length; + return bytes == null || (length = bytes.Length) == 0 + ? bytes + : UrlEncodeToBytesInternal (bytes, 0, length); } - public static byte [] UrlEncodeToBytes (string str) + public static byte [] UrlEncodeToBytes (string s) { - return UrlEncodeToBytes (str, Encoding.UTF8); + return UrlEncodeToBytes (s, Encoding.UTF8); } - public static byte [] UrlEncodeToBytes (string str, Encoding e) + public static byte [] UrlEncodeToBytes (string s, Encoding encoding) { - if (str == null) + if (s == null) return null; - if (str == "") + if (s.Length == 0) return new byte [0]; - byte [] bytes = e.GetBytes (str); + if (encoding == null) + encoding = Encoding.UTF8; - return UrlEncodeToBytes (bytes, 0, bytes.Length); + var bytes = encoding.GetBytes (s); + return UrlEncodeToBytesInternal (bytes, 0, bytes.Length); } public static byte [] UrlEncodeToBytes (byte [] bytes, int offset, int count) { - if (bytes == null) - return null; + int length; + if (bytes == null || (length = bytes.Length) == 0) + return bytes; - int len = bytes.Length; - if (len == 0) + if (count == 0) return new byte [0]; - if (offset < 0 || offset >= len) - throw new ArgumentOutOfRangeException("offset"); - - if (count < 0 || count > len - offset) - throw new ArgumentOutOfRangeException("count"); + if (offset < 0 || offset >= length) + throw new ArgumentOutOfRangeException ("offset"); - MemoryStream result = new MemoryStream (count); - int end = offset + count; - for (int i = offset; i < end; i++) - UrlEncodeChar ((char)bytes [i], result, false); + if (count < 0 || count > length - offset) + throw new ArgumentOutOfRangeException ("count"); - return result.ToArray(); + return UrlEncodeToBytesInternal (bytes, offset, count); } - public static string UrlEncodeUnicode (string str) + public static string UrlEncodeUnicode (string s) { - if (str == null) - return null; - - return Encoding.ASCII.GetString (UrlEncodeUnicodeToBytes (str)); + return s == null || s.Length == 0 + ? s + : Encoding.ASCII.GetString (UrlEncodeUnicodeToBytesInternal (s)); } - public static byte [] UrlEncodeUnicodeToBytes (string str) + public static byte [] UrlEncodeUnicodeToBytes (string s) { - if (str == null) + if (s == null) return null; - if (str == "") + if (s.Length == 0) return new byte [0]; - MemoryStream result = new MemoryStream (str.Length); - foreach (char c in str){ - UrlEncodeChar (c, result, true); - } - - return result.ToArray (); + return UrlEncodeUnicodeToBytesInternal (s); } public static string UrlPathEncode (string s) @@ -1129,15 +1175,13 @@ namespace WebSocketSharp.Net { if (s == null || s.Length == 0) return s; - MemoryStream result = new MemoryStream (); - int length = s.Length; - for (int i = 0; i < length; i++) { - UrlPathEncodeChar (s [i], result); - } + var result = new MemoryStream (); + foreach (var c in s) + UrlPathEncodeChar (c, result); return Encoding.ASCII.GetString (result.ToArray ()); } - #endregion // Public Methods + #endregion } }