Network C#

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace SocialKit.LightRest
{
    /// 
    /// Provides helper methods for common tasks.
    /// 

    public static class RestUtility
    {
        static string unreservedChars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_.~";
        /// 
        /// Represents the System.Text.Encoding.Default.
        /// 

        public static readonly Encoding DefaultEncoding = Encoding.Default;
        /// 
        /// Encodes a URL string with UTF8 encoding.
        /// 

        /// The text to encode.
        /// 
        public static string UrlEncode(string source)
        {
            return UrlEncode(source, Encoding.UTF8);
        }
        /// 
        /// Encodes a URL string with the specified encoding.
        /// 

        /// The text to encode.
        /// The System.Text.Encoding object that specifies the encoding scheme.
        /// 
        public static string UrlEncode(string source, Encoding encoding)
        {
            if (source == null)
                return null;
            if (string.IsNullOrEmpty(source))
                return string.Empty;
            if (encoding == null)
                encoding = DefaultEncoding;
            var buffer = new StringBuilder();
            foreach (var b in encoding.GetBytes(source))
            {
                if (b < 128 && unreservedChars.IndexOf((char)b) != -1)
                {
                    buffer.Append((char)b);
                }
                else
                {
                    buffer.AppendFormat("%{0:X2}", b);
                }
            }
            return buffer.ToString();
        }
        /// 
        /// Converts a string that has been encoded for transmission in a URL into a decoded string. 
        /// 

        /// The URL-encoded string to decode.
        /// 
        public static string UrlDecode(string source)
        {
            return UrlDecode(source, Encoding.UTF8);
        }
        /// 
        /// Converts a URL-encoded string into a decoded string, using the specified encoding object. 
        /// 

        /// The URL-encoded string to decode.
        /// The System.Text.Encoding object that specifies the encoding scheme.
        /// 
        public static string UrlDecode(string source, Encoding encoding)
        {
            if (source == null)
                return null;
            if (string.IsNullOrEmpty(source))
                return string.Empty;
            if (encoding == null)
                encoding = DefaultEncoding;
            var bytes = new List();
            for (int i = 0; i < source.Length; i++)
            {
                var c = source[i];
                if (unreservedChars.IndexOf(c) != -1)
                {
                    bytes.Add((byte)c);
                }
                else if (c == '%' && i < source.Length - 2)
                {
                    var n1 = HexToInt(source[i + 1]);
                    var n2 = HexToInt(source[i + 2]);
                    if (n1 >= 0 && n2 >= 0)
                    {
                        var b = (byte)((n1 << 4) | n2);
                        i += 2;
                        bytes.Add(b);
                    }
                }
            }
            return encoding.GetString(bytes.ToArray(), 0, bytes.Count);
        }
        /// 
        /// Converts an hex char to an integer.
        /// 

        /// 
        /// 
        static int HexToInt(char c)
        {
            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;
        }
        /// 
        /// Parse the query string in the URI into a KeyValuePair<string, string> collection.
        /// The keys and values will be URL decoded.
        /// 

        /// The query string to parse.
        /// A keys and values collection.
        public static IEnumerable> ParseQueryString(string query)
        {
            if (query == null)
                throw new ArgumentNullException("query");
            if (query.StartsWith("?"))
                query = query.Substring(1);
            if (string.IsNullOrEmpty(query))
                return new KeyValuePair[] { };
            var values = new List>();
            int length = query.Length;
            int startIndex, equalIndex;
            for (int i = 0; i < length; i++)
            {
                startIndex = i;
                equalIndex = -1;
                while (i < length)
                {
                    char c = query[i];
                    if (c == '=')
                    {
                        if (equalIndex < 0)
                        {
                            equalIndex = i;
                        }
                    }
                    else if (c == '&')
                    {
                        break;
                    }
                    i++;
                }
                string key = null;
                string value = null;
                if (equalIndex >= 0)
                {
                    key = query.Substring(startIndex, equalIndex - startIndex);
                    value = query.Substring(equalIndex + 1, (i - equalIndex) - 1);
                }
                else
                {
                    //standalone value is key or value?
                    key = query.Substring(startIndex, i - startIndex);
                }
                if (value == null)
                {
                    value = string.Empty;
                }
                values.Add(new KeyValuePair(UrlDecode(key), UrlDecode(value)));
            }
            return values;
        }
        /// 
        /// Gets a string indicates the URI without query string.
        /// 

        /// The URI to normalize.
        /// The host and path of the URI.
        public static string NormalizeUriWithoutQuery(Uri uri)
        {
            if (!uri.IsAbsoluteUri)
                throw new ArgumentOutOfRangeException("uri", "The relative URI is not supported.");
            var normalizedUri = string.Format("{0}://{1}", uri.Scheme, uri.Host);
            if (!((uri.Scheme == "http" && uri.Port == 80) || (uri.Scheme == "https" && uri.Port == 443)))
            {
                normalizedUri += ":" + uri.Port;
            }
            normalizedUri += uri.AbsolutePath;
            return normalizedUri;
        }
        /// 
        /// Extract encoding from the contentType string, or returns the fallback value.
        /// 

        /// The contentType string.
        /// If no encoding found, returns this value.
        /// A System.Text.Encoding value.
        public static Encoding ExtractEncoding(string contentType, Encoding fallback)
        {
            if (string.IsNullOrEmpty(contentType))
            {
                return fallback;
            }
            //find charset
            var values = contentType.Split(';');
            var charsetPair = values.FirstOrDefault(v => v.Trim().StartsWith("charset", StringComparison.InvariantCultureIgnoreCase));
            if (charsetPair == null)
                return fallback;
            var charset = charsetPair.Split('=')[1];
            return Encoding.GetEncoding(charset);
        }
        /// 
        /// Extract encoding from the contentType string.
        /// 

        /// The contentType string.
        /// A System.Text.Encoding value.
        public static Encoding ExtractEncoding(string contentType)
        {
            return ExtractEncoding(contentType, Encoding.Default);
        }
    }
}