Mega Code Archive

 
Categories / C# / Network
 

Url encoding (2)

// // System.Net.HttpUtility // // Author: //  Gonzalo Paniagua Javier (gonzalo@novell.com) // // Copyright (c) 2005 Novell, Inc. (http://www.novell.com) // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: //  // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. //  // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // using System; using System.Globalization; using System.IO; using System.Text; namespace Tavis.Http {     public sealed class HttpUtility {         private HttpUtility() {         }         public static string UrlDecode(string s) {             return UrlDecode(s, null);         }         static char[] GetChars(MemoryStream b, Encoding e) {             return e.GetChars(b.GetBuffer(), 0, (int)b.Length);         }         public static string UrlDecode(string s, Encoding e) {             if (null == s)                 return null;             if (s.IndexOf('%') == -1 && s.IndexOf('+') == -1)                 return s;             if (e == null)                 e = Encoding.GetEncoding(28591);             StringBuilder output = new StringBuilder();             long len = s.Length;             NumberStyles hexa = NumberStyles.HexNumber;             MemoryStream bytes = new MemoryStream();             for (int i = 0; i < len; i++) {                 if (s[i] == '%' && i + 2 < len) {                     if (s[i + 1] == 'u' && i + 5 < len) {                         if (bytes.Length > 0) {                             output.Append(GetChars(bytes, e));                             bytes.SetLength(0);                         }                         output.Append((char)Int32.Parse(s.Substring(i + 2, 4), hexa));                         i += 5;                     } else {                         bytes.WriteByte((byte)Int32.Parse(s.Substring(i + 1, 2), hexa));                         i += 2;                     }                     continue;                 }                 if (bytes.Length > 0) {                     output.Append(GetChars(bytes, e));                     bytes.SetLength(0);                 }                 if (s[i] == '+') {                     output.Append(' ');                 } else {                     output.Append(s[i]);                 }             }             if (bytes.Length > 0) {                 output.Append(GetChars(bytes, e));             }             bytes = null;             return output.ToString();         }         public static string UrlEncode(string str) {             return UrlEncode(str, Encoding.UTF8);         }         public static string UrlEncode(string s, Encoding Enc) {             if (s == null)                 return null;             if (s == "")                 return "";             byte[] bytes = Enc.GetBytes(s);             return Encoding.ASCII.GetString(UrlEncodeToBytes(bytes, 0, bytes.Length));         }         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));         }         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));         }         public static byte[] UrlEncodeToBytes(string str) {             return UrlEncodeToBytes(str, Encoding.UTF8);         }         public static byte[] UrlEncodeToBytes(string str, Encoding e) {             if (str == null)                 return null;             if (str == "")                 return new byte[0];             byte[] bytes = e.GetBytes(str);             return UrlEncodeToBytes(bytes, 0, bytes.Length);         }         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);         }         static char[] hexChars = "0123456789abcdef".ToCharArray();         const string notEncoded = "!'()*-._";         static void UrlEncodeChar(char c, Stream result, bool isUnicode) {             if (c > 255) {                 //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]);                 idx = (i >> 8) & 0x0F;                 result.WriteByte((byte)hexChars[idx]);                 idx = (i >> 4) & 0x0F;                 result.WriteByte((byte)hexChars[idx]);                 idx = i & 0x0F;                 result.WriteByte((byte)hexChars[idx]);                 return;             }             if (c > ' ' && notEncoded.IndexOf(c) != -1) {                 result.WriteByte((byte)c);                 return;             }             if (c == ' ') {                 result.WriteByte((byte)'+');                 return;             }             if ((c < '0') ||                 (c < 'A' && c > '9') ||                 (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');                 } else                     result.WriteByte((byte)'%');                 int idx = ((int)c) >> 4;                 result.WriteByte((byte)hexChars[idx]);                 idx = ((int)c) & 0x0F;                 result.WriteByte((byte)hexChars[idx]);             } else                 result.WriteByte((byte)c);         }         public static byte[] UrlEncodeToBytes(byte[] bytes, int offset, int count) {             if (bytes == null)                 return null;             int len = bytes.Length;             if (len == 0)                 return new byte[0];             if (offset < 0 || offset >= len)                 throw new ArgumentOutOfRangeException("offset");             if (count < 0 || count > len - offset)                 throw new ArgumentOutOfRangeException("count");             MemoryStream result = new MemoryStream(count);             int end = offset + count;             for (int i = offset; i < end; i++)                 UrlEncodeChar((char)bytes[i], result, false);             return result.ToArray();         }         public static string UrlEncodeUnicode(string str) {             if (str == null)                 return null;             return Encoding.ASCII.GetString(UrlEncodeUnicodeToBytes(str));         }         public static byte[] UrlEncodeUnicodeToBytes(string str) {             if (str == null)                 return null;             if (str == "")                 return new byte[0];             MemoryStream result = new MemoryStream(str.Length);             foreach (char c in str) {                 UrlEncodeChar(c, result, true);             }             return result.ToArray();         }     } }